zoukankan      html  css  js  c++  java
  • C# 调用C++ dll 返回char*调用方式(StringBuilder乱码)

    // 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 
    ", pMsgData);
        char *a = "ParseBaliseMsg2 hello word!";
        strcpy(resStr, a);
        printf("resStr is: %s 
    ", resStr);
    
        time_t rawtime;
        struct tm * timeinfo;
        time(&rawtime);
        timeinfo = localtime(&rawtime);
        printf("The current date/time is: %s 
    ", 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 
    ", pMsgData);
        char *resStr = "ParseBaliseMsg3 hello word!";
        printf("resStr is: %s 
    ", resStr);
    
        time_t rawtime;
        struct tm * timeinfo;
        time(&rawtime);
        timeinfo = localtime(&rawtime);
        printf("The current date/time is: %s 
    ", 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 
    ", pMsgData);
        char *a = "ParseBaliseMsg4 hello word!";
        strcpy(resStr, a);
        printf("resStr is: %s 
    ", resStr);
    
        time_t rawtime;
        struct tm * timeinfo;
        time(&rawtime);
        timeinfo = localtime(&rawtime);
        printf("The current date/time is: %s 
    ", 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 
    ", pMsgData);
        char *a = "ParseBaliseMsg5 hello word!";
        strcpy(resStr, a);
        printf("resStr is: %s 
    ", resStr);
    
        time_t rawtime;
        struct tm * timeinfo;
        time(&rawtime);
        timeinfo = localtime(&rawtime);
        printf("The current date/time is: %s 
    ", 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/*, 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方式接收即可。

    由于博客园一次只让上传10M大小的文件,vs2015新建的C++项目70M大小,压缩后也达到20M,无法上传C++代码。

    C++项目创建方式:

    _CRT_SECURE_NO_WARNINGS 输入这个,否则编译不过。!!!

    运行文件点击这里下载。

  • 相关阅读:
    英国下院通过法案允许合成人兽胚胎
    老外关于思考时间的问与答
    性能测试中用LambdaProbe监控Tomcat
    BT下载原理
    汽车维修行业呼吁大学生加入修车行列
    一个女研究生(高级测试工程师)的职业选择
    微软称20日验证Windows与Office 盗版将黑屏 网友评论
    Xbox摇身变NAS:BT的使用问题与性能测试
    李开复建言大学生:求职中不要把钱看得太重
    IBM雇员将罢工15分钟 为抗议公司裁员
  • 原文地址:https://www.cnblogs.com/ligl/p/9952849.html
Copyright © 2011-2022 走看看