C++ 中的线程安全字符串缓冲区变量DLL
我正在 MSVC++2010 中编写带有导出函数的 Win32 DLL。其中一些函数将文件名返回为 LPCSTR
。因为我之前有时需要摆弄字符串,所以我目前使用长度为 32184 的全局缓冲区变量,它应该涵盖 Windows 中可能出现的任何文件名,然后我总是在需要字符串的地方初始化并返回。
我的老板使用 VB6 遗留应用程序中的这个库。他现在告诉我他需要它是线程安全的:对我来说不幸的是,由于 VB6 的事件驱动行为,即使另一个函数尚未返回,也可能会在我的库中调用一个函数。当然,这意味着我不能依赖单个内部缓冲区,而必须在每次需要时创建一个,然后返回它。
2 个问题:
我严重依赖 Windows API 函数,例如
FindFirstFile
以及来自filesystem
和regex
库的 Boost 函数。我可以假设它们都是线程安全的吗?如果我每次想要返回字符串时都必须在堆上创建一个新缓冲区,那么我在哪里再次释放内存?
I am writing a Win32 DLL in MSVC++2010 with exported functions. Some of those functions return filenames as LPCSTR
. Because I sometimes need to fiddle with strings before, I am currently using a global buffer variable of length 32184 which should cover any filename that can occur in Windows which I then always initialize and return where a string is needed.
My boss uses this library from a VB6 legacy app. He now informed me that he needs it to be thread-safe: unfortunately for me, due to VB6's event-driven behaviour, it can happen that a function is called in my library even if another function has not yet returned. This, of course, means that I cannot rely on a single internal buffer but have to create one every time I need one and then return it.
2 Questions:
I rely heavily on Windows API functions such as
FindFirstFile
and Boost functions from thefilesystem
andregex
libraries. Can I assume that they are all thread-safe?If I have to create a new buffer on the heap every time I want to return a string, where do I free the memory again?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
FindNextFile
,但可以使用两个不同的句柄)。对于 boost 函数,请参阅文档,但一般来说,只要您不在两个线程之间同时使用同一对象,文件系统/正则表达式函数应该是安全的。FindNextFile
on the same handle from two threads at the same time, but you can with two different handles). For boost functions, consult the documentation, but generally speaking filesystem/regex functions should be safe as long as you don't use the same object between two threads at the same time.VB6 代码很可能是单线程的。可重入大概仅限于 VB6 代码。 VB6 代码无法将可重入事件注入到 C++ 代码中。只要 C++ 代码不回调到 VB6 代码,那么 C++ 代码本身就不会以可重入的方式调用。
如果这些假设正确,那么您当前具有单个全局缓冲区的代码将正确运行。也就是说,在我看来,您最好切换到 BSTR,因为它允许将来链接到多线程的调用者。
The VB6 code is most probably single threaded. The re-entrancy is presumably limited to the VB6 code. The VB6 code can't inject re-entrant events into the C++ code. So long as the C++ code does not call back into the VB6 code then the C++ code itself will not be called in re-entrant fashion.
If these presumptions are correct then your current code with a single global buffer will operate correctly. That said you would be better off switching to
BSTR
in my view because it would allow for future linking against caller's that were multi-threaded.您可以使用 TLS 来分配字符串:
You can use TLS for allocation the string: