托管C ++中的非托管C ++模板会丢失坏图像?

时间:2010-07-20 14:34:19

标签: templates c++-cli badimageformatexception

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

这很好用。 ICustomer.h在非托管DLL中

//  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用于Managed 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。

让我失望的是我有几个完全位于托管dll中的非托管C ++模板,它们工作正常。这只是dll之间的模板,似乎给我带来了不好的形象。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

[基础库公开模板dll] - &gt; [实施模板dll] - &gt; [托管C ++ dll]

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