我正在使用VS2012,我正在尝试从C ++调用CLI代码。所以我创建了两个项目。一个是可执行文件,它是纯C ++(没有CLI支持),第二个是动态库,它是CLI(带有/ clr开关)。如果我有main(可执行文件):
// main.cpp file
#include "..\CLILibrary\CCli.h"
int main()
{
Ccli test = Ccli();
test.Write();
return 0;
}
CLI库中的一个类(使用CLR开启构建):
// Ccli.h file
#pragma once
class Ccli
{
public:
void Write();
void CallRealCLIClass();
};
// Ccli.cpp file
#include " Ccli.h"
void Ccli::Write()
{
System::Console::WriteLine("In Ccli class.");
}
void Ccli::CallRealCLIClass()
{
// here I would like to call RealCLI class
}
到目前为止一切正常。据我所知,该头文件(Ccli.h)不能使用CLI中的任何内容,因为它必须对我的可执行文件是可读的,这纯粹是用C ++编写的(理论上如果我使用像#ifdef _MANAGED这样的东西,但这不是我的意思)。但在源文件(Ccli.cpp)中它很好。
但是现在我想使用完全CLI的类。我想从Ccli.cpp文件中调用它。所以我在CLI库中创建了以下类:
// RealCLI.h file
#pragma once
ref class RealCLI
{
public:
RealCLI(void);
System::String^ GetString();
void Write(System::String^ s);
};
// RealCLI.cpp file
#include "RealCLI.h"
RealCLI::RealCLI(void){}
System::String^ GetString()
{
System::String^ s = gcnew System::String("GetString in RealCLI class");
return s;
}
void Write(System::String^ s)
{
System::Console::WriteLine(s);
}
现在我有以下问题,我不知道为什么。我从链接器收到此错误:
错误1错误LNK2020:未解析的令牌(06000002)RealCLI :: GetString ... \ RealCLI \ RealCLI.obj
错误2错误LNK2020:未解析的令牌(06000003)RealCLI :: Write ... \ RealCLI \ RealCLI.obj
错误3错误LNK1120:2个未解析的外部... \ Debug \ RealCLI.dll 1
所以我的库很好(它构建没有问题)但我的可执行文件有这些链接器错误。我不明白为什么?我不在我的可执行项目中使用此文件,为什么我的可执行文件甚至关心它?我找到了解决方法。但由于我不知道为什么原始程序不起作用,我认为它只是解决方法。我的解决方法是删除RealCLI.cpp文件并将所有内容放在头文件中:
// RealCLI.h file
#pragma once
ref class RealCLI
{
public:
RealCLI(void) {}
// I cannot even put definition outside declaration of my class
System::String^ GetString()
{
System::String^ s = gcnew System::String("GetString in RealCLI class");
return s;
}
void Write(System::String^ s)
{
System::Console::WriteLine(s);
}
};
为什么?我究竟做错了什么?我的一些假设是错的吗?
修改
// Ccli.cpp file
#include " Ccli.h"
// !!!added this line:
#include "RealCLI.h"
void Ccli::Write()
{
System::Console::WriteLine("In Ccli class.");
}
void Ccli::CallRealCLIClass()
{
// here I would like to call RealCLI class
}
我在RealCli.cpp中修复了名称空间,这有帮助。但是当我添加#include“RealCLI.h”时,无论如何我都会遇到这些错误:
错误2错误LNK2020:未解析的令牌(06000001)RealCLI ::。ctor D:\ ftp \ my \ vyuka-cppToCLI-test \ vyuka-ManagedUmanaged \ UnmanagedToManagedSource.obj
错误3错误LNK2020:未解析的令牌(06000002)RealCLI :: GetString D:\ ftp \ my \ vyuka-cppToCLI-test \ vyuka-ManagedUmanaged \ UnmanagedToManagedSource.obj
错误4错误LNK2020:未解析的令牌(06000003)RealCLI ::写入D:\ ftp \ my \ vyuka-cppToCLI-test \ vyuka-ManagedUmanaged \ UnmanagedToManagedSource.obj
错误5错误LNK1120:3个未解析的外部D:\ ftp \ my \ vyuka-cppToCLI-test \ Debug \ vyuka-ManagedUmanaged.exe 1
答案 0 :(得分:1)
你犯了基本的C ++错误。在RealCLI.cpp中:
而不是:
System::String^ GetString() { ... }
使用:
System::String^ RealCLI::GetString() { ... }
同样适用于Write()
答案 1 :(得分:0)
实际上我没有设置链接器。代码是(编辑后)确定。我链接到.obj文件,因为直接链接到.dll时出错(因为它不是纯C ++而是CLI)。我只链接了Ccli.obj然后几周后我添加了另一个文件并忘记链接RealCLI.obj ...