我有一个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之间的模板,似乎给我带来了不好的形象。
答案 0 :(得分:2)
我不确定,但在我看来,你无法从dll中导出通用(模板)类。在构建时在代码中引用时,模板会实例化。这意味着模板的源代码必须在构建时可见,而实际情况并非如此。你有一个预编译的dll,你期望模板实例化吗?
答案 1 :(得分:0)
事实证明,解决方法是将非托管模板实现移动到他们自己的非托管实现dll中。暴露模板参数的接口可以通过h文件公开。但我似乎无法在托管dll中实现模板。 所以基本上
[基础库公开模板dll] - &gt; [实施模板dll] - &gt; [托管C ++ dll]
只要h文件隐藏了模板类的实现,这一切都很好。