C# C++ 字符串传递

C++程序:将字符串传递给函数 综上所述,我们可以通过值传递或引用传递的方式将字符串传递给函数。如果我们希望在函数内部修改字符串并影响到原始字符串,可以使用引用传递。在本篇文章中,我将详细介绍如何将字符串传递给函数,并提供相应的源代码示例。在C++中,字符串可以通过值传递或引用传递的方式传递给函数。在函数内部,我们将字符串与另一个字符串拼接,并输出结果。可以看到,尽管函数内部修改了字符串,但原始字符串并没有受到影响。在函数内部,我们修改了字符串的内容,并输出结果。可以看到,函数内部对字符串的修改直接影响到了原始字符串。 阅读详情

可以说新手使用P-INVOKE最开始的头疼就是C#和C++的字符串传递,因为这里涉及到两个问题。

第一:C#的string和C++的字符串首指针如何对应。

第二:字符串还有ANSI和UNICODE(宽字符串)之分。

 

本文分三部分阐述:

第一:字符串指针当输入参数,

第二:字符串指针作为返回值,

第三:字符串指针作为输入输出参数。

 

C++部分的测试代码很简单这里就全部贴出来了:

 

1#include "stdafx.h"
2#include "TestDll.h"
3#include <stdio.h>
4#include <string.h>
5#include <tchar.h>
6
7
8 staticchar* _hello ="Hello,World!!";
9 static TCHAR * _helloW = TEXT("Hello,World!!");
10
11 void __stdcall PrintString(char* hello)
12{
13 printf("%s\n",hello);
14}
15
16 void __stdcall PrintStringW(TCHAR * hello)
17{
18 _tprintf(TEXT("%s\n"),hello);
19}
20
21
22 char* __stdcall GetStringReturn()
23{
24return _hello;
25}
26
27TCHAR * __stdcall GetStringReturnW()
28{
29return _helloW;
30}
31
32
33 void __stdcall GetStringParam(char* outHello,int len)
34{ //output "aaaaaaaa"
35 for(int i=0; i< len -1 ;i++) outHello[i] ='a';
36 outHello[len -1] ='\0';
37}
38
39 void __stdcall GetStringParamW(TCHAR * outHello,int len)
40{ //output "aaaaaaaa" unicode version.
41 for(int i=0; i< len -1 ;i++) outHello[i] = TEXT('a');
42 outHello[len -1] = TEXT('\0');
43}

 

 

 

下面看C#如何调用。

 

第一:字符串指针作为输入参数,可以使用byte[] 和MarshalAs来解决。(注意四个P-INVOKE,两个ANSI版本,和两个UNICODE版本),推荐使用MarshalAs方法简单明了。

 

1 [DllImport("TestDll", EntryPoint ="PrintString")]
2publicstaticexternvoid PrintStringByBytes(byte[] hello);
3
4 [DllImport("TestDll", EntryPoint ="PrintString")]
5publicstaticexternvoid PrintStringByMarshal([MarshalAs(UnmanagedType.LPStr)]string hello);
6
7 [DllImport("TestDll", EntryPoint ="PrintStringW")]
8publicstaticexternvoid PrintStringByBytesW(byte[] hello);
9
10 [DllImport("TestDll", EntryPoint ="PrintStringW")]
11publicstaticexternvoid PrintStringByMarshalW([MarshalAs(UnmanagedType.LPWStr)]string hello);
12
13
14publicvoid Run()
15 {
16 PrintStringByBytes(Encoding.ASCII.GetBytes("use byte[]"));
17 PrintStringByMarshal("use MarshalAs");
18 PrintStringByBytesW(Encoding.Unicode.GetBytes("use byte[]"));
19 PrintStringByMarshalW("use MarshalAs");
20}

 

 

 

第二:字符串指针作为返回值,和上面一样也有两种声明方法,同样也包含两个版本。注意:Marshal.PtrToStringAnsi()函数的使用,把字符串指针转变为C#的string.推荐使用MarshalAs方法简单明了。

 

