我正试图在C++/CLI中做一些非常简单的事情,但我在Visual Studio中遇到了问题,我不知道为什么。
我有两个项目,其中一个包含一个名为JNIUtils.h的头文件。它的内容非常简单——
#pragma once
class JNIUtils
{
public:
JNIUtils( void );
~JNIUtils( void );
};
它的实现也非常简单——
#include "stdafx.h"
#include "JNIUtils.h"
JNIUtils::JNIUtils( void )
{
}
JNIUtils::~JNIUtils( void )
{
}
我所要做的就是在另一个项目中创建一个新定义类型的对象。在我包含这个头文件的项目中,我已经转到
项目属性>配置属性>VC++目录>包含目录
我添加了一个条目,其中包含头文件所在的路径(JNIUtils.h)
我试图在中创建此对象实例的CPP文件如下所示:
#include "stdafx.h"
#include "JNIUtils.h"
using namespace System;
int main(array<System::String ^> ^args)
{
JNIUtils *util = new JNIUtils();
Console::WriteLine(L"Hello World");
return 0;
}
当我尝试编译时,我得到以下错误:
Error 3 error LNK1120: 2 unresolved externals C:zcarterUDKWebSvcClientsDebugJNITester.exe JNITester
Error 2 error LNK2019: unresolved external symbol "public: __thiscall JNIUtils::JNIUtils(void)" (??0JNIUtils@@$$FQAE@XZ) referenced in function "int __clrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@System@@@Z) C:zcarterUDKWebSvcClientsJNITesterJNITester.obj JNITester
Error 1 error LNK2028: unresolved token (0A000009) "public: __thiscall JNIUtils::JNIUtils(void)" (??0JNIUtils@@$$FQAE@XZ) referenced in function "int __clrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@System@@@Z) C:zcarterUDKWebSvcClientsJNITesterJNITester.obj JNITester
有人能告诉我我在这里做错了什么吗?
当您想将一个项目中的类用于另一个项目时,需要做两件事:
1)将库编译的代码(.lib)链接到您的主要应用程序代码如果你有vs2010,只需在Project->Properties->Common->References
部分添加项目,所有的艰苦工作都会为你完成。
如果您有vs2008或更低版本,则必须将项目添加到Project->Dependencies...
中的依赖项中。然后,进入Project->Properties->Linker->Input
,将.lib文件添加到现有的.dll列表中。使用相对路径,以便在其他计算机上运行。请注意,vs2008中还有一个Reference
节,但我认为它只适用于CLR程序集。
2)将标题添加到包含目录
您已经配置好了该部分,但我建议您将它们添加到Project->Properties->C++->Additional Include Directories
中,因为除非它们进行与您相同的配置,否则您使用的方法在其他计算机上不起作用。
问题的关键是您试图在另一个项目中使用此对象。
要做到这一点,您必须将类编译到类库中(我在这里建议使用静态类库),然后在第二个程序的编译器设置中链接此库。这实际上有点乏味,但非常适合尝试!
请注意,这里有两个独立的"链接"。代码中的一个,其中包含头文件;链接器中的一个(发生在编译器之后)链接对象文件(现在位于静态库文件中)。
在我的情况下,错误消息显示LNK2019 unresolved external symbol __imp_someFunctionName referenced in function ...
,我发现函数名的前缀__imp_
意味着程序使用的是__declspec(dllimport)
,而不是__declspec(dllexport)
。
所以我给Project->Properties->Configuration Properties->C/C++->Preprocessor
加了一个合适的名字,让__declspec(dllexport)
工作,这样就可以解决错误并构建成功。
参考:如何在VC++中去掉链接器中的__imp__前缀?