c++ - 如何跨多个线程在 COM 中使用 LoadLibrary?

标签 c++ multithreading com loadlibrary

假设我有以下代码在多线程 COM 应用程序的一个线程中运行:

// Thread 1
struct foo {
    int (*DoSomething)(void ** parm);
};

HMODULE fooHandle = LoadLibrary("pathToFoo");
typedef int (*loadUpFooFP)(foo ** fooPtrPtr);
loadUpFooFP loadUpFoo;
loadUpFoo = (loadUpFooFP)GetProcAddress(fooHandle, "fooLoader");
foo * myFoo;
loadUpFoo(&myFoo);

这一切都很好,然后我可以调用

myFoo->DoSomething(&parmPtr);

这也行!现在,另一个线程出现并加载它的 foo:

// Thread 2
foo * myFooInThread2;
loadUpFoo(&myFooInThread2);

这也很管用。在线程 2 中,我可以调用 DoSomething:

// Thread 2
myFooInThread2->DoSomething(&anotherParmPtr);

现在,当线程 1 最终消失时,我遇到了一个问题。我注意到在 Visual Studio 中调试时无法再评估 DoSomething 的地址。第一个线程结束后,当我调用时:

myFooInThread2->DoSomething(&anotherParmPtr);

我遇到访问冲突。 myFooInThread2 指针仍然有效,但函数指针无效。此函数指针是通过调用 loadUpFoo 设置的,而 loadUpFoo 又位于由 LoadLibrary 加载的 dll 中。

我的问题是:我从哪里开始寻找失败的原因?外部 DLL(我用 LoadLibrary 加载)在我的 foo 结构中设置函数指针的方式有问题吗?还是与使用同一库的不同线程有关?或者,它是否与我在此应用程序中使用 COM 有关(在第一个线程中调用 CoUninitialize 是否会以某种方式释放此内存或库)?

我可以提供有关 COM 设置的更多详细信息,如果这看起来是负责的话。谢谢!

编辑:感谢到目前为止的建议。 foo 结构是不透明的——我不太了解它的实现。 foo 结构在我导入的 header 中声明。没有我显式调用的引用计数方法,也没有与使用 LoadLibrary 加载的库进行其他交互。我很确定 foo 结构没有内存映射到某个 COM 类,但就像我说的那样它是不透明的,我不能肯定地说。

foo 指针的生命周期得到妥善管理(未删除)。

foo 结构是一个加密库,所以我不便透露更多。在这一点上,我确信我在不同线程和 COM 应用程序中使用 LoadLibrary 没有任何内在错误(并且我认为函数指针内存清理是由库本身中我无法控制的某些东西引起的) ).

最佳答案

您显示的代码中没有与 COM 相关的内容。 LoadLibrary 不是特定于线程的,因此一旦您拥有库的句柄,就可以在所有线程中重用它。这同样适用于指向 fooLoader 方法的指针。

但是,在 fooLoader 中肯定有一些特定于 COM 的东西。此外,这里不清楚的是 foo 实例的生命周期控制是什么。

从您提到 COM 的事实和您看到的古怪行为来看,我偷偷怀疑 foo 实际上是 COM 对象的 vtable 的内存映射,而 fooLoader 是 DllGetClassObject 或创建 COM 对象的另一个工厂方法。:- )

在任何情况下,foo 实例变得无效的最可能的解释是它被引用计数并且 DoSomething 调用 AddRef()/Release() 导致它自毁。

要准确查明发生了什么,您必须提供更多信息,说明 fooLoader 的作用以及您认为您的代码与 COM 相关的原因。

关于c++ - 如何跨多个线程在 COM 中使用 LoadLibrary?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1381646/

相关文章:

c# - 在 64 位 Office 插件中加载 32 位 COM dll

delphi - 有没有办法从流加载 Crystal Report 9.0 文件?

c++ - 首选具有相同名称的多个声明之一

c++ - std::arg 为实际输入返回不正确的值(使用 MSVC 编译器)

objective-c - Objective-C 中的线程

C# 更新对象引用和多线程

windows - 我什么时候应该在 HKCR\Interface 中注册我的 COM 接口(interface)?

c++ - 如何编辑二进制文件中的特定值?

c++ - 如何制作不依赖于 .so 文件的可执行二进制文件

c++ - 线程安全的 TBB::concurrent_hash_map 删除