非托管C++代码LNK2019未解析外部符号问题解决方案咨询
解决LNK2019未解析外部符号问题,保持头文件与实现分离
这个LNK2019错误的核心原因很明确:你的导出函数声明和实现的名字修饰规则不匹配。头文件里用extern "C"声明了要导出的函数(告诉编译器用C风格的名字生成规则),但.cpp文件里的函数实现却没加extern "C",导致编译器按C++的名字 mangling 生成符号,链接器自然找不到对应的外部符号。
下面是具体的修复步骤:
1. 修改Sum.cpp的函数实现
把三个对象处理函数的实现包裹在extern "C"块里,和头文件的声明保持一致:
#include "Sum.h" using namespace Something::Really::Simple; SimpleClass::SimpleClass() { // empty constructor } double SimpleClass::SumValues(double x, double y) { return x + y; } #pragma region Class handlers extern "C" { SimpleClass* CreateInstance() { return new SimpleClass; } double InvokeSumValues(SimpleClass*inst, double x, double y ) { return inst->SumValues( x, y); } void InstanceDelete(SimpleClass*inst) { delete inst; } } #pragma endregion
2. 检查C++项目的编译设置(以Visual Studio为例)
- 确保项目类型是动态链接库(DLL):右键项目 -> 属性 -> 配置属性 -> 常规 -> 项目默认值 -> 配置类型,选择
动态库(.dll) - 确认预处理器定义包含
_WIN32:项目属性 -> C/C++ -> 预处理器 -> 预处理器定义,确保有_WIN32(默认情况下Windows平台的项目会自动添加) - 保持平台一致性:你的C++项目的平台(x86/x64)要和调用它的.NET项目平台完全一致,否则会出现加载失败或符号找不到的问题
额外提示:修复C#代码中的小问题
你的C#代码里InvokeSumValues的返回值写错了——C++里这个函数返回的是double,但你写成了IntPtr,这会导致运行时错误。另外别忘了添加释放实例的导入函数,避免内存泄漏:
[DllImport(@"Simple.dll", EntryPoint = "CreateInstance", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr CreateInstance(); [DllImport(@"Simple.dll", EntryPoint = "InvokeSumValues", CallingConvention = CallingConvention.Cdecl)] private static extern double InvokeSumValues(IntPtr inst, double x, double y); [DllImport(@"Simple.dll", EntryPoint = "InstanceDelete", CallingConvention = CallingConvention.Cdecl)] private static extern void InstanceDelete(IntPtr inst); private static void SumValues(double x, double y ) { IntPtr inst = CreateInstance(); double result = InvokeSumValues(inst, x, y); // 务必释放实例,防止内存泄漏 InstanceDelete(inst); }
这样修改后,你的C++项目就能正常编译生成DLL,同时保持头文件和实现代码的分离,.NET项目也能正确调用。
内容的提问来源于stack exchange,提问作者fragae
相关产品推荐
相关产品推荐

