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

    技术2022-05-11  73

        接着说说如何调用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是可以正常工作的,但不知是否是一个比较笨的方法,如果你还有更好的方法也可告诉我喔. 

    最新回复(0)