将非托管C ++ DLL与托管C ++类库DLL链接

时间:2010-10-23 03:05:32

标签: c++-cli mixed-mode

如问题Creating simple c++.net wrapper. Step-by-step

我想在.NET中使用C ++类 但我在使用Visual Studio(2008)构建时遇到了问题。

我有一个非托管类A(使用/ clr编译的C ++)。 我创建了一个C ++ / clr类'Class1',它包装A和匹配 方法委托给A的方法。

如果我在类库中包含A类的单元源文件 Class1的项目(托管)我没有问题 一切都链接和工作正常, 但是我有许多像A这样的非托管C ++类,我想把它们放进去 一个DLL并将该DLL链接到托管库(类包装器)。 [我实际上并不认为此时需要将这些DLL连接在一起, 但编译器似乎需要它,给出如下所示的相同错误。]

我创建了VisualC ++ / CLR / Class库 并添加了我的C ++类(下面列出的A)和构建。 [我使用了默认设置但是 在项目链接器设置中,我已经尝试过两者 使用yes和no注册输出。 没有错误,并且创建了.DLL文件。

我创建了VisualC ++ / CLR / Class库 并创建了包装类'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? 即使在启用CLR的情况下编译非托管C ++库。

(我也尝试编译为静态库,但我无法弄清楚如何添加 .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?

我尝试了References / Add New Reference,并选择了新的这个新DLL;并收到消息“无法添加对文件'C:.. \ unmanaged_lib.dll'的引用,因为它既不是.NET程序集也不是注册的ActiveX控件。” DLL已添加到项目的文件列表中,但编译器似乎忽略了它。

我尝试了Add / Existing项并选择了新的DLL。 但.DLL文件不是可选择的文件类型。

1 个答案:

答案 0 :(得分:6)

根据您的更新中的一些提示,我会尝试两个猜测......

  1. 当unmanaged_lib是静态链接的lib时,您是否将unmanaged_lib项目设置为test_NET_library的依赖项? (在Project Explorer窗口中,右键单击test_NET_library,选择“Project Dependencies ...”并选择unmanaged_lib。)
  2. 当unmanaged_lib是DLL时,您需要按照this回答从DLL导出类,并使test_NET_library依赖于unmanaged_lib项目。