gpt4 book ai didi

c++ - 神秘的全局变量 - COM/STA 单元对象

转载 作者:太空宇宙 更新时间:2023-11-04 12:20:16 24 4
gpt4 key购买 nike

场景如下:

-COM DLL,加载到使用该 DLL 的进程的地址空间中。-在 DLL 中存在一对全局变量(比如 var a、var b)和一个全局函数。- 进程启动,调用全局函数并初始化全局变量 a、b 并调用 CoInitialize(NULL) - 该线程是一个 STA。-然后相同的全局函数创建一个 STA COM 对象

稍后在程序中,同一个线程(上面调用 CoInitialize 并创建 STA COM 对象的线程)在此 DLL 中调用同一个全局 C 函数(我们称之为 func())。在 C 函数的范围内,全局变量的状态完全符合预期(即正确初始化)。函数 func() 在现有 STA COM 对象上调用 COM 方法的那一刻,同一 DLL 中的 COM 对象看到全局变量(var a,var b)的完全不同的拷贝。我获取了这两个变量的地址,它们在 C-func 中与调用的 COM 对象函数完全不同。到底是怎么回事?我认为同一地址空间中的全局变量应该是全面可见的。

最佳答案

可能正在加载您的 DLL 的两个实例——一个由托管您的 DLL 的应用程序显式加载,第二个通过 CoCreateInstance 通过 COM 子系统加载。前者将在 DLL 搜索路径中查找应用程序进程,而后者将在注册表中查找实现 COCLASS 的 COM 组件的位置。

如果您的 DLL 有 DllMain(如果它是基于 MFC 的 DLL,则有 InitInstance 函数),那么您可以对其断点并查看 hinstance 参数(如果是 MFC,则为 AfxGetInstanceHandle)以查看是否 (a) 您初始化了两次并且(b) 您看到两个不同的 DLL 实例句柄。如果是这样,那么您肯定加载了两次。

DLL 在文件系统中的位置很重要,因此您应该查看是否有位于不同位置的拷贝,这些拷贝可能会根据我上面提到的规则单独加载。

一般来说,COM DLL 不应该被直接加载。您应该将您的功能分解为两个 DLL,其中一个 COM 服务器 DLL 专用于 COM 内容。如果您愿意,您可以为自己提供一个内部 COCLASS 接口(interface),使您能够将全局变量传递给 COM DLL。

关于c++ - 神秘的全局变量 - COM/STA 单元对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5480633/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com