郑州建站排名,深圳网站设计公司怎么样,网站设计对网站搜索引擎友好性的影响,wordpress formcraft 0.8下载在使用第三方的非托管API时#xff0c;我们经常会遇到参数为指针或指针的指针这种情况#xff0c;
一般我们会用IntPtr指向我们需要传递的参数地址#xff1b; 但是当遇到这种一个导出函数时,我们如何正确的使用IntPtr呢#xff0c;
extern C __declspec(dll…在使用第三方的非托管API时我们经常会遇到参数为指针或指针的指针这种情况
一般我们会用IntPtr指向我们需要传递的参数地址 但是当遇到这种一个导出函数时,我们如何正确的使用IntPtr呢
extern C __declspec(dllexport) int GetClass(Class pClass[50]) 由于这种情况也经常可能遇到所以我制作了2个示例程序来演示下如何处理这种非托管函数的调用 首先创建一个C 的DLL 设置一个如上的导出函数
#include Windows.h
#include stdio.htypedef struct Student
{ char name[20]; int age; double scores[32];
}Student;typedef struct Class
{int number;Student students[126];
}Class;extern C __declspec(dllexport)int GetClass(Class pClass[50])
{ for(int i0;i50;i) { pClass[i].numberi; for(int j0;j126;j) { memset(pClass[i].students[j].name,0,20); sprintf(pClass[i].students[j].name,name_%d_%d,i,j); pClass[i].students[j].agej%20?15:20; } } return 0;30
} 上面DLL 的导出函数要求传递的参数为它自定义的Class结构体数组 那么我们在C#调用它时也要自定义对应的结构体了
我们可以定义为如下
[StructLayout(LayoutKind.Sequential)]struct Student{[MarshalAs(UnmanagedType.ByValTStr,SizeConst20)]public string name;public int age;[MarshalAs(UnmanagedType.ByValArray,SizeConst32)]public double[] scores;}[StructLayout(LayoutKind.Sequential)]struct Class{public int number;[MarshalAs(UnmanagedType.ByValArray,SizeConst126)]public Student[] students;} 需要注意的是这2个结构体中的数组大小一定要跟C中的限定一样大小哦接下来如何使用这个API来正确的获取数据呢大多数人可能想到像这样的处理方式
Class myclass new Class();
IntPtr ptrMarshal.AllocHGlobal(Marshal.SizeOf(typeof(Class)));
GetClass(ptr);
Marshal.FreeHGlobal(ptr); 没错这样的处理是没问题的但是我们的API的参数是Class数组这种处理方式只是传递一个Class结构体参数,所以这种方式在这里就不太合适了 那大家就想到先Class[] myclass new Class[MaxClass]; 然后在用Marshal.AllocHGlobal 来获取myclass 数据的指针
其实这样也是错的 因为 Class结构中包含了不能直接封送的Student结构所以无论如何上面的想法是错误的
那要怎么办呢其实很简单就是先分配一段非托管内存并调用API后再将非托管内容数据读取到托管结构体数据中 static void Main(string[] args)
{int size Marshal.SizeOf(typeof(Class)) * 50;byte[] bytes new byte[size];IntPtr pBuff Marshal.AllocHGlobal(size);Class[] pClass new Class[50];GetClass(pBuff);for (int i 0; i 50; i){IntPtr pPonitor new IntPtr(pBuff.ToInt64() Marshal.SizeOf(typeof(Class)) * i);pClass[i] (Class)Marshal.PtrToStructure(pPonitor, typeof(Class));}Marshal.FreeHGlobal(pBuff);Console.ReadLine();
}