c#里实现dll调用(郁闷版)
时间:2011-01-23 来源:orchids
public Delegate Invoke(string APIName, Type t)
{
IntPtr api = GetProcAddress(hModule, APIName);
return (Delegate)Marshal.GetDelegateForFunctionPointer(api, t);
}
/// <summary>
/// Loadlibrary 返回的函数库模块的句柄
/// </summary>
private IntPtr hModule = IntPtr.Zero;
/// <summary>
/// GetProcAddress 返回的函数指针
/// </summary>
private IntPtr farProc = IntPtr.Zero;
/// <summary>
/// 装载 Dll
/// </summary>
/// <param name="lpFileName">DLL 文件名 </param>
public void LoadDll(string lpFileName)
{
hModule = LoadLibrary(lpFileName);
if (hModule == IntPtr.Zero)
throw (new Exception(" 没有找到 :" + lpFileName + "."));
}
// 若已有已装载Dll的句柄,可以使用LoadDll方法的第二个版本:
public void LoadDll(IntPtr HMODULE)
{
if (HMODULE == IntPtr.Zero)
throw (new Exception(" 所传入的函数库模块的句柄 HMODULE 为空 ."));
hModule = HMODULE;
}
/// <summary>
/// 获得函数指针
/// </summary>
/// <param name="lpProcName"> 调用函数的名称 </param>
public void LoadFun(string lpProcName)
{ // 若函数库模块的句柄为空,则抛出异常
if (hModule == IntPtr.Zero)
throw (new Exception(" 函数库模块的句柄为空 , 请确保已进行 LoadDll 操作 !"));
// 取得函数指针
farProc = GetProcAddress(hModule, lpProcName);
// 若函数指针,则抛出异常
if (farProc == IntPtr.Zero)
throw (new Exception(" 没有找到 :" + lpProcName + " 这个函数的入口点 "));
}
/// <summary>
/// 获得函数指针
/// </summary>
/// <param name="lpFileName"> 包含需调用函数的 DLL 文件名 </param>
/// <param name="lpProcName"> 调用函数的名称 </param>
public void LoadFun(string lpFileName, string lpProcName)
{ // 取得函数库模块的句柄
hModule = LoadLibrary(lpFileName);
// 若函数库模块的句柄为空,则抛出异常
if (hModule == IntPtr.Zero)
throw (new Exception(" 没有找到 :" + lpFileName + "."));
// 取得函数指针
farProc = GetProcAddress(hModule, lpProcName);
// 若函数指针,则抛出异常
if (farProc == IntPtr.Zero)
throw (new Exception(" 没有找到 :" + lpProcName + " 这个函数的入口点 "));
}
/// <summary>
/// 卸载 Dll
/// </summary>
public void UnLoadDll()
{
FreeLibrary(hModule);
hModule = IntPtr.Zero;
farProc = IntPtr.Zero;
}
Dll函数如下:
extern "C" _declspec(dllexport)int _stdcall count(int init);
int _stdcall count(int init)
{//count 函数,使用参数 init 初始化静态的整形变量 S ,并使 S 自加 1 后返回该值
static int S=init;
S++;
return S;
}
下面是调用的代码:
private void button1_Click_1(object sender, EventArgs e)
{
Class1 tryDll = new Class1();
tryDll.LoadDll(@"D:\Count.dll");//加载dll
tryDll.LoadFun("_count@4");//找到函数入口 ,这个函数名可能和dll中的不一样,必须找到编绎后的dll函数名,就这个,困扰了我一下午,所以当我找到他时,我快要疯了,郁闷死了
//tryDll.Invoke("_count@4", typeof(Class1));//错误同上 ,类型必须从委托中派生
tryDll.UnLoadDll();//缷载dll
}