1 [DllImport("TestDll", EntryPoint ="GetStringReturn")]
2publicstaticextern IntPtr GetStringReturnByBytes();
3
4 [DllImport("TestDll", EntryPoint ="GetStringReturn")]
5 [return:MarshalAs(UnmanagedType.LPStr)]
6publicstaticexternstring GetStringReturnByMarshal();
7
8 [DllImport("TestDll", EntryPoint ="GetStringReturnW")]
9publicstaticextern IntPtr GetStringReturnByBytesW();
10
11 [DllImport("TestDll", EntryPoint ="GetStringReturnW")]
12 [return: MarshalAs(UnmanagedType.LPWStr)]
13publicstaticexternstring GetStringReturnByMarshalW();
14
15
16publicvoid Run()
17 { //Marshal.PtrToStringAuto(GetStringReturnByBytes()); 自动判断类型不错。
18  Console.WriteLine(Marshal.PtrToStringAnsi(GetStringReturnByBytes()));
19 Console.WriteLine(GetStringReturnByMarshal());
20 Console.WriteLine(Marshal.PtrToStringUni(GetStringReturnByBytesW()));
21 Console.WriteLine(GetStringReturnByMarshalW());
22}

 

 

 

第三:字符串指针作为输入输出参数时,因为要求有固定的容量,所以这里使用的是StringBuilder,大家仔细看了,当然也有byte[]版本。这个看大家喜欢那个版本就是用那个.

 

1 [DllImport("TestDll", EntryPoint ="GetStringParam")]
2publicstaticexternvoid GetStringParamByBytes(byte[] outHello, int len);
3
4 [DllImport("TestDll", EntryPoint ="GetStringParam")]
5publicstaticexternvoid GetStringParamByMarshal([Out, MarshalAs(UnmanagedType.LPStr)]StringBuilder outHello, int len);
6
7 [DllImport("TestDll", EntryPoint ="GetStringParamW")]
8publicstaticexternvoid GetStringParamByBytesW(byte[] outHello, int len);
9
10 [DllImport("TestDll", EntryPoint ="GetStringParamW")]
11publicstaticexternvoid GetStringParamByMarshalW([Out, MarshalAs(UnmanagedType.LPWStr)]StringBuilder outHello, int len);
12
13
14publicbyte[] _outHello =newbyte[10];
15publicbyte[] _outHelloW =newbyte[20];
16public StringBuilder _builder =new StringBuilder(10); //很重要设定string的容量。
17 
18publicvoid Run()
19 {
20//
21  GetStringParamByBytes(_outHello, _outHello.Length);
22 GetStringParamByMarshal(_builder, _builder.Capacity);
23 GetStringParamByBytesW(_outHelloW, _outHelloW.Length /2);
24 GetStringParamByMarshalW(_builder, _builder.Capacity);
25
26//
27  Console.WriteLine(Encoding.ASCII.GetString(_outHello));
28 Console.WriteLine(_builder.ToString());
29 Console.WriteLine(Encoding.Unicode.GetString(_outHelloW));
30 Console.WriteLine(_builder.ToString());
31}
C#与C++之间传递字符串的方法——string、wchar_t*、char*、IntPtr 在上述示例中,C++的DLL代码定义了一个名为DisplayString的函数,该函数接收一个wchar_t*类型的字符串,并打印出来。然后,使用Marshal类的相关方法将字节数组拷贝到分配的内存中,并添加字符串结尾的’\0’。通过上述示例,我们介绍了在C#与C++之间传递字符串的几种常用方法,分别使用了string、wchar_t*、char*和IntPtr类型。而在C#代码中,我们首先将string类型的字符串转换为字节数组,然后将字节数组的指针传递给DisplayString函数。 阅读详情

相关推荐

C++与C#字符串数据传递机制详解

P/Invoke(Platform Invocation Services)是C#访问本地C/C++动态链接库(DLL)的核心机制。它允许托管代码调用非托管函数,但在此过程中,数据类型特别是字符串的传递必须经过严格的类型映射和内存管理协调。在C++侧,字符串通常以或可修改的缓冲区形式存在;而在C#中,string是不可变的引用类型,存储于托管堆,并由CLR自动管理生命周期。因此,在跨边界调用时,CLR会通过封送处理(marshaling)将托管字符串转换为非托管格式,反之亦然。

weixin_32098457的博客 383

c#编程指南(十) 平台调用P-INVOKE完全掌握, 字符串和指针

可以说新手使用P-INVOKE最开始的头疼就是C#和C++的字符串传递,因为这里涉及到两个问题。 第一:C#的string和C++的字符串首指针如何对应。 第二:字符串还有ANSI和UNICODE(宽字符串)之分。 本文分三部分阐述: 第一:字符串指针当输入参数, 第二:字符串指针作为返回值, 第三:字符串指针作为输入输出参数。 C++部分的测试代码很简单这里就全部贴出来...

weixin_30436101的博客 563

03 C#与C++dll互相传递字符串.rar

附件是一套C#调用C++dll时,相互传递字符串的Demo。亲测可用。

c++ 与c#之间的字符串传递

