尽管选项正确,但静态链接不适用于 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 它们做任何事情或有任何不同:
- 将#pragma comment(lib, "Static Lib.lib") 添加到 Wrapper.cpp
- 用
#pragma managed(push, off)
和 #pragma managed(pop)
包围 #include "Gvar.h"
- 以上两者
更新您的 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
原因是 C
和 C++
中的名称修改方案不同。所以 C
代码库中定义的变量名将与 compiling/linking C++ 代码中链接器搜索的变量名不同。
更多参考资料在 In C++ source, what is the effect of extern "C"?
我有 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 它们做任何事情或有任何不同:
- 将#pragma comment(lib, "Static Lib.lib") 添加到 Wrapper.cpp
- 用
#pragma managed(push, off)
和#pragma managed(pop)
包围 - 以上两者
#include "Gvar.h"
更新您的 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
原因是 C
和 C++
中的名称修改方案不同。所以 C
代码库中定义的变量名将与 compiling/linking C++ 代码中链接器搜索的变量名不同。
更多参考资料在 In C++ source, what is the effect of extern "C"?