类别:程序开发
日期:2022-09-23 浏览:2237 评论:0
最近调用动态库传数据,发现C#接收C++动态库返回字符串char*,在C#端设置对应类型为string无法接收到正确值,最后想到在C#端先用字节数组接收返回的字符串,然后再将字节数组转换为对应的字符串,数据接收终于正确
首先打开VS2012,新建项目->Visual C++,选择Win32项目,如图选择dll
新建项目的名字为dlltest,新建头文件dlltest.h,在源文件dlltest.cpp中加入如下代码:
#include "stdafx.h" #include "dlltest.h" char s[20]="您好hahaha"; int __stdcall test(char* str) { char attr[1024]; memset(attr,0,sizeof(attr)); memcpy(attr,s,sizeof(s)); memcpy(str,attr,sizeof(attr)); return 1; }
在dlltest.h中加入:
extern "C" _declspec(dllexport) int __stdcall test(char* str);
运行环境为debug模式,点击生成解决方案,在debug文件下可看到生成了dlltest.dll,这就是动态库文件。
打开VS2012,新建Visual C#控制台应用程序,命名为dlltestC
新建类文件Class1.cs,启动程序,运行空项目(debug模式),生成exe文件,打开exe所在目录,将之前生成的dll复制到该目录下,如图
然后在Class1.cs中加入如下代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.InteropServices; namespace dlltestC { public class Class1 { [DllImport("dlltest.dll", EntryPoint = "test")] public extern static int test(ref byte str); } }
最后在Program.cs中加入:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace dlltestC { public class Program { static void Main(string[] args) { byte[] s = new byte[1024]; int t = Class1.test(ref s[0]);//用字节数组接收动态库传过来的字符串 string strGet = System.Text.Encoding.Default.GetString(s, 0, s.Length); //将字节数组转换为字符串 Console.WriteLine(strGet); } } }
运行该程序,输出:您好hahaha
参考网址 :
https://blog.csdn.net/cry_smile_hate/article/details/103695020?spm=1035.2023.3001.6557&utm_medium=distribute.pc_relevant_bbs_down.none-task-blog-2defaultOPENSEARCHdefault-1.nonecase&depth_1-utm_source=distribute.pc_relevant_bbs_down.none-task-blog-2defaultOPENSEARCHdefault-1.nonecase
https://blog.csdn.net/qq_22889875/article/details/78670172
// CDLLDemo.cpp : 定义 DLL 应用程序的导出函数。 // #include "stdafx.h" #include "string.h" #include <stdio.h> #include <time.h> extern "C" __declspec(dllexport) int ParseBaliseMsg2(const unsigned char *pMsgData, char *resTgm, char *resStr) { /*CString strInfo; strcpy(resTgm, strMsg.GetBuffer()); strMsg = strFor1 + strMsg + strFor2; strInfo += "erro!!!"; strcpy(resStr, strInfo.GetBuffer());*/ //memset(resStr, 0, 50); printf("%s \r\n", pMsgData); char *a = "ParseBaliseMsg2 hello word!"; strcpy(resStr, a); printf("resStr is: %s \r\n", resStr); time_t rawtime; struct tm * timeinfo; time(&rawtime); timeinfo = localtime(&rawtime); printf("The current date/time is: %s \r\n", asctime(timeinfo)); return 120; } extern "C" __declspec(dllexport) char * ParseBaliseMsg3(const unsigned char *pMsgData, char *resTgm, int & retInt) { /*CString strInfo; strcpy(resTgm, strMsg.GetBuffer()); strMsg = strFor1 + strMsg + strFor2; strInfo += "erro!!!"; strcpy(resStr, strInfo.GetBuffer());*/ //memset(resStr, 0, 50); printf("%s \r\n", pMsgData); char *resStr = "ParseBaliseMsg3 hello word!"; printf("resStr is: %s \r\n", resStr); time_t rawtime; struct tm * timeinfo; time(&rawtime); timeinfo = localtime(&rawtime); printf("The current date/time is: %s \r\n", asctime(timeinfo)); retInt = 130; return resStr; } extern "C" __declspec(dllexport) int ParseBaliseMsg4(const unsigned char *pMsgData, char *resTgm, char *resStr) { /*CString strInfo; strcpy(resTgm, strMsg.GetBuffer()); strMsg = strFor1 + strMsg + strFor2; strInfo += "erro!!!"; strcpy(resStr, strInfo.GetBuffer());*/ //memset(resStr, 0, 50); printf("%s \r\n", pMsgData); char *a = "ParseBaliseMsg4 hello word!"; strcpy(resStr, a); printf("resStr is: %s \r\n", resStr); time_t rawtime; struct tm * timeinfo; time(&rawtime); timeinfo = localtime(&rawtime); printf("The current date/time is: %s \r\n", asctime(timeinfo)); return 140; } extern "C" __declspec(dllexport) int ParseBaliseMsg5(const unsigned char *pMsgData, char *resTgm, char *resStr) { /*CString strInfo; strcpy(resTgm, strMsg.GetBuffer()); strMsg = strFor1 + strMsg + strFor2; strInfo += "erro!!!"; strcpy(resStr, strInfo.GetBuffer());*/ //memset(resStr, 0, 50); printf("%s \r\n", pMsgData); char *a = "ParseBaliseMsg5 hello word!"; strcpy(resStr, a); printf("resStr is: %s \r\n", resStr); time_t rawtime; struct tm * timeinfo; time(&rawtime); timeinfo = localtime(&rawtime); printf("The current date/time is: %s \r\n", asctime(timeinfo)); return 150; } extern "C" __declspec(dllexport) char* strcpyTest(char* dest, char* sour) { char* temp = dest; while ('\0' != *sour) { *dest = *sour; dest++; sour++; } *dest = '\0'; return temp; }
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); } } }
发表评论 / 取消回复