8

正如在创建简单的 c++.net 包装器问题中一样。一步步

我想在 .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 文件不是可选择的文件类型。

4

1 回答 1

6

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

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