1.方法中不要直接返回字符串,防止内存崩溃。 c++写法: void necall(char* str1, char* outdata) { strcpy(outdata, str1); } outdata 为导出数 c#写法: [DllImport("testdemo")] private static extern void necall(string ...

GTOFEI013的博客 4202

Arcgis 10.3 与 ArcGIS Engine 10.3 安装与破解

Arcgis 10.3 与 ArcGIS Engine 10.3 安装与破解

weixin_52127098的博客 4726

《斯图尔特微积分》实战指南:从理论到解题技巧的跨越

本文深入解析《斯图尔特微积分》教材的独特价值与实用学习策略,重点介绍其理论深度与实际应用的完美平衡。通过概念理解、符号语言转换、解题思维框架等五个关键跨越,帮助读者高效掌握微积分核心技巧。文章还提供分层练习、可视化工具等教学实践方法,是提升微积分学习效率的实战指南。

weixin_28432777的博客 396

C#与C++交互开发系列(九):字符串传递的几种形式

在C#与C++交互开发中,字符串的传递是非常常见的需求。字符串作为数据类型在托管代码(C#)和非托管代码(C++)之间的传递存在一些特殊的挑战,因为两者的字符串内存管理和编码方式不同。本篇博客将详细介绍几种常见的字符串传递方式,讨论字符串作为参数传递和作为响应结果返回的不同情况,并给出相关代码示例。在C#与C++的交互开发中,字符串的传递是一项常见但需要特别关注的任务。

dotnet研习社 2962

FastAPI + LLM 实战:5分钟搞定本地模型API服务部署(含避坑指南)

本文详细介绍了如何使用FastAPI和LLM(大语言模型)快速部署本地API服务,涵盖环境准备、模型集成、性能优化及避坑指南。通过实战示例,帮助开发者在5分钟内完成从零到生产的部署过程,提升AI应用开发效率。

weixin_29062963的博客 105

C++和C#混合编程,C#调用C++生成的dll以及字符串传递

使用VS2017把C++项目打包成dll,并暴露函数。 1、创建下图类型的项目 默认生成的是这样的,我们在Dll3.cpp中写函数就行。 2、创建、或者从外部引入C++文件。 注意:要在每个cpp文件的头部都加上 #include “stdafx.h”,而且一定要在首行。不然会报错。 注意:若想要以c语言封装,图中标记的一定要存在。这里还是都加上吧。 由于这里使用了strdup,所以生成dll时会报4996错误。 参考 https://blog.youkuaiyun.com/heimabuhei/article

Ripo_za的博客 5860

FPGA新手必看:Quartus生成jic文件全流程详解(附AS/JTAG模式选择指南)

本文详细解析了在Quartus中生成JIC文件以固化FPGA程序到Flash的全流程。核心在于理解JIC文件作为连接JTAG调试与AS固化的桥梁作用,并重点阐述了Convert Programming Files工具的关键配置步骤、AS与JTAG模式的选择逻辑,以及烧录过程中的常见问题排查指南,帮助开发者实现程序断电不丢失。

weixin_29271053的博客 275

告别黑盒:深入解析西部数据UFS芯片的44个SMART健康参数(附高通XBL读取源码)

本文深入解析西部数据UFS芯片的44个SMART健康参数,结合高通XBL启动加载层源码,提供了一套完整的健康状态诊断方法论。从SCSI命令层封装到数据结构映射,详细介绍了如何在高通平台早期启动阶段捕获UFS健康状态,帮助工程师实现预测性维护。

weixin_30600197的博客 427

c#中传递字符串数组给C++

需要注意的是,如果传递的字符串中包含中文,则需要使用CharSet = CharSet.Unicode,并在C++端使用wchar_t**接收。

weixin_43786608的博客 1083

后摄模块辐射超标整改

某行车记录仪在EMI测试中出现辐射超标问题,通过模块剥离法定位到后摄模块的Ethernet数据线为噪声源。深入检查发现TYPE-C延长线屏蔽层未有效接地,形成辐射泄漏通道。整改措施包括加强屏蔽层360°接地、使用导电布改善连接处屏蔽等,最终使辐射降至EN55032 Class B限值以内。案例揭示了高速信号延长线中屏蔽连续性的重要性,建议设计阶段就重视连接器屏蔽设计和共模干扰抑制。

硬核科技 256

c# 调用c++ dll,传递 string 路径给c++ 之二 宽字节字符串

