C# C++ 字符串传递

标签: c#c++bytestring测试c

2012-06-14 17:425707人阅读评论(3)收藏举报

分类:

C#(11)  作者同类文章X

C++(112)  作者同类文章X

可以说新手使用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++ 字符串传递的更多相关文章

  1. JNI 中文字符串传递(转)

    源:JNI 中文字符串传递 因为项目编码中通过JNI传递中文字符时出现乱码问题,特搜集了相关资料,整理如下: java内部是使用16bit的unicode编码(UTF-16)来表示字符串的,无论中文英 ...

  2. 33深入理解C指针之---通过字符串传递数据

    一.传递字符串:在函数的参数列表中,将参数声明为char指针即可实现通过字符串传递参数 1.特征: 1).字符串以char指针的形式传递,一般是const指针传递: 2).使用字符数组声明字符串,调用 ...

  3. C++调用Go方法的字符串传递问题及解决方案

    摘要:C++调用Go方法时,字符串参数的内存管理需要由Go侧进行深度值拷贝. 现象 在一个APP技术项目中,子进程按请求加载Go的ServiceModule,将需要拉起的ServiceModule信息 ...

  4. 使用JQuery将前端form表单数据转换为JSON字符串传递到后台处理

    一般地,我们在处理表单(form表单哦)数据时,传输对象或字符串到后台,Spring MVC或SpringBoot的Controller接收时使用一个对象作为参数就可以被正常接收并封装到对象中.这种方 ...

  5. JavaScript拼接字符串传递多个参数

    var ftOpreat = function (value,rows){ var v = rows.Version; var preview = "<a href=\"#\ ...

  6. js奇葩错误 字符串传递问题

    第一种方式function hello(){    var name="he";    var content="<input type=button value= ...

  7. p/invoke 碎片-- 对字符串的处理

    字符串在内存中的的几种风格 字符串作为参数和返回值 参考 字符串在内存中的几种风格 所谓的风格,也就是字符串在内存中的存在形式.如何存放的,占据内存的大小,还有存放顺序等.在不同的编程语言和不同的平台 ...

  8. android第一行代码-3.activity之间的调用跟数据传递

    前面两节所有应用都是同一个activity中的,是时候讲activity之间交互的操作了,此后会涉及到intent这个概念,这也算一个新的里程碑开始. 主要内容包括intent的使用,以及activi ...

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

    可以说新手使用P-INVOKE最开始的头疼就是C#和C++的字符串传递,因为这里涉及到两个问题. 第一:C#的string和C++的字符串首指针如何对应. 第二:字符串还有ANSI和UNICODE(宽 ...

随机推荐

  1. 安装oracle常见问题分析

    1,之前已经安装过软件,卸载不完全 /tmp/.oracle /tmp/ora* /var/tmp/ora* /etc/ora* 2,安装介质权限或者本身就有问题 3,oracle用户 $/HOME/ ...

  2. JSP页面的静态包含和动态包含的区别与联系

    JSP中有两种包含: 静态包含:<%@include file="被包含页面"%> 动态包含:<jsp:include page="被包含页面" ...

  3. 【2017 Multi-University Training Contest - Team 1 1002】Balala Power!

    [Link]:http://acm.hdu.edu.cn/showproblem.php?pid=6034 [Description] 给你n个字符串; 每个字符串都仅由小写字母组成; 然后,你可以把 ...

  4. CCF模拟题 最优配餐

    最优配餐 时间限制: 1.0s 内存限制: 256.0MB   问题描述 栋栋最近开了一家餐饮连锁店,提供外卖服务.随着连锁店越来越多,怎么合理的给客户送餐成为了一个急需解决的问题. 栋栋的连锁店所在 ...

  5. github连接报"ssh: connect to host github.com port 22: Connection timed out"错误

    1. 异常 在连接github时,执行"ssh -T git@github.com" 命令时,出现 ssh: connect to host github.com port 22: ...

  6. 免费css布局和模板集合

    Internet 上有很多基于 (X)HTML/CSS 标记的模板.如果你是一个 Web 开发人员,你不希望把时间一次又一次地浪费在重复代码设计上面,这里提供了一个列表,提供了基于 CSS 的免费模板 ...

  7. 使用cocos2dx 3.2和cocosstudio屏幕适配总结----相对布局

    屏幕适配的文章太多了,基本上都是理论性的东西.大家明确了机制就知道了.没有完美的适配方案,除非你们的美工愿意折腾. 常规策略: 今天研究了一下屏幕适配导致的缩放和展示不全的问题(黑边的方案直接淘汰). ...

  8. RISC-V指令集的诞生,"V"也表示变化(variation)和向量(vectors)

    RISC-V登场,Intel和ARM会怕吗? 张竞扬 摩尔精英 摩尔精英.创始人兼CEO 82 人赞了该文章 在2015年12月的Nature网站上,由U.C. Berkeley等几个大学的研究人员主 ...

  9. vue1

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. html ---- a 标签 在新窗口打开的问题