C# 调用C++ dll 返回char*调用方式(StringBuilder乱码)
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace DotNet_Use_C_Demo { public class TestCMethodHelper { [DllImport("CDLLDemo.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] private static extern int ParseBaliseMsg2(string msg, string rmsg, ref byte memory); [DllImport("CDLLDemo.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] private static extern IntPtr ParseBaliseMsg3(string msg, string rmsg, ref int rInt); [DllImport("CDLLDemo.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] private static extern IntPtr ParseBaliseMsg4(string msg, string rmsg, [MarshalAs(UnmanagedType.LPStr)]StringBuilder t); [DllImport("CDLLDemo.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] private static extern IntPtr ParseBaliseMsg5([MarshalAs(UnmanagedType.LPStr)]StringBuilder msg, string rmsg, [MarshalAs(UnmanagedType.LPStr)]StringBuilder t); [DllImport("CDLLDemo.dll", EntryPoint = "strcpyTest", CallingConvention = CallingConvention.Cdecl/*, CallingConvention = CallingConvention.Cdecl*/)] public static extern IntPtr strcpyTest(ref byte destA, string sourA); public static void TestMethod() { Byte[] bPara = new Byte[100]; //新建字节数组 var r2 = ParseBaliseMsg2("abcd", "", ref bPara[0]); string strGet = System.Text.Encoding.Default.GetString(bPara, 0, bPara.Length); //将字节数组转换为字符串 Console.WriteLine("返回值:" + r2); Console.WriteLine("传出值:" + strGet); Console.WriteLine("***************************************************"); int retResult = 0; IntPtr pRet = ParseBaliseMsg3("1234", "", ref retResult); string strRet = Marshal.PtrToStringAnsi(pRet); Console.WriteLine("返回值:" + strRet); Console.WriteLine("传出值:" + retResult); Console.WriteLine("***************************************************"); //StringBuilder方式 StringBuilder sb = new StringBuilder(); var r4 = ParseBaliseMsg4("abcd", "", sb); Console.WriteLine("返回值:" + r4); Console.WriteLine("传出值:" + sb.ToString()); Console.WriteLine("***************************************************"); StringBuilder sb5 = new StringBuilder(); StringBuilder sb5E_para = new StringBuilder(); sb5E_para.Append("abcdedf123456"); var r5 = ParseBaliseMsg5(sb5E_para, "", sb5); Console.WriteLine("返回值:" + r5); Console.WriteLine("传出值:" + sb5.ToString()); } public static void CpyTest() { string strSour = "测试调用C++ dll"; Byte[] bPara = new Byte[100]; //新建字节数组 IntPtr pRet = strcpyTest(ref bPara[0], strSour); string strGet = System.Text.Encoding.Default.GetString(bPara, 0, bPara.Length); //将字节数组转换为字符串 string strRet = Marshal.PtrToStringAnsi(pRet); Console.WriteLine("源字符串:"); Console.WriteLine(strSour); Console.WriteLine("传出值:"); Console.WriteLine(strGet); Console.WriteLine("返回值:"); Console.WriteLine(strRet); } } }
1.用StringBuilder接收Char*参数 需要定义为[MarshalAs(UnmanagedType.LPStr)]StringBuilder,否则就是乱码。
2.用ref byte memory接收Char*参数 不能使用ref IntPtr方式接收,否则返回值一直为空。
3.使用返回值Char* 直接使用IntPtr方式接收即可。