c# 平台调用 传递参数
最近做项目用到了dll,网上介绍了很多,但是真要自己实现起来确实也费了不少功夫,这里有自己基础不扎实的原因,也有客观原因,比如平台调用中,好多细节问题如果注意不到,就会得到错误的答案。下面是些我写的一些小测试程序:
1
//str为输入参数,outstr为输出参数2
char* strtest(char* str, int a, unsigned char* outstr);3

4
[DllImport("FaceLib.dll", EntryPoint = "strtest", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]5
public static extern string strtest(string str,out int a,[In,Out] byte [] outstr); 6

7
调用函数为:8
private void button1_Click(object sender, EventArgs e)9

{10
//ss();11
//test2 x = new test2();12
//x.n1 = 4;13
//x.n2 = 8;14
//test2fun(x); 15

16
//FaceDetectModel fdmodel = new FaceDetectModel();17
//Bitmap bmp = new Bitmap("c:\\image.bmp");18
//Convert_to_IntImage_ref(ref fdmodel, bmp);19
//loadFaceDetectModel(fdmodel, "C:\\data.txt");20
//showFaceDetectModel(fdmodel, "c:\\data1.txt");21

22
string s = "c:\\data.txt";23
int a = 0;24
string ss = "";25

26
byte[] sb = new byte[256];27
for (int i = 0; i < 256; i++)28

{29
sb[i] = (byte)(256-i);30
}31
strtest(s, out a, sb);32
foreach (int i in sb)33

{34
ss = ss + sb[i].ToString() + " ";35
} 36
37

/**/////StringBuilder sb = new StringBuilder(256);38
MessageBox.Show(ss);39
}40

41
应该注意的问题:42
1. c#编码方式是unicode,而c里面是Ansi。在传入字符串时,要指定CharSet为Ansi格式,否则会出错。43
2. 传入char* 用string即可,这方面资料很多,传出用StringBuilder,原因可以参见csdn上的封送字符串,和回调函数部分的介绍。这里要说的是,用StringBuilder来传出参数时,要保证函数执行完保存在非托管函数参数中的值不被释放,比如在原函数char* strtest(char* str, int a, unsigned char* outstr);中如果我把以字符串传入str,然后保存到char* outstr中,要用memcpy()或strcpy()来拷贝,而不能直接outstr=str,这在原函数中执行是没问题的,但是执行完毕后,不能返回到c#的托管函数。其中原因就是outstr只是一个str的copy,或者说outstr和str指向了同一块内存,在非托管函数执行完毕后,outstr就销毁了,自然也不能返回值。44

45


浙公网安备 33010602011771号