1
#include
"
stdafx.h
"
2
#include
"
TestDll.h
"
3
#include
<
stdio.h
>
4
#include
<
string
.h
>
5
#include
<
tchar.h
>
6
7
8
static
char
*
_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
}
第一:字符串指針做爲輸入參數,能夠使用byte[] 和MarshalAs來解決。(注意四個P-INVOKE,兩個ANSI版本,和兩個UNICODE版本),推薦使用MarshalAs方法簡單明瞭。ci
1
[DllImport(
"
TestDll
"
, EntryPoint
=
"
PrintString
"
)]
2
public
static
extern
void
PrintStringByBytes(
byte
[] hello);
3
4
[DllImport(
"
TestDll
"
, EntryPoint
=
"
PrintString
"
)]
5
public
static
extern
void
PrintStringByMarshal([MarshalAs(UnmanagedType.LPStr)]
string
hello);
6
7
[DllImport(
"
TestDll
"
, EntryPoint
=
"
PrintStringW
"
)]
8
public
static
extern
void
PrintStringByBytesW(
byte
[] hello);
9
10
[DllImport(
"
TestDll
"
, EntryPoint
=
"
PrintStringW
"
)]
11
public
static
extern
void
PrintStringByMarshalW([MarshalAs(UnmanagedType.LPWStr)]
string
hello);
12
13
14
public
void
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
"
)]
2
public
static
extern
IntPtr GetStringReturnByBytes();
3
4
[DllImport(
"
TestDll
"
, EntryPoint
=
"
GetStringReturn
"
)]
5
[
return
:MarshalAs(UnmanagedType.LPStr)]
6
public
static
extern
string
GetStringReturnByMarshal();
7
8
[DllImport(
"
TestDll
"
, EntryPoint
=
"
GetStringReturnW
"
)]
9
public
static
extern
IntPtr GetStringReturnByBytesW();
10
11
[DllImport(
"
TestDll
"
, EntryPoint
=
"
GetStringReturnW
"
)]
12
[
return
: MarshalAs(UnmanagedType.LPWStr)]
13
public
static
extern
string
GetStringReturnByMarshalW();
14
15
16
public
void
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
"
)]
2
public
static
extern
void
GetStringParamByBytes(
byte
[] outHello,
int
len);
3
4
[DllImport(
"
TestDll
"
, EntryPoint
=
"
GetStringParam
"
)]
5
public
static
extern
void
GetStringParamByMarshal([Out, MarshalAs(UnmanagedType.LPStr)]StringBuilder outHello,
int
len);
6
7
[DllImport(
"
TestDll
"
, EntryPoint
=
"
GetStringParamW
"
)]
8
public
static
extern
void
GetStringParamByBytesW(
byte
[] outHello,
int
len);
9
10
[DllImport(
"
TestDll
"
, EntryPoint
=
"
GetStringParamW
"
)]
11
public
static
extern
void
GetStringParamByMarshalW([Out, MarshalAs(UnmanagedType.LPWStr)]StringBuilder outHello,
int
len);
12
13
14
public
byte
[] _outHello
=
new
byte
[
10
];
15
public
byte
[] _outHelloW
=
new
byte
[
20
];
16
public
StringBuilder _builder
=
new
StringBuilder(
10
);
//
很重要設定string的容量。
17
18
public
void
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