C#动态调用非托管DLL(二)

    接着说说如何调用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;

要在C#里正常调用,首先要定义出一个相同的结构

private struct  StudyRec
        
{
            [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啦
       //前期的所有工作就是为了能正常用到m_Open
     m_Open(parrStudyRec);
非托管DLL的调用基本上就说这么多了.试用时发现这样调用DLL是可以正常工作的,但不知是否是一个比较笨的方法,如果你还有更好的方法也可告诉我喔. 

你可能感兴趣的:(C#)