委托delegate的使用-动态加载DLL控件 转
委托delegate的使用-动态加载DLL控件
上次利用Dllimport加载DLL控件时,却只能加载固定路径的DLL文件。对于一些路径不确定的DLL文件来说,这种方法是无法完全满足要求的。
或许有些人会认为DLL文件都可以利用引用方法来加载并进行开发,可对于非托管了DLL控件是无法实现的。这时,唯一的办法就是使用委托方法。
很遗憾的是,我接触委托太少了,早前也没有完整使用过。
一下这样是我在Google上找到了。本人测试时,完全可以使用
首先:要使用下面的类
public class DLLWrapper
{
///<summary>
///API LoadLibrary
///</summary>
[DllImport("Kernel32")]
public static extern int LoadLibrary(String funcname);
///<summary>
///API GetProcAddress
///</summary>
[DllImport("Kernel32")]
public static extern int GetProcAddress(int handle,String funcname);
///<summary>
///API FreeLibrary
///</summary>
[DllImport("Kernel32")]
public static extern int FreeLibrary(int handle);
///<summary>
///通过非托管函数名转换为对应的委托, by jingzhongrong
///</summary>
///<param name="dllModule">通过LoadLibrary获得的DLL句柄</param>
///<param name="functionName">非托管函数名</param>
///<param name="t">对应的委托类型</param>
///<returns>委托实例,可强制转换为适当的委托类型</returns>
public static Delegate GetFunctionAddress(int dllModule,string functionName,Type t)
{
int address=GetProcAddress(dllModule,functionName);
if(address== 0)
return null;
else
return Marshal.GetDelegateForFunctionPointer(new IntPtr(address),t);
}
///<summary>
///将表示函数地址的IntPtr实例转换成对应的委托。
///</summary>
public static Delegate GetDelegateFromIntPtr(IntPtr address,Type t)
{
if(address==IntPtr.Zero)
return null;
else
return Marshal.GetDelegateForFunctionPointer(address,t);
}
///<summary>
///将表示函数地址的int转换成对应的委托。
///</summary>
public static Delegate GetDelegateFromIntPtr(int address,Type t)
{
if(address== 0)
return null;
else
return Marshal.GetDelegateForFunctionPointer(new IntPtr(address),t);
}
}
public class DLLWrapper
{
///<summary>
///API LoadLibrary
///</summary>
[DllImport("Kernel32")]
public static extern int LoadLibrary(String funcname);
///<summary>
///API GetProcAddress
///</summary>
[DllImport("Kernel32")]
public static extern int GetProcAddress(int handle,String funcname);
///<summary>
///API FreeLibrary
///</summary>
[DllImport("Kernel32")]
public static extern int FreeLibrary(int handle);
///<summary>
///通过非托管函数名转换为对应的委托, by jingzhongrong
///</summary>
///<param name="dllModule">通过LoadLibrary获得的DLL句柄</param>
///<param name="functionName">非托管函数名</param>
///<param name="t">对应的委托类型</param>
///<returns>委托实例,可强制转换为适当的委托类型</returns>
public static Delegate GetFunctionAddress(int dllModule,string functionName,Type t)
{
int address=GetProcAddress(dllModule,functionName);
if(address== 0)
return null;
else
return Marshal.GetDelegateForFunctionPointer(new IntPtr(address),t);
}
///<summary>
///将表示函数地址的IntPtr实例转换成对应的委托。
///</summary>
public static Delegate GetDelegateFromIntPtr(IntPtr address,Type t)
{
if(address==IntPtr.Zero)
return null;
else
return Marshal.GetDelegateForFunctionPointer(address,t);
}
///<summary>
///将表示函数地址的int转换成对应的委托。
///</summary>
public static Delegate GetDelegateFromIntPtr(int address,Type t)
{
if(address== 0)
return null;
else
return Marshal.GetDelegateForFunctionPointer(new IntPtr(address),t);
}
}
第二步骤使用
[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);
[DllImport("Kernel32")] <br/> public static extern int GetProcAddress(int handle,String funcname); <br/><br/> [DllImport("Kernel32")] <br/> public static extern int LoadLibrary(String funcname); <br/><br/> [DllImport("Kernel32")] <br/> public static extern int FreeLibrary(int handle);<br/>
第三步骤使用委托,我今天就是卡在这个步骤,后来,小张帮我找到这个问题。
public delegate string FOO(bool HDD, bool NIC, bool CPU, bool BIOS, string sRegistrationCode);
public delegate string FOO(bool HDD, bool NIC, bool CPU, bool BIOS, string sRegistrationCode);<br/>
第四步骤,开始委托
int hModule = DLLWrapper.LoadLibrary(Server.MapPath("bin/aq82.dll"));
Response.Write(hModule.ToString());
//if (inthModule == 0)
FOO foo = (FOO)DLLWrapper.GetFunctionAddress(hModule, "FunctionName", typeof(FOO));
if (foo == null)
{
DLLWrapper.FreeLibrary(hModule);
return;
}
Response.Write("<br/>");
Response.Write(foo(true, false, false, false, "R5LR-S4TQ"));