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

 更新时间:2022年11月08日 08:32:25   作者:tinghe17  
C#与C++ dll之间传递字符串string wchar_t* char* IntPtr问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

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';这一行代码,也就是在字符串数组末尾添加上结束符。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • C# 设计模式系列教程-观察者模式

    C# 设计模式系列教程-观察者模式

    将一个系统分割成一个一些类相互协作的类有一个不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。观察者就是解决这类的耦合关系的。
    2016-06-06
  • C#中委托和事件的区别实例解析

    C#中委托和事件的区别实例解析

    这篇文章主要介绍了C#中委托和事件的区别,并分别以实例形式展示了通过委托执行方法与通过事件执行方法,以及相关的执行流程与原理分析,需要的朋友可以参考下
    2014-09-09
  • 解决C# winForm自定义鼠标样式的两种实现方法详解

    解决C# winForm自定义鼠标样式的两种实现方法详解

    本篇文章是对在C#中winForm自定义鼠标样式的两种实现方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C# 注册表 操作实现代码

    C# 注册表 操作实现代码

    Windows 操作系统的注册表包含了很多有关计算机运行的配置方式,打开注册表我们可以看到注册表是按类似于目录的树结构组织的
    2009-07-07
  • C#实现货币金额数字转大写汉字

    C#实现货币金额数字转大写汉字

    这篇文章主要为大家详细介绍了如何使用C#实现货币金额数字转大写汉字功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • C#开发Android百度地图手机应用程序(多地图展示)

    C#开发Android百度地图手机应用程序(多地图展示)

    这篇文章主要介绍了C#开发Android百度地图手机应用程序(多地图展示)的相关资料,需要的朋友可以参考下
    2016-02-02
  • C# 和 Python 的 hash_md5加密方法

    C# 和 Python 的 hash_md5加密方法

    这篇文章主要介绍了C# 和 Python 的 hash_md5加密方法,文章围绕着C# 和 Python 的 hash_md5加密的相关资料展开文章的详细呢偶然,需要的朋友可以参考一下,希望对你有所帮助
    2021-11-11
  • C#实现定时关机小应用

    C#实现定时关机小应用

    这篇文章主要为大家详细介绍了C#实现定时关机小应用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • C#创建安全的字典(Dictionary)存储结构

    C#创建安全的字典(Dictionary)存储结构

    本文主要对存储结构字典(Dictionary)的一些常用方法进行简单的说明,并阐述了如何创建安全的字典(Dictionary)存储结构。希望对大家有所帮助
    2016-12-12
  • C# 7.0之ref locals and returns(局部变量和引用返回)

    C# 7.0之ref locals and returns(局部变量和引用返回)

    这篇文章主要介绍了C# 7.0之ref locals and returns,即局部变量和引用返回,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-03-03

最新评论