非托管 C++托管 C++ 中的模板会造成不良形象吗?
我有一个托管 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 交叉,
令我烦恼的是,我有几个完全位于托管 dll 中的非托管 C++ 模板,并且它们工作正常,只是 dll 之间的交叉模板似乎给我带来了不好的印象。 。
I have a Managed C++ dll which dynamically links with an unmanaged C++ dll. The managed C++ derives several unmanaged classes from abstract interfaces in the unmanaged dll.
This works fine.
ICustomer.h in unmanaged dll
// uses macro __declspec(dllexport)
class EXPORT_API ICustomer
{
public:
virtual void PlaceOrder() = 0;
//...
};
LocalCustomer.h in managed C++
#include "unmanagedlib/ICustomer.h"
//an unmanaged derived class defined in the managed dll
class LocalCustomer : public ICustomer
{
public:
void PlaceOrder();
//...
};
LocalCustomer is used in the Managed dll. I can pass it to functions in the unmanaged dll and it all works fine.
Here is the problem.
I get an STATUS_INVALID_IMAGE_FORMAT at startup when I try to implement an interface which exposes a template.
Does not run.
in unmanaged Dll
stuct Order
{
double price;
//...
};
template<typename T>
class EXPORT_API ICollection<T>
{
//...
};
class EXPORT_API IFactory
{
public:
virtual ICollection<Order>& GetOrders() = 0;
}
in the managed C++ dll
class OrderCollection : public ICollection<Order>
{
//...
};
class LocalFactory : public IFactory
{
public:
virtual ICollection<Order>& GetOrders() { return m_orders; }
private:
OrderCollection m_orders;
};
I have narrowed it down the template override GetOrders. Having the code in the managed dll causes a dialog to open "The application was unable to start correctly (0xc000007b) which is just the STATUS_INVALID_IMAGE_FORMAT HRESULT getting thrown by the managed loader. Removing the code allows it to run. So whats wrong with the template? Why can't I use it in the managed dll.
One other clue, not sure if this is a distraction of not.. I am compiling a 32 bit app and running on Win7 x64. Like I said with works just fine as long as the template does not cross the dll from unmanaged to managed.
What kills me is I I have several unmanaged C++ templates that live wholly within the managed dll and they work fine. It is just templates crossing between the dll that seems to give me bad image.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不确定,但在我看来,你不能从 dll 导出通用(模板)类。在构建时在代码中引用模板时,模板就会被实例化。这意味着模板的源代码必须在构建时可见,但事实并非如此。你有一个预编译的 dll,你期望模板如何实例化?
I am not sure, but it seem to me you can't export generic (template) classes from a dll. Templates get instantiated when referenced in code at build time. This means that template's source code has to be visible at build time, which is not the case. You have a precompiled dll, how would you expect template instantiation?
因此,解决方法是将非托管模板实现移至它们自己的非托管实现 dll 中。暴露模板参数的接口可以通过h文件暴露。但我似乎无法在托管 dll 中实现该模板。
所以基本上
[基础库公开模板 dll] -> [实现模板dll]-> [ 托管 C++ dll ]
只要 h 文件隐藏了模板类的实现,一切都很好。
So it turns out that the workaround was to move the unmanaged template implementations into their own unmanaged implementation dll. The interface which expose template parameters CAN be exposed via h file. But I could not seem to implement the template inside the managed dll.
So basically
[base library exposes templates dll] -> [ implement templates dll ] -> [ managed C++ dll ]
It was all good as long as the h files hid the implementation of the template class.