我目前需要为本地 C++ 库 (TetGen) 编写 C++/CLI 包装器,以便以后在 C# 项目中使用。我已经阅读了很多关于如何做到这一点的文章,但对我的链接器错误感到茫然。一个叫做“Sam Agten”的小伙子也试图做到这一点,正如他在他的博客中所说的那样,这使我看到了一个关于 C++ 互操作的系列(第 1部分、第 2部分、第 3部分、第 4部分、第 5 部分),其中第 3 部分应该是解释如何做我完成的事情。
因为 Sam 想将 TetGen 与 Unity 集成,所以他最后不得不求助于 C-Style-Wrappers。现在,如果我没有完全弄错的话,我已经尝试在以前的相关项目中使用 C-Style-Wrappers。
因为我打包的 TetGen 必须在 Windows Server(我认为是 2008 年)上运行,所以我的第一个问题是: C++/CLI-Wrapper 将在服务器环境中工作吗?
我根据前面提到的第 3 部分开始编写一个非常简单的包装器,但失败得很惨。无论如何,我试图沿着思路创建一个简单的包装库,我想与你分享。我首先创建了一个 C# 项目,它最终应该使用我的包装库,并首先从 C++ 项目“SimpleAdd”的“Win32”子部分添加一个新项目。
//SimpleAdd.h
class _declspec(dllexport) SimpleAdd
{
public:
SimpleAdd();
~SimpleAdd();
int Add(int a,int b);
};
//SimpleAdd.cpp
#include "SimpleAdd.h"
int SimpleAdd::Add(int a, int b)
{
return a+b;
}
在项目设置中,我确保它编译为静态库 (*.lib),并且没有使用 CLR 支持。从预处理器定义中,我假设 lib 是针对 x86 系统的:“WIN32”。一切都保留在标准值上。如果我右键单击 => 构建,它将成功构建一个名为“SimpleAdd.lib”的库。
我通过其他帖子指出的一件事:如果我在 DependencyWalker 中打开库,我会收到一条错误消息:“未找到 DOS 或 PE 签名。此文件不是有效的 32 位或 64 位 Windows 模块”,即有点令人沮丧。我必须做什么才能使 DependencyWalker 停止显示此错误,因为我认为这个 32/64 问题可能暗示解决方案。
无论如何,我有我的库,现在我想把它包起来。因此,我使用 C++ 分支的 CLR-ClassLibrary-template 在我的解决方案中创建了一个名为“AddWrapper”的新项目。
// AddWrapper.h
#pragma once
#include "..\SimpleAdd\SimpleAdd.h"
using namespace System;
namespace AddWrapper {
public ref class ManagedSimpleAdd
{
private:
SimpleAdd *sa;
public:
ManagedSimpleAdd();
~ManagedSimpleAdd();
int Add(int a, int b);
};
}
//AddWrapper.cpp
#include "AddWrapper.h"
using namespace AddWrapper;
ManagedSimpleAdd::ManagedSimpleAdd() : sa(new SimpleAdd())
{
}
ManagedSimpleAdd::~ManagedSimpleAdd(){delete sa;}
int ManagedSimpleAdd::Add(int a, int b)
{
return sa->Add(a,b);
}
由于两个 C++ 项目都位于同一层次结构的不同文件夹中,因此我指定了头文件的相对路径。在项目设置中,我现在拥有配置标准.dll和/clr -switch。在我的 VC++ 文件夹中,我添加了整个灵魂的调试目录的路径,因为这是编译引用的库的位置。在“附加依赖项”下的链接器设置中,我添加了名称:“SimpleAdd.lib”。
但是,当我想构建包装器时,会出现问题,或者说是其中的 5 个问题:
Fehler 3 错误 LNK2028: Nicht aufgel÷stes Token (0A00000B) ""public: __thiscall SimpleAdd::SimpleAdd(void)" (??0SimpleAdd@@$$FQAE@XZ)", auf das in Funktion ""public: __clrcall AddWrapper ::ManagedSimpleAdd::ManagedSimpleAdd(void)" (??0ManagedSimpleAdd@AddWrapper@@$$FQ$AAM@XZ)" 版本。%path%\AddWrapper\AddWrapper.obj AddWrapper Fehler 4 错误 LNK2028: Nicht aufgel÷stes 令牌 (0A00000C) ""public: __thiscall SimpleAdd::~SimpleAdd(void)" (??1SimpleAdd@@$$FQAE@XZ)" , auf das in Funktion ""public: void * __thiscall SimpleAdd::
scalar deleting destructor'(unsigned int)" (??_GSimpleAdd@@$$FQAEPAXI@Z)" verwiesen wird. %path%\AddWrapper\AddWrapper.obj AddWrapper Fehler 5 error LNK2019: Verweis auf nicht aufgel÷stes externes Symbol ""public: __thiscall SimpleAdd::SimpleAdd(void)" (??0SimpleAdd@@$$FQAE@XZ)" in Funktion ""public: __clrcall AddWrapper::ManagedSimpleAdd::ManagedSimpleAdd(void)" (??0ManagedSimpleAdd@AddWrapper@@$$FQ$AAM@XZ)". %path%\AddWrapper\AddWrapper.obj AddWrapper Fehler 6 error LNK2019: Verweis auf nicht aufgel÷stes externes Symbol ""public: __thiscall SimpleAdd::~SimpleAdd(void)" (??1SimpleAdd@@$$FQAE@XZ)" in Funktion ""public: void * __thiscall SimpleAdd::
标量删除析构函数'(unsigned int)" (??_GSimpleAdd@@$$FQAEPAXI@Z)"。%path%\AddWrapper\AddWrapper.obj AddWrapper Fehler 7 错误 LNK1120: 4 nicht aufgel÷ste Externe %path%\Debug\AddWrapper。
现在,这些错误的原因可能是什么?是 lib 的平台迷惑性吗?我是否错过了指定其他内容?