C#与C++ dll之间传递字符串string wchar_t* char* IntPtr问题

作者:tinghe17 时间:2022-09-16 09:34:53 

C#与C++ dll之间传递字符串string wchar_t* char* IntPtr

1、由C#向C++ dll 传入字符串时,参数直接用string,设置编码格式 CharSet.Unicode CharSet.Ansi。

C++ dll接收使用wchar_t* 或 char*。

2、由C++ dll返回字符串,使用 wchar_t 或char*。

  • .net 4.0 C#可以直接使用string接收,很方便。

  • .net 4.0+ C# 用 IntPtr 接收,使用string接收调试不行。

dll代码如下:

extern "C" _declspec(dllexport)const wchar_t* Diagnoser(wchar_t* inputText)
{
    delete diagnoser;
    diagnoser = new FireEye::Diagnoser();
    diagnoser->diagnose(inputText);
    diagnoser->report();
    return diagnoser->reportText.c_str();
}

C#代码如下:

//声明
[DllImport("FireEyeDll.dll", CharSet = CharSet.Unicode , CallingConvention = CallingConvention.Cdecl)]
//public static extern string Diagnoser(string inputText); //.net 4.0
public static extern IntPtr Diagnoser(string inputText);
 
 
 
//调用
//outputBox.Text = Diagnoser(inputBox.Text); //.net 4.0
IntPtr outPtr = Diagnoser(inputBox.Text);
outputBox.Text = Marshal.PtrToStringUni(outPtr);

C#调用C++ DLL的步骤以及遇到的乱码等问题

C++ DLL动态库Lib_LR.dll

函数声明:

DLL_API_LR void GetAuthInfo(char* strCode);

函数定义:

两个入参,两个出参

void GetAuthInfo(int inPrama1, char *inParam2, int outParam1, char *outParam2)
{
    char buff[2048];
    memset(buff, 0, 2048);
    std::ifstream inFile("license.lr", std::ios::binary);
    if (inFile.fail())
    {
        return;
    }
    else
    {
        inFile.read(buff, sizeof(temp));
        inFile.close();
    }
    memcpy(outParam2, buff, outParam2.length());
    string strCode=outParam2;
    outParam1=strCode.length();
}

C#调用流程

函数引用:

[DllImport("Lib_LR.dll", EntryPoint = "GetAuthInfo", CallingConvention = CallingConvention.Cdecl)]
public static extern void GetAuthInfo(ref int InParam1, string nInPrama2, StringBuilder strCode);

函数调用:

int inParam1=0;
int outParam1=0;
string inParam2="测试";
StringBuilder outParam2= new StringBuilder(1024);
//注意:调用函数的时候,int型的出口参数要加ref,出口字符串参数要声明StringBuilder类型
GetAuthInfo(inParam1,inParam2,ref outParam1,outParam2);

遇到的问题

1、平台不匹配:

C#工程是基于.net core的webapi项目,默认编译平台选择的是Any CPU,而C++ DLL工程默认的平台是x86,这就产生了调用方(C#工程)和被调用方(DLL)编译平台不匹配的问题。可以尝试通过以下方法来解决:C++ DLL和C#工程编译的时候都选择x86或者x64(前提操作系统是64位才行)。

2、乱码问题:

调用GetAuthInfo函数的时候,获取到的strCode出现乱码,网上给出的解决方法是改变函数参数声明方式public static extern voidGetAuthInfo([MarshalAs(UnmanagedType.LPStr)] StringBuilder strCode)。但是这种方法我试了,没有效果。最后通过修改DLL源码的方式得到解决:在GetAuthInfo函数的最后加上outParam2[strCode.length()] = '\0';这一行代码,也就是在字符串数组末尾添加上结束符。

来源:https://blog.csdn.net/tinghe17/article/details/114381046tinghe17

标签:C#,C++,dll,传递,字符串
0
投稿

猜你喜欢

  • Java jar打包工具使用方法步骤解析

    2023-07-01 12:26:47
  • 10k+点赞的 SpringBoot 后台管理系统教程详解

    2021-08-11 14:39:44
  • C# FTP操作类分享

    2022-05-11 22:03:49
  • dialog dismiss时键盘不消失的问题浅析及解决办法

    2021-09-18 10:06:30
  • spring cloud Ribbon用法及原理解析

    2021-11-28 15:27:21
  • 本地jvm执行flink程序带web ui的操作

    2022-09-03 20:49:00
  • 详解SpringBoot通用配置文件(不定时更新)

    2022-12-01 09:07:04
  • Redis集群原理详细分析

    2021-08-06 07:34:00
  • Android仿抖音列表效果

    2022-03-01 16:36:50
  • Windows下Java环境变量配置详解

    2022-02-04 05:56:02
  • logback之自定义指定日志文件存储目录方式

    2022-05-11 15:05:19
  • Java 实现repalceAll只替换第二个匹配到的字符串

    2021-06-12 11:56:20
  • Android GestureDetector实现手势滑动效果

    2023-10-01 04:37:50
  • Java IO之流的分类详解

    2022-08-14 02:18:41
  • Springboot实现高吞吐量异步处理详解(适用于高并发场景)

    2023-08-20 23:40:35
  • Android结束进程的方法详解

    2023-06-09 20:27:30
  • java中staticclass静态类详解

    2021-10-12 19:47:35
  • 详解Spring中bean的几种注入方式

    2023-02-12 20:25:07
  • mybatis中<choose>标签的用法说明

    2023-07-22 19:37:27
  • Java详细讲解堆排序与时间复杂度的概念

    2023-10-20 02:00:11
  • asp之家 软件编程 m.aspxhome.com