【发布时间】:2013-08-19 20:00:13
【问题描述】:
我在问这个之前提到了this somewhat similar question,但无法解决我的问题
我正在查看具有许多解决方案的旧应用程序。问题发生在其中一种解决方案中(比如 S)。情况如下:
- S 中的项目(比如 P1)包含所有 C/C++ 文件,需要调用 C# 函数
- 由于 P1 还包含 .c 文件,我不能将
/clr选项与 那 - 如果我将 P1 中的 .c 文件编译为 .cpp 文件,则会生成很多 错误,我不打算更改旧 .c 文件中的源代码
- 所以我创建了另一个启用
/clr的项目(比如P2)并创建了一个头文件 函数声明和函数定义的 .cpp 文件;这 C#调用是在它下面进行的; P2 编译正常 - 请注意,P1 是一个 .dll,而 P2 是作为静态库创建的;
- P2 在 P1 的“框架和参考”中提及
还有一个警告:
警告 LNK4098:defaultlib 'MSVCRT' 与使用其他库冲突; 使用 /NODEFAULTLIB:library
现在有了所有这些,我在 P1 中遇到 3 个链接器错误:
错误 LNK2005:“私人:__thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) 已经定义在 libcmtd.lib(typinfo.obj)
错误 LNK2005:“私有:类 type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) 已经定义在 libcmtd.lib(typinfo.obj)
错误 LNK1169:找到一个或多个多重定义的符号
包括本网站在内的许多在线论坛都会出现此错误。但不知何故,在尝试了这些选项后我无法修复它(我是 .NET 框架的新手)。
重要的一点是,即使我从 P2 中删除了 C# 代码,也会出现同样的错误。
修复它的正确方法是什么?
更新:
P2 只包含 1 个带有函数声明的头文件和 1 个带有函数定义的源文件,这是对 C# 方法的 1 行调用;例如
void Class::foo () { // A static function inside Class
std::string x = marshal_as<std::string>(C#_function);
// ...
}
新添加了 P2 以使用 /clr 进行编译(删除 P2 使解决方案编译正常)。
我正在使用 /MD[d] 选项编译 P1 和 P2。上面的错误是P1抛出的。
如果我将 P2 从静态库 (.lib) 制作为动态链接库 (.dll),那么上述错误就会消失。新的链接器错误来自foo 本身,用于未定义的引用:
错误 LNK2019:无法解析的外部符号“public: void __cdecl Class::foo()" 在函数 { P1 的某个函数}
中引用
【问题讨论】:
-
从本机代码中创建一个静态库要容易得多,然后将其拉入创建实际 DLL 的托管(C++/CLI,使用
/clr)项目中。这使您可以将本机与托管的项目设置分开,同时让链接步骤了解托管。 -
@BenVoigt,您能否将其放入答案中并提供更多详细信息(哪个菜单,哪个选项等)。如果效果好,我会很乐意接受。我是 VC++ 的新手,这让我很烦恼!请注意,在当前的解决方案 S 中,由于存在 .c 文件,我无法将 P1 设为
/clr。 -
嗯,哪个菜单等将取决于哪个版本的 Visual Studio。
-
如果您将项目 2 设为 DLL,将项目 1 设为静态库,并切换项目依赖项,事情可能就开始工作了。
-
@BenVoigt,这就是重点!!请把它放在一个正确的答案中(只要你有时间),我会接受的。顺便说一句,它是 VC++2010。我可以理解 P2 必须是 .dll (我已经设置了)。您可能想解释为什么将 P1 从 .dll 更改为 .lib 有效。
标签: c# c++ visual-c++ clr linker-errors