写dll的c++中,如果用void setFileName(char* pFileName)接收字符串,则对第一个字符的第二个字节判断为结束符,导致只能传递一个字符。 改为用wchar_t* 接收,然后转换为string类型 在.cpp文件中 #include void setFileName(wchar_t* content) { int pSize = WideCharToMultiByte(CP_OEMCP, 0, content, wcslen(content), NULL, 0, NULL, N

blue_xinran的博客 1818

基于 Simulink 的三相四线制整流器在三相不平衡负载下的中点电位平衡控制实战教程。

本文介绍了三相四线制整流器在不平衡负载下的中点电位平衡控制方法。首先分析了中点电位漂移的物理机理和控制策略(零序电压注入)。接着详细讲解了Simulink建模步骤:搭建三相四线制主电路、设计平衡控制算法、实现PWM调制。通过对比有无平衡控制的仿真结果,验证了控制方法的有效性。最后提供了工程建议:零序注入需限幅、考虑中性线寄生电感影响、采用稳健的PI参数。该方案能有效抑制中点电位波动,保障三电平系统在不平衡工况下的稳定运行。

MHD0815的博客 60

YOLOv11目标检测模型性能评价指标详解,涉及混淆矩阵、F1-Score、IoU、mAP、参数量、计算量等,一文打尽所有评价指标

本文主要讲解的是计算机视觉网络模型的性能评价指标,这是每一篇论文中都需要展示的内容。熟悉每一个评价指标也能够帮助我们在训练和改进模型过程中,更好的观察模型的变化效果。

Limiiiing的博客 8413

c++传递字符串给c#使用问题

C++里,字符串要占用内存的。C++创建字符串,并传给C#,就会造成内存泄露(因为C#不知道C++如何创建,也就不知道如何销毁)。 因此,通常的做法(甚至是C++互相调用的惯例),是 调用者(这里是C#)准备好一段内存缓冲区(这里是StringBuilder); 被调用者C++把字符串内容,填充到指定缓冲区去; 调用者从缓冲区能得到结果,也知道如何清理缓冲(C#自己会用垃圾回收),没有内存泄露问...

gsl111000的博客 981

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

java向c++传递字符串数组 com,将字符串数组从C#传递到C++ dll,然后再返回

我查看了googleverse和堆栈溢出,并且看到了几个类似的问题,但没有找到我找到的答案。我是一名新成员,因此我不允许在别人的问题中对答案发表评论以要求澄清,所以我不得不求助于自己的问题。将字符串数组从C#传递到C++ dll,然后再返回好吧,所以我想从C#应用程序传递一个字符串数组到C++ DLL,然后在另一个C#应用程序中获取这些信息。我相信我正确传递给C++,但是我无法从dll中获得正确的...

weixin_28695537的博客 417

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

C#调用C++动态库传递字符串

嗯,我是菜鸟,记录一下成功的方法: C#是托管代码:赋值一个字符串: string tt = "水果bigbig.png"; byte[] ss = System.Text.Encoding.Default.GetBytes(tt); vtkDLLUse.Invoke.SavePicture(ss, ss.Length); 传递给C++时,用指针即可: void SavePicture(char* i_Path, int Length); ...

一堆土的博客 1427

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

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

1、由C#向C++ dll 传入字符串时,参数直接用string,设置编码格式 CharSet.UnicodeCharSet.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)...

7830

c#与c++的字符串传递

在c#中调用dll时,使用参数接收字符串数据。

weixin_46420972的博客 1190

java向c++传递字符串数组 com,C#:将字符串数组传递给c++ dll / dylib

我无法从我的c#代码传递一个字符串数组到我的c ++ dylib函数。C#代码:[DllImport("array2d.dylib", EntryPoint = "process_array", CallingConvention = CallingConvention.Cdecl)]public static extern int process_array(String[] a, int b)...

weixin_31693025的博客 230

C++向C#传递字符串

方法一: headfile: #pragma once extern "C" __declspec(dllexport) char* SayHelloWorld(); cpp file char* SayHelloWorld(){ return "hello world"; } C# file [DllImport("persimmon_dll")] public static ...

junex的博客 3300

C#传递字符串给C++不能用ref限定

场景 //DLL中申明 extern “C” __declspec(dllexport) int WINAPI Test(charastr2,charbstr2) { //改变astr2 bstr 2 ,astr1 bstr1不会被改变 return a+b; } DLL 需传入char *类型 [DllImport(“MyDLL.dll"...

weixin_33950035的博客 565
上一篇: 经典线程同步总结 关键段 事件 互斥量 信号量
下一篇: 6款免费的C++图形和游戏库
雪岢奇
博客等级 码龄17年 310粉丝 60原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值