C++ cli 创建C++/本机C++;代码 我目前需要为C++的C++库(TeGEN)编写一个C++/CLI包装器,以便以后在C语言项目中使用。我已经读了不少关于如何做到这一点的文章,但我对我的链接器错误感到茫然。一个叫“山姆AgTEN”的家伙也试图做到这一点,正如他在他的《C++互操作(,)》中所说的那样,第3部分应该解释如何完成我的任务。

C++ cli 创建C++/本机C++;代码 我目前需要为C++的C++库(TeGEN)编写一个C++/CLI包装器,以便以后在C语言项目中使用。我已经读了不少关于如何做到这一点的文章,但我对我的链接器错误感到茫然。一个叫“山姆AgTEN”的家伙也试图做到这一点,正如他在他的《C++互操作(,)》中所说的那样,第3部分应该解释如何完成我的任务。,c++-cli,static-libraries,native,wrapper,tetgen,C++ Cli,Static Libraries,Native,Wrapper,Tetgen,因为Sam想将TetGen与Unity整合在一起,他最终不得不求助于C风格的包装。现在,如果我没有完全弄错的话,我已经尝试在以前的相关项目中使用C风格的包装器 因为我的包装好的TetGen必须在Windows服务器上运行(我想是2008年),所以我的第一个问题是: C++/CLI包装器能否在服务器环境中工作? 根据前面提到的第3部分,我开始编写一个非常简单的包装,但失败得很惨。无论如何,我试图按照我的思路创建一个简单的包装器库,我想与大家分享。我首先创建了一个C#项目,该项目最终应该使用我的包装

因为Sam想将TetGen与Unity整合在一起,他最终不得不求助于C风格的包装。现在,如果我没有完全弄错的话,我已经尝试在以前的相关项目中使用C风格的包装器

因为我的包装好的TetGen必须在Windows服务器上运行(我想是2008年),所以我的第一个问题是: C++/CLI包装器能否在服务器环境中工作?

根据前面提到的第3部分,我开始编写一个非常简单的包装,但失败得很惨。无论如何,我试图按照我的思路创建一个简单的包装器库,我想与大家分享。我首先创建了一个C#项目,该项目最终应该使用我的包装库,并首先添加了一个来自C++projects“simplead”的“Win32”子部分的新项目

在项目设置中,我确保将其编译为静态库(*.lib),并且未使用CLR支持。根据预处理器定义,我假设lib的目标是x86系统:“WIN32”。几乎所有的东西都保留在标准值上。如果我右键单击=>build,它将成功地构建一个名为“simpledd.lib”的库

有一件事我在其他帖子中被指出:如果我在DependencyWalker中打开lib,我会得到一个错误:“找不到DOS或PE签名。这个文件不是有效的32位或64位Windows模块”,这有点令人沮丧我必须做什么才能使DependencyWalker停止显示此错误,因为我认为此32/64问题可能暗示解决方案

无论如何,我有我的自由,现在我想结束它。因此,我使用C++分支的CLR类库模板在我的解决方案中创建了一个名为“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++项目都位于同一层次上的不同文件夹中,因此我指定了headerfile的相对路径。在项目设置中,我现在有了配置标准.dll/clr-开关。在我的VC++文件夹中,我添加了整个soultion的Debug目录的路径,因为引用的lib就是在这里编译的。在“附加依赖项”下的链接器设置中,我添加了名称:“simpledd.lib”

但是,当我想构建包装器时,有一个问题,或者更确切地说是其中的5个问题:

Fehler 3错误LNK2028:Nicht aufgel÷stes令牌(0A00000B)““公共:此调用SimpleAdd::SimpleAdd(无效)”(??0SimpleAdd@@$$FQAE@XZ),auf das in Funktion“public:u clrcall AddWrapper::managedsimplead::managedsimplead(void)”(?)??0ManagedSimpleAdd@AddWrapper@@$$FQ$AAM@XZ)“维维森·维德”路径%\AddWrapper\AddWrapper.obj AddWrapper Fehler 4错误LNK2028:Nicht aufgel÷stes令牌(0A00000C)““公共:此调用SimpleAdd::~SimpleAdd(无效)”(@@$$FQAE@XZ),auf das in function“public:void*u thiscall simplead::
标量删除析构函数(unsigned int)”(??\u gsimplead@@$$FQAEPAXI@Z)“维维森·维德”路径%\AddWrapper\AddWrapper.obj AddWrapper
Fehler 5错误LNK2019:Verweis auf nicht aufgel÷stes externes Symbol“public:u thiscall simpledd::simpledd(void)”(??0simpledd@@$$FQAE@XZ)“在函数中”“public:u clrcall AddWrapper::managedsimplead::managedsimplead(void)”(?)??0ManagedSimpleAdd@AddWrapper@@$$FQ$AAM@XZ)".  %路径%\AddWrapper\AddWrapper.obj AddWrapper
Fehler 6错误LNK2019:Verweis auf nicht aufgel÷stes externes Symbol“公共:u此调用SimpleAdd::~SimpleAdd(无效)”(@@$$FQAE@XZ)“函数中”“public:void*u thiscall SimpleAdd::
scalar deleting destructor'(unsigned int)”(??\u GSimpleAdd@@$$FQAEPAXI@Z)". %路径%\AddWrapper\AddWrapper.obj AddWrapper Fehler 7错误LNK1120:4 nicht aufgel÷ste Externe%path%\Debug\AddWrapper.dll 1 AddWrapper

现在,这些错误的原因可能是什么?是平台对库的无知吗?我没有指定其他内容吗

我必须做什么才能使DependencyWalker停止显示此错误

不要编译为lib文件!它不是可执行文件,也不是动态链接库,因此它没有PE签名。您可以构建一个静态库并将其链接到您的C++/CLI程序集中(如果您愿意的话),也可以简单地将所有代码放入您的C++/CLI程序集中。由你决定

这些错误的原因可能是什么

您直接包含了头文件,让我突出显示您的代码:

class _declspec(dllexport) SimpleAdd
正如您所看到的,您实际上是在使用
\u declspec(dllexport)
进行编译,您没有告诉编译器从库中导入此类类,而是在导出它(链接器会抱怨,因为您声明了该类,但没有任何实现)。当您包含一个类时,必须使用
声明它\u declspec(dllimport)

通常,这个技巧是通过预处理器宏完成的。让我举一个简单的例子。在
simplead.h
文件中,您可以声明:

#if defined(SIMPLEADD_LIB)
#define SIMPLEADD_EXPORTED _declspec(dllexport)
#else
#define SIMPLEADD_EXPORTED _declspec(dllimport)
#endif
然后将代码更改为

class SIMPLEADD_EXPORTED SimpleAdd
simplead
项目中,您可以定义一个名为
simplead_LIB
的宏(从项目设置)。这将导致使用
dllexport
构建库(因为从库中导出该类),但在C++/CLI包装中声明为
dllimport
(正确的原因是没有声明
simplead_LIB
,并且您正在导入该类)

#if defined(SIMPLEADD_LIB)
#define SIMPLEADD_EXPORTED _declspec(dllexport)
#else
#define SIMPLEADD_EXPORTED _declspec(dllimport)
#endif
class SIMPLEADD_EXPORTED SimpleAdd