Linking unmanaged C++ DLL with managed C++ class library DLL
As in the question Creating simple c++.net wrapper. Step-by-step
I am tring to use C++ classes in .NET but I am having problems building in Visual Studio (2008).
I have an unmanaged class A (C++ compiled with /clr). I created a C++/clr class 'Class1' which wraps A and with matching method delegates to A's methods.
If I include class A's unit source file in the class library project for Class1 (managed) I have no problems everything links and works fine, But I have many unmanaged C++ classes like A and I am tring to put them in a DLL and link that DLL to the managed library (of class wrappers). [I actually don't see a need to link these DLL's together at this point, but the compiler appears to be requiring it, giving the same errors shown below.]
I created VisualC++ / CLR / Class library and added my C++ class (A listed below) and build. [I used the default settings but in the project linker settings I've tried both Register output with yes and no.] There were no errors and the .DLL file was created.
I created VisualC++ / CLR / Class library and created the wrapper class 'Class1' I used all default settings. Under project properties I clicked 'References' 'Add New Reference" and selected the DLL created in the first step.
I get linker errors:
test_NET_library.obj : error LNK2028: unresolved token (0A000009) "public: int __thiscall Z::A::m1(int,int)" (?m1@A@Z@@$$FQAEHHH@Z) referenced in function "public: int __clrcall test_NET_library::Class1::m1(int,int)" (?m1@Class1@test_NET_library@@$$FQ$AAMHHH@Z)
test_NET_library.obj : error LNK2028: unresolved token (0A00000A) "public: int __thiscall Z::A::m2(int,int)" (?m2@A@Z@@$$FQAEHHH@Z) referenced in function "public: int __clrcall test_NET_library::Class1::m2(int,int)" (?m2@Class1@test_NET_library@@$$FQ$AAMHHH@Z)
test_NET_library.obj : error LNK2019: unresolved external symbol "public: int __thiscall Z::A::m1(int,int)" (?m1@A@Z@@$$FQAEHHH@Z) referenced in function "public: int __clrcall test_NET_library::Class1::m1(int,int)" (?m1@Class1@test_NET_library@@$$FQ$AAMHHH@Z)
test_NET_library.obj : error LNK2019: unresolved external symbol "public: int __thiscall Z::A::m2(int,int)" (?m2@A@Z@@$$FQAEHHH@Z) referenced in function "public: int __clrcall test_NET_library::Class1::m2(int,int)" (?m2@Class1@test_NET_library@@$$FQ$AAMHHH@Z)
C:\temp\test_Cpp_CLI\test_NET_library\Debug\test_NET_library.dll : fatal error LNK1120: 4 unresolved externals
The same errors as if I remove A.cpp in the wrapper class library project (the option that works). I don't understand why the build is trying to resolve externals in the first place because this is a library, not a program.
Is there something else I need to add to the wrapper class library project properties or register the DLL of unmanaged classes, or compiler options? Do I also need a .lib file to go with the DLL? (no lib file appears in the pro开发者_JAVA百科jects target directory)
Do I still have to use __declspec(dllexport) [it thought that was only for C style functions not class members.] as in the question: Export Unmanaged Classes from a Visual C++ DLL? even though the unmanaged C++ library is compiled with CLR enabled.
(I did also try compiling as a static library, but I can't figure out how to add the .lib file to the CLR class library project).
My test class is
namespace Z
{
class A
{
public:
int m1(int p1, int p2);
int m2(int p3, int p4);
};
};
with the implementation:
#include "A.h"
namespace Z
{
int A::m1(int p1, int p2) { return p1+p2; };
int A::m2(int p3, int p4) { return p3 * p4; };
};
And the wrapper class is
#pragma once
#include "../A.h"
using namespace System;
namespace test_NET_library {
public ref class Class1
{
private: Z::A *a;
public: Class1()
: a(new Z::A)
{}
public: inline int m1(int p1, int p2)
{ return a->m1(p1,p2);
};
public: inline int m2(int p3, int p4)
{return a->m2(p3,p4);
};
};
}
As per the question: C++/CLI Mixed Mode DLL Creation I have also tried:
#pragma managed(push, off)
#include "../A.h"
#pragma managed(pop)
And also this pushing managed around A.cpp.
Update: As per mcdave's response I removed the /clr this produced a DLL, now how do I make this DLL available to my test_NET_library?
I tried References/Add New Reference, and selected the new this new DLL; and got the message "Could not add reference to file 'C:..\unmanaged_lib.dll' because it is neither .NET assembly or registered ActiveX control.". The DLL was added to the project's file list, but the compiler appears to be ignoring it.
I tried Add/Existing item and selected the new DLL. but .DLL files are not a selectable file type.
With the few hints from your update I will try two guesses...
- When unmanaged_lib is a statically linked lib, have you set the unmanaged_lib project to be a dependency of test_NET_library? (In the Project Explorer window, right-click on test_NET_library, select "Project Dependencies..." and select unmanaged_lib.)
- When unmanaged_lib is a DLL, you need to export the class from the DLL by following this answer and also make the test_NET_library depend on the unmanaged_lib project.
精彩评论