我正在尝试使用camlidl生成的C接口。我使用的库通过分配和填充in/out参数返回错误代码
char* error_message
把它还给我。函数调用后,我检查错误代码是否为非零。。。如果是真的,我会打电话给你
caml_failwith(error_message)
使用库错误消息引发OCaml异常。
但是,我开始挖掘一些,因为抛出异常看起来好像它将终止函数,并且永远不会释放错误消息。考虑以下模拟代码:
/* in the C stub function call... */
double _res;
int error = 0;
char* error_message = NULL;
// if this function errors, it will set error to non-zero
// and strdup something into error_message
_res = call_library_function(&error, error_message);
if (error) {
caml_failwith(error_message);
free(error_message); // NEVER CALLED?
}
/* code to copy result to an OCaml value and return */
caml_failwith(s)
runtime/fail_*.c
,但基本上只是打电话
caml_raise_with_string
,即:
CAMLparam1(tag);
value v_msg = caml_copy_string(msg);
caml_raise_with_arg(tag, v_msg);
CAMLnoreturn;
因此,它用caml\u copy\u string将字符串复制到OCaml值,然后提升arg,不返回。总之,
.
…对吧?我错过了什么。。。我可以使用罐装字符串,但这使得动态错误消息不可能。我可以使用static char*,不过如果没有大量的工作,它就不再是线程安全的了。
caml_failwith
,使用普通的旧动态
char*
编辑:我想到了一个解决办法。。。
char error_message_buf[100] = {'\0'};
double _res;
// ... rest of local vars and service call ...
if (error) {
strncpy(error_message_buf, error_message, 99)
free(error_message);
caml_failwith(error_message_buf);
}
strncpy
就为了转身
caml_copy_string
再一次?此外,它还设置了错误消息长度的硬编码上限。不过,如果这是唯一不泄漏的方法。。。