我想在 .NET 中使用 C++ 类,但在 Visual Studio (2008) 中构建时遇到问题。
我有一个非托管类 A(用 /clr 编译的 C++)。我创建了一个 C++/clr 类“Class1”,它包装了 A 并使用匹配的方法委托给 A 的方法。
如果我在 Class1 的类库项目中包含类 A 的单元源文件(托管),我没有问题,所有链接都可以正常工作,但是我有许多非托管 C++ 类,如 A,我想将它们放入 DLL 并链接DLL 到托管库(类包装器)。[我实际上认为此时不需要将这些 DLL 链接在一起,但编译器似乎需要它,并给出如下所示的相同错误。]
我创建了 VisualC++ / CLR / 类库并添加了我的 C++ 类(下面列出的 A)并构建。[我使用了默认设置,但在项目链接器设置中,我尝试了使用 yes 和 no 注册输出。] 没有错误,并且创建了 .DLL 文件。
我创建了 VisualC++ / CLR / 类库并创建了包装类“Class1”,我使用了所有默认设置。在项目属性下,我单击“引用”“添加新引用”并选择在第一步中创建的 DLL。
我收到链接器错误:
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
与我在包装类库项目中删除 A.cpp 相同的错误(有效的选项)。我不明白为什么构建首先要尝试解决外部问题,因为这是一个库,而不是程序。
我还需要添加到包装类库项目属性或注册非托管类的 DLL 或编译器选项吗?我还需要一个 .lib 文件来与 DLL 一起使用吗?(项目目标目录中没有出现lib文件)
我是否仍然需要使用 __declspec(dllexport) [它认为这仅适用于 C 样式函数而不是类成员。] 如问题:Export Unmanaged Classes from a Visual C++ DLL? 即使非托管 C++ 库是在启用 CLR 的情况下编译的。
(我也尝试编译为静态库,但我不知道如何将 .lib 文件添加到 CLR 类库项目)。
我的测试课是
namespace Z
{
class A
{
public:
int m1(int p1, int p2);
int m2(int p3, int p4);
};
};
与实施:
#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; };
};
包装类是
#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);
};
};
}
根据问题: C++/CLI Mixed Mode DLL Creation 我也尝试过:
#pragma managed(push, off)
#include "../A.h"
#pragma managed(pop)
而且这种推动也围绕 A.cpp 进行管理。
更新:根据 mcdave 的回复,我删除了 /clr 这产生了一个 DLL,现在如何使这个 DLL 可用于我的 test_NET_library?
我尝试了引用/添加新引用,并选择了新的这个新的 DLL;并收到消息“无法添加对文件 'C:..\unmanaged_lib.dll' 的引用,因为它既不是 .NET 程序集也不是注册的 ActiveX 控件。”。DLL 已添加到项目的文件列表中,但编译器似乎忽略了它。
我尝试了添加/现有项目并选择了新的 DLL。但 .DLL 文件不是可选择的文件类型。