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


猜你喜欢
- 本文实例讲述了Spring Bean的初始化和销毁。分享给大家供大家参考,具体如下:一 点睛在开发过程中,经常遇到在Bean使用之前或者之后
- float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用 java.math.BigDecimal。而且使用BigDe
- 跨域问题,其实百度上面有一堆的解决方案针对普通的情况其实百度上面的方案都是可行的。我这里主要介绍2种情况。当然我这里的配置都是基于网关的,而
- 遇到的问题解决方法win7:insert键切回win10:fn+insert切回Mac:fn+i 切回来源:https://blog.csd
- 使用filter对response内容进行加密编写加密类(AES)/** * aes加密解密 */public class AesEncry
- 结果映射ResultMap引入resultMap–MyBatis中最强大的元素数据库字段名::实体类字段名:public
- 写在开头java.util.Collection 作为Java开发最常用的接口之一,我们经常使用,今天我带大家一起研究一下Collectio
- 本文实例为大家分享了Android实现可复用的选择页面的具体代码,供大家参考,具体内容如下窗口代码/** * 根据上一个页面传过来的isMu
- 1.为什么要用thrift js C#? 1.1 首先,js 通过 thrift 访问C#,实际上是一种
- 简介反射是Java编程语言中的一个特性。它允许执行的Java程序检查或 操作 自身,并操作程序的内部属性。例如,Java类可以获取其所有成员
- 项目效果实现代码using System;namespace 飞行棋项目{ class Program
- mybatis-plus实现in嵌套sql今天使用jeegboot看源码时发现用户权限部分的代码条件查询的inSql方法的用法:即sql中的
- 1、存储在App内部最简单的一种。在尝试过程中发现,手机中很多文件夹都没有权限读写。我们可以将我们需要写的文件存放到App中的files文件
- 基于SMTP发送一个简单的邮件首先,需要一个认证器:package No001_基于SMTP的文本邮件;import javax.mail.
- 目录Retrofit介绍Retrofit优点Retrofit的使用1.引入依赖项2.添加网络权限3.编写Retrofit辅助类4.定义Api
- 一、this关键字的作用this关键字除了可以强调本类中的方法还具有以下作用。1.表示类中的属性2.可以使用关键字调用本类中的构造方法3.t
- 一:需求当小数位很多的时候,小数位后面可能有一些多余的0并没有任何实际意义。所以在某些业务需求下可以去掉这些多余的0。例如:0.2000可以
- SpringBoot2之PUT请求接收不了参数的解决办法,这个问题,关乎两个Filter过滤器,是spring3和3.5之后提供的,目的就是
- public string check_number(string num_str)
- @Autowired注解在抽象类中失效最近在工作中遇到这个问题,在抽象类中使用Autowired这个注解,注入mybatis的dao时,总是