接着说说如何调用DLL中带结构数组指针作为参数的函数.在原来Delphi中定义如下:
//一个结构定义如下
TStudyRec = Record
UID : Array[0..127 ] of Char;
end;
TCharArray=Array[0..49 ] of TStudyRec;
//在DLL中有如下函数 其中AStudys为TCharArray的指针
function Open(AStudys: Pointer): HRESULT; StdCall;
TStudyRec = Record
UID : Array[0..127 ] of Char;
end;
TCharArray=Array[0..49 ] of TStudyRec;
//在DLL中有如下函数 其中AStudys为TCharArray的指针
function Open(AStudys: Pointer): HRESULT; StdCall;
要在C#里正常调用,首先要定义出一个相同的结构
private struct
StudyRec
... {
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] public string UID; //名称
}
... {
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] public string UID; //名称
}
接着声明一个委托
private delegate int
Open(IntPtr aStudys);
从DLL得到委托实例
private
Open m_Open
=
(Open) DllLoader.GetAddress(m_hDLL,
"
Open
"
,
typeof
(Open));
//
m_hDLL为DLL指针
好,到此为止终于在C#里定义出相同的结果及函数了,下面就是要调用了,因为结构数组是要给非托管的DLL使用的,因此最关键的一点是要用Marshal.AllocHGlobal来分配好非托管内存,把结构数组放到内存中去,再把内存指针当作参数调用就OK啦
StudyRec[] arrStudyRec
= new StudyRec[50
];
int isize = Marshal.SizeOf(typeof (StudyRec));
IntPtr parrStudyRec = Marshal.AllocHGlobal(Marshal.SizeOf(isize*50 ));
int run = (int ) parrStudyRec;
for (int i = 0; i < 50; i++ )
... {
arrStudyRec[i].UID = i.tostring();//这里只是模拟,所以直接把i当作UID了
Marshal.StructureToPtr(arrStudyRec[i], (IntPtr) run, false);
run += isize;
}
//好,前期工作结束,剩下的就交给调用的DLL啦
int isize = Marshal.SizeOf(typeof (StudyRec));
IntPtr parrStudyRec = Marshal.AllocHGlobal(Marshal.SizeOf(isize*50 ));
int run = (int ) parrStudyRec;
for (int i = 0; i < 50; i++ )
... {
arrStudyRec[i].UID = i.tostring();//这里只是模拟,所以直接把i当作UID了
Marshal.StructureToPtr(arrStudyRec[i], (IntPtr) run, false);
run += isize;
}
//好,前期工作结束,剩下的就交给调用的DLL啦
//前期的所有工作就是为了能正常用到m_Open
m_Open(parrStudyRec);