Unmanaged C++ template in managed C++ throws bad image?
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 im开发者_运维技巧age.
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?
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.
精彩评论