尽管选项正确,但静态链接不适用于 C++/CLI(未解析的外部符号)

Static linking does not work with C++/CLI (unresolved external symbol) despite correct options

我有 2 个项目:一个本机 C 项目和一个 C++/CLI 包装器,它将用于允许 C 项目与 C# 程序互操作。这两个项目都位于同一个 Visual Studio 2010 解决方案中。为了允许互操作,我计划将 C++/CLI 包装器静态 link 与本机 C 项目一起使用,以便我可以访问其全局变量和函数,并同时拥有包装器和本机 C 项目编译成一个可加载的 DLL。

对于我的 C 项目,我已将项目配置类型设置为 "static library",并且不支持 CLR。据我所见,它只生成一个 .lib 文件,没有 DLL。因为 VS2010 使用 C++ 编译器,我想代码正在编译为 C++,这对我来说没问题。

我使用 C++/CLI 向导创建了第二个项目,然后在 linker 选项及其目录中添加了库的名称。如果我理解正确,这应该使 linker link 成为带有 C++/CLI DLL 的静态库。我还添加了本机 C 项目作为对 C++/CLI 包装器项目的引用(在框架和参考中)

为了对此进行测试,我尝试在我的 C++/CLI .cpp 文件中使用 C 项目中的全局变量。这是我的代码(删除了无关的东西(至少,我希望它们是无关的)):

Wrapper.cpp(位于 C++/CLI 包装器项目中)

#include "stdafx.h"

#include "Wrapper.h"
#include "Gvar.h"

Wrapper::Wrapper()
{
}

Wrapper::~Wrapper()
{
}

Wrapper::!Wrapper()
{
}

void Wrapper::initialize(int year)
{
    g_year = year
    System::Console::WriteLine(::g_year);
}

Gvar.h(位于静态库项目中)

#ifndef GVAR_H
#define GVAR_H

extern int g_year;

#endif

Gvar.c(位于静态库项目中)

#include "Gvar.h"

int g_year = 2013;

当我构建 C++/CLI 项目时,出现以下 linker 错误:

2>Wrapper.obj : error LNK2020: unresolved token (0A00003B) "int g_year" (?g_year@@3HA)
2>Wrapper.obj : error LNK2001: unresolved external symbol "int g_year" (?g_year@@3HA)

我不确定我做错了什么。我在C文件里明确定义了变量

我也知道 linker 实际上会查看我指定的库,因为在 linker 选项中启用 "show progress" 后我可以看到 linker 在图书馆内搜索,但似乎没有找到任何东西:

(一小段输出):

...
2>  
2>  Finished searching libraries
2>  Search transition ?g_year@@3HA->__t2m@?g_year@@3HA
2>  Search transition __pRawDllMain->__t2m@__pRawDllMain
2>  Merging metadata
2>  Finished merging metadata
2>  
2>  Searching libraries
2>      Searching C:\Usersa3eedi\Documents\Solution\Static Lib\Debug\Static Lib.lib:
2>      Searching C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\MSVCRTD.lib:
2>      Searching C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\OLDNAMES.lib:
2>      Searching C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\MSVCMRTD.lib:
2>      Searching C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\lib\MSCOREE.lib:
2>        Found __CorDllMain@12
2>          Loaded MSCOREE.lib(mscoree.dll)
2>        Found __IMPORT_DESCRIPTOR_mscoree
2>          Referenced in MSCOREE.lib(mscoree.dll)
2>          Loaded MSCOREE.lib(mscoree.dll)
2>        Found mscoree_NULL_THUNK_DATA
2>          Referenced in MSCOREE.lib(mscoree.dll)
2>          Loaded MSCOREE.lib(mscoree.dll)
2>      Searching C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\lib\kernel32.lib:
2>      Searching C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\lib\uuid.lib:
2>      Searching C:\Usersa3eedi\Documents\Solution\Static Lib\Debug\Static Lib.lib:
2>      Searching C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\MSVCRTD.lib:
2>      Searching C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\OLDNAMES.lib:
2>      Searching C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\MSVCMRTD.lib:
2>  
2>  Finished searching libraries
2>  Generating clr ijw/native image
2>  
2>  Searching libraries
2>      Searching C:\Usersa3eedi\Documents\Solution\Static Lib\Debug\Static Lib.lib:
...

有问题的静态库是"Static Lib.lib"。它在上面的 linker 输出中。

为什么 linker 无法解析我的全局变量?

我在谷歌搜索后尝试了以下方法,但是 none 它们做任何事情或有任何不同:

更新您的 wrapper.cpp 以将 gvar.h 包含在 extern C 中。

#include "stdafx.h"
#include "Wrapper.h"

#ifdef __cplusplus 
extern "C" {
#endif

#include "gvar.h"

#ifdef __cplusplus
}
#endif

...
//other code in wrapper.cpp

原因是 CC++ 中的名称修改方案不同。所以 C 代码库中定义的变量名将与 compiling/linking C++ 代码中链接器搜索的变量名不同。

更多参考资料在 In C++ source, what is the effect of extern "C"?