我正在使用导出的函数在MSVC ++ 2010中编写Win32 DLL。其中一些函数将文件名返回为LPCSTR
。因为我以前有时需要摆弄字符串,所以我目前正在使用长度为32184的全局缓冲区变量,该变量应该覆盖Windows中可能出现的任何文件名,然后我总是初始化并返回需要字符串的地方。
我的老板在VB6遗留应用程序中使用此库。他现在告诉我他需要它是线程安全的:不幸的是,由于VB6的事件驱动行为,即使另一个函数尚未返回,也可能在我的库中调用函数。当然,这意味着我不能依赖单个内部缓冲区,但每次需要时都必须创建一个,然后返回它。
2个问题:
我在很大程度上依赖于FindFirstFile
和filesystem
库中的regex
和Boost函数等Windows API函数。我可以假设它们都是线程安全的吗?
如果每次要返回一个字符串时都要在堆上创建一个新的缓冲区,我该在哪里再次释放内存?
答案 0 :(得分:3)
FindNextFile
,但你可以使用两个不同的句柄)。有关boost函数,请参阅文档,但一般来说,只要不同时在两个线程之间使用相同的对象,文件系统/正则表达式函数就应该是安全的。答案 1 :(得分:1)
VB6代码很可能是单线程的。重新入门可能仅限于VB6代码。 VB6代码无法将重入事件注入C ++代码。只要C ++代码不回调到VB6代码,那么C ++代码本身就不会以可重入的方式被调用。
如果这些假设是正确的,那么具有单个全局缓冲区的当前代码将正确运行。这表示你最好在我的视图中切换到BSTR
,因为它允许将来链接到多线程的调用者。
答案 2 :(得分:0)
您可以使用TLS分配字符串:
const int string_size = 1024; // string size
DWORD idTlsString = 0;
// use this function to get the string which you will use to return to VB
char* GetTheString()
{
return (char*)TlsGetValue(idTlsString);
}
// Dll init function
BOOL WINAPI DllMain(
HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved
)
{
switch( fdwReason )
{
// allocate TSL
case DLL_PROCESS_ATTACH:
idTlsString = TlsAlloc();
break;
// allocate the srting
case DLL_THREAD_ATTACH:
TlsSetValue(idTlsString, (LPVOID)new char[string_size] );
break;
// free the string
case DLL_THREAD_DETACH:
delete[] (char*)TlsGetValue(idTlsString);
break;
// release TLS
case DLL_PROCESS_DETACH:
TlsFree(idTlsString);
break;
}
return true;
}