栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

C#接收C++动态库返回字符串char*,在C#端如何接收并得到正确的字符串

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C#接收C++动态库返回字符串char*,在C#端如何接收并得到正确的字符串

  最近调用动态库传数据,发现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 
#include 
extern "C" __declspec(dllexport)
int ParseBaliseMsg2(const unsigned char *pMsgData, char *resTgm, char *resStr)
{
    
    //memset(resStr, 0, 50);
    printf("%s rn", pMsgData);
    char *a = "ParseBaliseMsg2 hello word!";
    strcpy(resStr, a);
    printf("resStr is: %s rn", resStr);
    time_t rawtime;
    struct tm * timeinfo;
    time(&rawtime);
    timeinfo = localtime(&rawtime);
    printf("The current date/time is: %s rn", asctime(timeinfo));
    return 120;
}
extern "C" __declspec(dllexport)
char * ParseBaliseMsg3(const unsigned char *pMsgData, char *resTgm, int & retInt)
{
    
    //memset(resStr, 0, 50);
    printf("%s rn", pMsgData);
    char *resStr = "ParseBaliseMsg3 hello word!";
    printf("resStr is: %s rn", resStr);
    time_t rawtime;
    struct tm * timeinfo;
    time(&rawtime);
    timeinfo = localtime(&rawtime);
    printf("The current date/time is: %s rn", asctime(timeinfo));
    retInt = 130;
    return resStr;
}
extern "C" __declspec(dllexport)
int ParseBaliseMsg4(const unsigned char *pMsgData, char *resTgm, char *resStr)
{
    
    //memset(resStr, 0, 50);
    printf("%s rn", pMsgData);
    char *a = "ParseBaliseMsg4 hello word!";
    strcpy(resStr, a);
    printf("resStr is: %s rn", resStr);
    time_t rawtime;
    struct tm * timeinfo;
    time(&rawtime);
    timeinfo = localtime(&rawtime);
    printf("The current date/time is: %s rn", asctime(timeinfo));
    return 140;
}
extern "C" __declspec(dllexport)
int ParseBaliseMsg5(const unsigned char *pMsgData, char *resTgm, char *resStr)
{
    
    //memset(resStr, 0, 50);
    printf("%s rn", pMsgData);
    char *a = "ParseBaliseMsg5 hello word!";
    strcpy(resStr, a);
    printf("resStr is: %s rn", resStr);
    time_t rawtime;
    struct tm * timeinfo;
    time(&rawtime);
    timeinfo = localtime(&rawtime);
    printf("The current date/time is: %s rn", asctime(timeinfo));
    return 150;
}
extern "C" __declspec(dllexport)
char* strcpyTest(char* dest, char* sour)
{
    char* temp = dest;
    while ('' != *sour)
    {
        *dest = *sour;
        dest++;
        sour++;
    }
    *dest = '';
    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)]
        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);
        }
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1023231.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号