2014-03-29 98 views
-2

我正在使用VS2012,并且尝试从C++调用CLI代码。所以我创建了两个项目。一种是纯C++(不支持CLI)的可执行文件,另一种是CLI(带/ clr开关)的动态库。如果我有主(可执行):从纯C++代码调用C++/CLI代码时出现链接器错误

// 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: :写... \ RealCLI \ RealCLI.obj

错误3错误LNK1120:2周无法解析的外部... \调试\ 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的\我\ vyuka-cppToCLI测试\ vyuka-ManagedUmanaged \ UnmanagedToManagedSource.obj

错误4错误LNK2020:无法解析的令牌(06000003)RealCLI ::写入D:\ ftp \ my \ vyuka-cppToCLI-test \ vyuka-ManagedUmanaged \ UnmanagedToManagedSource.obj

Err或5错误LNK1120:3无法解析的外部D:\ ftp \ my \ vyuka-cppToCLI-test \ Debug \ vyuka-ManagedUmanaged.exe 1

回答

0

其实我没有设置链接的权利。代码是(编辑后)好的。我链接到.obj文件,因为直接链接到.dll时会出错(因为它不是纯粹的C++,而是CLI)。而我只链接了Ccli.obj然后几个星期后我又添加了另一个文件并忘记了链接RealCLI.obj ...

1

您正在犯基本的C++错误。在RealCLI中。CPP:

相反的:

System::String^ GetString() { ... }

使用:

System::String^ RealCLI::GetString() { ... }

同样,对于Write()

+0

现在我觉得有点笨。但是,谢谢。但它不能解决我的问题。如果我将“RealCLI.h”添加到Ccli.cpp文件中,我仍然会收到链接器错误。我将这添加到我的原始问题。 – Sekory