using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.InteropServices;//加载非托管dll(跨平台dll)的调用类库 using System.ComponentModel;//显示win32错误代码提示 namespace DllHandle { public class NotHostingDLLHandler { //kernel32.dll是Windows 9x/Me中非常重要的32位动态链接库文件,属于内核级文件。 //它控制着系统的内存管理、数据的输入输出操作和中断处理,当Windows启动时,kernel32.dll就驻留在内存中特定的写保护区域,使别的程序无法占用这个内存区域。 //LoadLibrary:传入dll路径,返回dll的实例指针 [DllImport("Kernel32.dll")] private static extern IntPtr LoadLibrary(string path); //GetProcAddress:,参数lib为LoadLibrary()方法返回的值,FunName方法名,返回dll中指定的方法委托 [DllImport("Kernel32.dll")] private static extern IntPtr GetProcAddress(IntPtr lib, string FunName); [DllImport("kernel32.dll")] public static extern bool FreeLibrary(IntPtr lib); private IntPtr libr;//指针或句柄 public NotHostingDLLHandler(string path) { libr = LoadLibrary(path);//加载非托管dll的加载 } public Delegate Invoke(string funName, Type type) { Delegate d = null; try { IntPtr api = GetProcAddress(libr, funName); d = (Delegate)Marshal.GetDelegateForFunctionPointer(api, type);//把非托管函数转化为委托 } catch (Exception) { Console.WriteLine(new Win32Exception().Message); } return d; } ~NotHostingDLLHandler()//按位取反~ { FreeLibrary(libr); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using DllHandle; using System.Reflection;//加载托管dll(非跨平台dll)的调用类库 using System.Runtime.InteropServices; using System.IO; namespace DllHelper { class Program { public delegate bool DBConnect();//如果需要执行的函数有参数,可对之进行声明。 static void Main(string[] args) { int index = AppDomain.CurrentDomain.BaseDirectory.IndexOf(@"\bin"); string path = AppDomain.CurrentDomain.BaseDirectory.Substring(0, index) + "\\Dlls\\zlDrugPacker.dll"; // Assembly ab = DllHandler.GetUrlAssembly(path);//获取指定路径的dll对象,这里加载的是托管的dll,不是第三方的,而是.net自带的,调用方式与是否注册没关系 //zlDrugPacker.clsDrugPacker model = new zlDrugPacker.clsDrugPacker(); //model.DBConnect(); NotHostingDLLHandler notHostdll = new NotHostingDLLHandler(path); DBConnect dbconnect = (DBConnect)notHostdll.Invoke("DBConnect", typeof(DBConnect)); //show(); Console.ReadLine(); } } }
问题:IntPtr api = GetProcAddress(libr, funName);//函数指针获取为0,libr的dll地址是获取到的。
其中zlDrugPacker.dll为我的VB6的非托管代码
P/invoke上有这个例子,http://www.pinvoke.net/default.aspx/kernel32/GetProcAddress.html
VB6的代码是32位的,你的托管程序是64位的吧
感谢你的回复,这里我的系统确定是32位的系统,在这里我的dll文件中有个函数名叫:DBConnect(),名字是没有写错的。
奇怪的是:网上我下载了其他的demo调用我的dll文件时都出现GetProcAddress方法返回值为0的情况,而他们的demo调用自己的非托管dll能成功调用。
@Lasthelloworld: VB我不太熟,是否函数的导出不对,使用depends.exe看看dll的输出信息,或者查查该函数的stdcall cdcall之类的导出函数用法
@2012: 好的,我刚才已经打开了但是第一次用denpends.exe,先研究下