1

我有一个托管 C++ dll,它与非托管 C++ dll 动态链接。托管 C++ 从非托管 dll 中的抽象接口派生几个非托管类。

这工作正常。非托管 dll 中的 ICustomer.h

//  uses macro __declspec(dllexport)
class EXPORT_API ICustomer
{
public:
    virtual void PlaceOrder() = 0;
    //...
};  

托管 C++ 中的 LocalCustomer.h

#include "unmanagedlib/ICustomer.h"

//an unmanaged derived class defined in the managed dll
class LocalCustomer : public ICustomer
{
public:
    void PlaceOrder();
    //...
};  

LocalCustomer 在托管 dll 中使用。我可以将它传递给非托管 dll 中的函数,并且一切正常。

这是问题所在。当我尝试实现一个公开模板的接口时,我在启动时得到一个 STATUS_INVALID_IMAGE_FORMAT 。

不运行。在非托管 Dll 中

stuct Order
{
    double price;
    //...
};

template<typename T>
class EXPORT_API ICollection<T>
{
    //...
};

class EXPORT_API IFactory
{  
public:
    virtual ICollection<Order>& GetOrders() = 0;
}

在托管 C++ dll 中

class OrderCollection : public ICollection<Order>
{
    //...
};

class LocalFactory : public IFactory
{
public:
    virtual ICollection<Order>& GetOrders() { return m_orders; }
private:
    OrderCollection m_orders;
};

我已经缩小了模板覆盖 GetOrders 的范围。将代码放在托管 dll 中会导致打开一个对话框“应用程序无法正确启动 (0xc000007b),这只是托管加载程序抛出的 STATUS_INVALID_IMAGE_FORMAT HRESULT。删除代码允许它运行。那么模板有什么问题? 为什么我不能在托管的 dll 中使用它。

另一个线索,不确定这是否会分散注意力。我正在编译一个 32 位应用程序并在 Win7 x64 上运行。就像我说的那样,只要模板不跨越 dll 从非托管到托管就可以了。

杀死我的是 II 有几个非托管 C++ 模板,它们完全存在于托管 dll 中,并且工作正常。只是 dll 之间的模板交叉似乎给我带来了不好的形象。

4

2 回答 2

2

我不确定,但在我看来,您无法从 dll 导出通用(模板)类。模板在构建时在代码中引用时被实例化。这意味着模板的源代码必须在构建时可见,但事实并非如此。你有一个预编译的 dll,你会如何期望模板实例化?

于 2010-07-20T14:41:34.030 回答
0

所以事实证明,解决方法是将非托管模板实现移动到它们自己的非托管实现 dll 中。暴露模板参数的接口可以通过h文件暴露。但我似乎无法在托管 dll 中实现模板。所以基本上

[基础库公开模板 dll] -> [实现模板 dll] -> [托管 C++ dll]

只要 h 文件隐藏了模板类的实现,一切都很好。

于 2010-07-21T16:22:00.660 回答