【问题标题】:Strange C++/CLI linking issue - unresolved external symbols but header file is linked奇怪的 C++/CLI 链接问题 - 未解析的外部符号,但链接了头文件
【发布时间】:2012-02-08 10:17:30
【问题描述】:

我正在尝试在 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:\zcarter\UDK\WebSvcClients\Debug\JNITester.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:\zcarter\UDK\WebSvcClients\JNITester\JNITester.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:\zcarter\UDK\WebSvcClients\JNITester\JNITester.obj    JNITester

谁能告诉我我在这里做错了什么?

【问题讨论】:

  • 通常您需要使用包含其他目标文件的目标文件或库。
  • 你能告诉我在哪里添加 obj 文件吗?没有lib文件...
  • 您能指定您使用的 Visual Studio 版本吗?
  • 当你编译 JNIUtils.cpp 时,你会得到一个 JNIUtils.o,你需要将该文件提供给链接器。头文件只提供函数的原型,编译够用,不能链接

标签: .net compilation linker c++-cli


【解决方案1】:

当您想将一个项目中的类用于另一个项目时,您需要做两件事:

1) 将库编译代码 (.lib) 链接到您的主应用程序代码。 如果你有vs2010,只需在Project-&gt;Properties-&gt;Common-&gt;References部分添加项目,所有的辛苦工作都会为你完成。

如果你有vs2008或更低版本,则必须将项目添加到Project-&gt;Dependencies...中的依赖项中。然后,进入Project-&gt;Properties-&gt;Linker-&gt;Input 并将.lib 文件添加到现有的.dll 列表中。使用相对路径,以便这将在其他计算机上运行。请注意,在 vs2008 中还有一个 Reference 部分,但我相信它只适用于 CLR 程序集。

2) 将标头添加到包含目录

您已经想到了那部分,但我建议您将它们添加到Project-&gt;Properties-&gt;C++-&gt;Additional Include Directories,因为除非它们与您进行相同的配置,否则您使用的方法将无法在另一台计算机上运行。

【讨论】:

  • 非常感谢Coincoin,这正是我需要做的。
【解决方案2】:

问题的关键在于您试图在另一个项目中使用此对象。

为此,您必须将该类编译成一个类库(我在这里建议一个静态类库),然后在您的编译器设置中为第二个程序链接该库。这实际上有点乏味,但很好尝试!

请注意,这里有两个单独的“链接”。一个在您的代码中,其中包含头文件;还有一个在你的链接器中(发生在编译器之后),你链接目标文件(现在在静态库文件中)。

【讨论】:

  • 第一个“链接”根本不是链接,真的。它只是一个包含(告诉编译器JNIUtils::JNIUtils 存在)。
【解决方案3】:

在我的情况下,错误消息显示LNK2019 unresolved external symbol __imp_someFunctionName referenced in function ...,我发现函数名的前缀__imp_,意味着程序正在使用__declspec(dllimport),而不是__declspec(dllexport)

所以我给Project-&gt;Properties-&gt;Configuration Properties-&gt;C/C++-&gt;Preprocessor加上了正确的名字,让__declspec(dllexport)工作,然后可以解决错误并构建成功。

参考:How can I get rid of the __imp__ prefix in the linker in VC++?

【讨论】:

    猜你喜欢
    • 2013-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-26
    • 1970-01-01
    • 2020-11-06
    • 2014-07-17
    • 2012-03-03
    相关资源
    最近更新 更多