C++调用C# DLL时字符串传递乱码问题求助
问题根源与解决步骤
核心问题
C#与C++的字符串确实存在本质差异:
- C#的
string是UTF-16编码的宽字符序列(对应C++的wchar_t*) - C++的
char*/std::string是ANSI编码的窄字符序列(单字节,编码取决于系统区域设置)
此外你的代码还存在函数签名不匹配、路径转义错误、调用约定不一致的问题,共同导致了乱码。
具体修复步骤
1. 修正C#的DllExport属性
明确指定字符集和调用约定,让C#导出的函数能正确识别C++传递的字符串类型:
using System.Runtime.InteropServices; using System.IO; public class YourClass { // 方案1:接受ANSI窄字符串(对应C++的const char*) [DllExport(CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static int AntiMacro([MarshalAs(UnmanagedType.LPStr)] string filepath) { Console.WriteLine(filepath); bool isFolder = false; string fullpath = ""; try { fullpath = Path.GetFullPath(filepath); Console.WriteLine(fullpath); } catch (Exception) { Console.WriteLine(fullpath); Console.WriteLine("Invalid path 1"); return 1; } // 补充你的其他逻辑 return 0; } // 方案2:接受Unicode宽字符串(对应C++的const wchar_t*,推荐) // [DllExport(CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] // public static int AntiMacro([MarshalAs(UnmanagedType.LPWStr)] string filepath) // { // // 逻辑同上 // } }
2. 修正C++代码的函数签名与字符串处理
- 不能用
std::string作为导出函数的参数(C#无法识别C++类类型),必须用C兼容的指针类型 - 修正路径字符串的转义问题(
\要写成\\,或者用C++11的原始字符串) - 确保调用约定与C#端一致(这里用
__cdecl,和C#的设置匹配)
方案1(对应C#的ANSI版本):
#include "pch.h" #include <stdio.h> #include <Windows.h> #include <string> int main() { // 修正路径转义:用双反斜杠 const char* pemodule = "C:\\Users\\source\\repos\\ClassLibrary2\\ClassLibrary2\\bin\\Debug\\ClassLibrary2.dll"; HMODULE hlib = LoadLibraryA(pemodule); if (!hlib) { printf("Failed to load DLL\n"); return 1; } // 函数签名改为接受const char*,调用约定__cdecl typedef int(__cdecl* AntiMacro)(const char* path); auto pAntiMacro = (AntiMacro)GetProcAddress(hlib, "AntiMacro"); if (!pAntiMacro) { printf("Failed to get proc address\n"); FreeLibrary(hlib); return 1; } // 修正路径转义 const char* path = "C:\\macro\\test"; int a = pAntiMacro(path); printf("%d\n", a); FreeLibrary(hlib); return 0; }
方案2(对应C#的Unicode版本,推荐,避免编码依赖):
C#端用CharSet.Unicode和LPWStr,C++代码改为:
#include "pch.h" #include <stdio.h> #include <Windows.h> #include <wchar.h> int main() { const wchar_t* pemodule = L"C:\\Users\\source\\repos\\ClassLibrary2\\ClassLibrary2\\bin\\Debug\\ClassLibrary2.dll"; HMODULE hlib = LoadLibraryW(pemodule); if (!hlib) { wprintf(L"Failed to load DLL\n"); return 1; } typedef int(__cdecl* AntiMacro)(const wchar_t* path); auto pAntiMacro = (AntiMacro)GetProcAddress(hlib, "AntiMacro"); if (!pAntiMacro) { wprintf(L"Failed to get proc address\n"); FreeLibrary(hlib); return 1; } const wchar_t* path = L"C:\\macro\\test"; int a = pAntiMacro(path); wprintf(L"%d\n", a); FreeLibrary(hlib); return 0; }
3. 额外注意事项
- 确保C# DLL编译时的平台(x86/x64)与C++程序一致,否则会加载失败
- 如果使用DllExport库,要确保版本正确,且已正确配置导出设置
- 路径中的转义字符必须处理,否则会被解析为特殊字符(比如
\t是制表符,\U是Unicode转义)
内容的提问来源于stack exchange,提问作者TomC
相关产品推荐
相关产品推荐

