打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
C#动态调用非托管DLL
C#动态调用非托管DLL 尝试着在C#下调用以前Delphi写的一些DLL,基本实现动态调用,传入回调函数,及调用带结构数组指针作为参数的函数. 虽然DllImport可以方便的静态调用DLL的函数,但在.net2.0中新增加了一个Marshal.GetDelegateForFunctionPointer 方法,可以将非托管函数指针转换为委托。 有了这个方法就可以用三个Windows API函数即:Loadlibrary,GetProcAddress和Freelibrary来实现动态调用DLL了.下面是实现DLL动态调用的静态类using System;using System.Collections.Generic;using System.Text;using System.Runtime.InteropServices;using System.Data; namespace Test{ /// /// DLL加载类 /// internal class DynamicLoadDll { [DllImport("Kernel32")] public static extern int GetProcAddress(int handle, String funcname); [DllImport("Kernel32")] public static extern int LoadLibrary(String funcname); [DllImport("Kernel32")] public static extern int FreeLibrary(int handle); public static Delegate GetAddress(int dllModule, string functionname, Type t) { int addr = GetProcAddress(dllModule, functionname); if (addr == 0) return null; else return Marshal.GetDelegateForFunctionPointer(new IntPtr(addr), t); }} Public class referDll{private int m_hDLL = 0; //DLL句柄 private delegate int ShowForm(IntPtr aHandle); private ShowForm m_ShowForm; private const string DLLNAEM = "XXX.dll"; m_hDLL = DllLoader.LoadLibrary(DLLNAEM); if (m_hDLL == 0) { MessageBox.Show("加载失败!") return; } m_ShowForm = (ShowForm) DllLoader.GetAddress(m_hPacsview, "ShowForm", typeof (ShowForm));//使用ShowForm if (m_ShowForm != null) m_ShowForm(iHandle);//卸载DLLDllLoader.FreeLibrary(m_hDLL); }}接着说说如何调用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;} m_open(parrstudyrec); 50;="" i++){arrstudyrec[i].uid="i.tostring();//这里只是模拟,所以直接把i当作UID了Marshal.StructureToPtr(arrStudyRec[i]," (intptr)="" run,="" false);run="" +="isize;}">
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
创建Win32DLL,并在C#里面调用
C#托管代码与C++非托管代码互相调用一(C#调用C++代码&.net 代码安全)
c# – 如何从非托管DLL访问包含动态数组的csharp中的结构?
C# 互操作性入门系列(二):使用平台调用调用Win32 函数
C#中DllImport用法和路径问题
C#调用非托管程序5种方式
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服