简体   繁体   English

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

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

I have 2 projects: a native C project, and a C++/CLI wrapper which will be used to allow the C project to interop with a C# program. 我有2个项目:本机C项目和C ++ / CLI包装器,它们将用于允许C项目与C#程序互操作。 Both projects are located in the same Visual Studio 2010 solution. 这两个项目都位于同一Visual Studio 2010解决方案中。 In order to allow for interop, I was planning to have the C++/CLI wrapper statically link with the native C project, so that I can access its global variables and functions, and have both the wrapper and the native C project compile into one loadable DLL. 为了允许互操作,我计划让C ++ / CLI包装器与本地C项目静态链接,以便我可以访问其全局变量和函数,并将包装器和本地C项目都编译为一个可加载的DLL。

For my C project, I've set the project configuration type to "static library", and with no CLR support. 对于我的C项目,我将项目配置类型设置为“静态库”,并且不支持CLR。 From what I've seen, it builds only to a .lib file, with no DLL. 从我所看到的,它仅构建为.lib文件,没有DLL。 Because VS2010 uses a C++ compiler, I suppose the code is being compiled as C++, which is fine by me. 因为VS2010使用的是C ++编译器,所以我认为代码被编译为C ++,这对我来说很好。

I've used the C++/CLI wizard to create the second project, and then I added the name of the library in the linker options and its directory. 我使用C ++ / CLI向导创建了第二个项目,然后在链接器选项及其目录中添加了库的名称。 If I understand correctly this should make the linker link the static library with the C++/CLI DLL. 如果我理解正确,则应使链接器将静态库与C ++ / CLI DLL链接。 I also added the native C project as a reference to the C++/CLI wrapper project (in Frameworks and References) 我还添加了本机C项目作为对C ++ / CLI包装项目的引用(在“框架和参考”中)

To test this, I tried using a global variable from the C project in my C++/CLI .cpp file. 为了对此进行测试,我尝试在C ++ / CLI .cpp文件中使用C项目中的全局变量。 This is my code (with unrelated stuff removed (at least, I hope they're unrelated)): 这是我的代码(删除了不相关的内容(至少,我希望它们不相关)):

Wrapper.cpp (located in C++/CLI wrapper project) 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 (located in static library project) Gvar.h(位于静态库项目中)

#ifndef GVAR_H
#define GVAR_H

extern int g_year;

#endif

Gvar.c (located in static library project) Gvar.c(位于静态库项目中)

#include "Gvar.h"

int g_year = 2013;

When I build the C++/CLI project, I get the following linker error: 生成C ++ / CLI项目时,出现以下链接器错误:

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)

I'm not sure what I'm doing wrong. 我不确定自己在做什么错。 I clearly defined the variable in the C file. 我在C文件中明确定义了变量。

I also know that the linker actually looks at the library I specified, because after enabling "show progress" in the linker options I can see that the linker searches inside the library, but it seems it's not finding anything: 我也知道链接器实际上是在查看我指定的库,因为在链接器选项中启用“显示进度”后,我可以看到该链接器在库中搜索,但是似乎找不到任何东西:

(a small snippet of the output): (输出的一小段):

...
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:\Users\9a3eedi\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:\Users\9a3eedi\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:\Users\9a3eedi\Documents\Solution\Static Lib\Debug\Static Lib.lib:
...

The static library in question is "Static Lib.lib". 有问题的静态库是“ Static Lib.lib”。 It's in the linker output above. 在上面的链接器输出中。

Why isn't the linker able to resolve my global variable? 链接器为什么不能解析我的全局变量?

I have tried the following after some googling, but none of them do anything or make any difference: 经过一番谷歌搜索后,我尝试了以下操作,但是它们都没有做任何事情或有任何不同之处:

  • Adding #pragma comment(lib, "Static Lib.lib") to Wrapper.cpp 向Wrapper.cpp添加#pragma注释(lib,“ Static Lib.lib”)
  • Surrounding the #include "Gvar.h" with #pragma managed(push, off) and #pragma managed(pop) #include "Gvar.h"#include "Gvar.h" #pragma managed(push, off)#include "Gvar.h" #pragma managed(pop)周围
  • Both of the above 以上两者

Update your wrapper.cpp to include the gvar.h within extern C . 更新您的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

The cause is name mangling scheme in C and C++ are different. 原因是CC++中的名称处理方案不同。 So the variable name defined in library of C code will not be same as the one searched by linker while compiling/linking C++ code. 因此,在C代码库中定义的变量名将与在编译/链接C ++代码时链接器搜索到的变量名不同。

More reference at In C++ source, what is the effect of extern "C"? 在C ++源中有更多参考,外部“ C”的作用是什么?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM