1

我有一个引用 2 个 COM DLL 的应用程序。应用程序在启动时调用的 2 个 DLL 中有一个 Init 函数。

这两个 DLL 几乎相似——除了它们有不同的 uid 和不同的接口名称。除此之外,逻辑是相同的......并且使用的变量也相同。

这就是该系统的工作方式 - 1. StartApp() 2. Init DLL1(appVar1,appVar2)..这里应用程序将在此 DLL 中定义的 var x,y 设置为从应用程序传递的值。假设 x = appVar1 和 y = appVar2。x 和 y 是全局变量。3. 初始化 DLL2(appVar1a,appVar2a)...应用程序将 DLL2 中定义的 var x 设置为从应用程序传递的值。x = appVar1a;y = appVar2。

现在,当我尝试在 DLL1 上运行某些东西时,x 和 y 的值神秘地变成了 else 。

x 现在变成 appVar2 并且 y 是空白的。

这里 x、y 以及应用程序在 InitDLL 函数中传递的所有变量(如 appVar1 等)都是 BSTR 的。

我通过代码... x,y 在 InitDLL1 中正确设置为 appVar1,appVar2。但是一旦这个函数返回并且我们正在初始化第二个 DLL (InitDLL2),情况就会改变。

有趣的是,我在 DLL2 中没有看到任何此类问题..即使代码/逻辑非常相似....除了它调用的接口。

在 DLL1 和 DLL2 中,在 InitDLL 函数中,我们创建了一个新线程,我们在各种函数中使用 x 和 y。由于上述问题,DLL1 总是失败..DLL2 没有问题。

关于什么可能出错的任何线索?

4

1 回答 1

0

您不能只分配 BSTR,您需要复制它。这是问题所在:

// caller - by COM memory management rules, for [in] parameters
// caller needs to allocate and free the memory
BSTR str = SysAllocString("..."); // string is allocated
comObjectPtr->Init(str);          // in the function, pointer is copied to global
SysFreeString(str);               // string released, pointer points to garbage

// callee
ComObject::Init(BSTR str)
{
    // wrong code!!! you have no idea about lifetime of str,
    // so you can't just assign it. When the caller function
    // exits, string memory is released and your global is thrashed
    // I suspect you use some BSTR wrapper (bstr_t or CComBSTR) so
    // you don't see the deallocation part and that's why the values
    // are invalidated on function exit: the destructor of BSTR wrapper
    // does its job
    global_str = str;             

    // correct code:
    // global_str = SysAllocString(str);
}
于 2012-12-04T08:28:02.870 回答