【问题标题】:Linking unmanaged C++ DLL with managed C++ class library DLL将非托管 C++ DLL 与托管 C++ 类库 DLL 链接
【发布时间】:2011-04-29 11:19:40
【问题描述】:

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

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

我有一个非托管类 A(使用 /clr 编译的 C++)。 我创建了一个包含 A 并匹配的 C++/clr 类“Class1” 方法委托给 A 的方法。

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

我创建了 VisualC++ / CLR / 类库 并添加了我的 C++ 类(下面列出的 A)并构建。 [我使用了默认设置,但是 在项目链接器设置中我都尝试过 使用是和否注册输出。] 没有错误,并创建了 .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?

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

我尝试了添加/现有项目并选择了新的 DLL。 但 .DLL 文件不是可选择的文件类型。

【问题讨论】:

  • 尝试从 A 类的 DLL 中删除 /clr(意味着使其成为“正常”的 win32 dll),如果这不起作用,请更新您的问题。
  • @mcdave:我这样做了,但后来我不知道如何让 test_NET_libary “知道”或“链接到”这个包含 A 的 unmanaged_lib.DLL(参见我上面的编辑)。这与我尝试将 unmanaged_lib 用作静态链接的 .lib 的问题相同。

标签: c++-cli mixed-mode


【解决方案1】:

根据您更新的一些提示,我将尝试两种猜测...

  1. 当 unmanaged_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 项目。

【讨论】:

  • 解决方案1有效(通常我使用Embarcadero C++Builder,您只需将编译的.lib文件添加到您的项目中,甚至不需要在您的项目组中拥有所有静态库项目(解决方案),也不需要设置依赖项)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-07
  • 2013-01-07
相关资源
最近更新 更多