码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2014-08-19 18:46:25      阅读:274      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   java   使用   os   io   

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

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

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

 

本文分三部分阐述:

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

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

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

 

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

 

bubuko.com,布布扣
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 {
24 return _hello;
25 }
26
27 TCHAR * __stdcall GetStringReturnW()
28 {
29 return _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 }
bubuko.com,布布扣

 

 

 

下面看C#如何调用。

 

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

 

bubuko.com,布布扣
1 [DllImport("TestDll", EntryPoint ="PrintString")]
2 publicstaticexternvoid PrintStringByBytes(byte[] hello);
3
4 [DllImport("TestDll", EntryPoint ="PrintString")]
5 publicstaticexternvoid PrintStringByMarshal([MarshalAs(UnmanagedType.LPStr)]string hello);
6
7 [DllImport("TestDll", EntryPoint ="PrintStringW")]
8 publicstaticexternvoid PrintStringByBytesW(byte[] hello);
9
10 [DllImport("TestDll", EntryPoint ="PrintStringW")]
11 publicstaticexternvoid PrintStringByMarshalW([MarshalAs(UnmanagedType.LPWStr)]string hello);
12
13
14 publicvoid 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 }
bubuko.com,布布扣

 

 

 

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

 

bubuko.com,布布扣
1 [DllImport("TestDll", EntryPoint ="GetStringReturn")]
2 publicstaticextern IntPtr GetStringReturnByBytes();
3
4 [DllImport("TestDll", EntryPoint ="GetStringReturn")]
5 [return:MarshalAs(UnmanagedType.LPStr)]
6 publicstaticexternstring GetStringReturnByMarshal();
7
8 [DllImport("TestDll", EntryPoint ="GetStringReturnW")]
9 publicstaticextern IntPtr GetStringReturnByBytesW();
10
11 [DllImport("TestDll", EntryPoint ="GetStringReturnW")]
12 [return: MarshalAs(UnmanagedType.LPWStr)]
13 publicstaticexternstring GetStringReturnByMarshalW();
14
15
16 publicvoid 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 }
bubuko.com,布布扣

 

 

 

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

 

bubuko.com,布布扣
1 [DllImport("TestDll", EntryPoint ="GetStringParam")]
2 publicstaticexternvoid GetStringParamByBytes(byte[] outHello, int len);
3
4 [DllImport("TestDll", EntryPoint ="GetStringParam")]
5 publicstaticexternvoid GetStringParamByMarshal([Out, MarshalAs(UnmanagedType.LPStr)]StringBuilder outHello, int len);
6
7 [DllImport("TestDll", EntryPoint ="GetStringParamW")]
8 publicstaticexternvoid GetStringParamByBytesW(byte[] outHello, int len);
9
10 [DllImport("TestDll", EntryPoint ="GetStringParamW")]
11 publicstaticexternvoid GetStringParamByMarshalW([Out, MarshalAs(UnmanagedType.LPWStr)]StringBuilder outHello, int len);
12
13
14 publicbyte[] _outHello =newbyte[10];
15 publicbyte[] _outHelloW =newbyte[20];
16 public StringBuilder _builder =new StringBuilder(10); //很重要设定string的容量。
17  
18 publicvoid 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 }
32  
bubuko.com,布布扣

 

 

下载:代码

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

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

标签:style   blog   http   color   java   使用   os   io   

原文地址:http://www.cnblogs.com/1971ruru/p/3922667.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!