通过dll边界的C字符串
C string through dll boundaries
我们需要以安全的方式通过dll边界返回一个C字符串!我们该怎么做?
我的想法:
extern "C" __declspec(dllexport) const char *const Api
{
...
static const char *output = result.c_str();
return output;
}
示例代码中返回了一个指针,但它所指向的内存区域可能不是常驻的。
如果结果变量(std::string?)在堆栈上,那么当函数返回时,它将被销毁,并且返回的指针将悬空——当然不是您想要的。
一个安全的方法是strdup()响应,但调用方将负责释放C字符串。卸载DLL意味着返回的指针将悬空,除非它指向堆变量。
最简单的安全方法是
extern "C"
__declspec(dllexport)
size_t Api
(char* dest,
size_t dest_size)
{
if (dest)
strncpy(dest, str, dest_size);
return strlen(str);
}
另一种安全的方法是
extern "C"
__declspec(dllexport)
void Api
(void (*callback)(const char*))
{
callback(str);
}
返回malloc'd/new'd内存不是100%安全的,因为DLL和主程序可以链接到不同的运行时并使用不同的堆。如果是这种情况,调用程序只能通过调用DLL中的free/delete来释放/删除内存(DLL必须包装这些内存并导出包装器)。这很麻烦。
返回静态内存不是100%安全的,因为调用方可能会存储指针并卸载DLL,在这种情况下,指针将挂起。
当然,返回自动内存是100%不安全的。