真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C#中怎么調(diào)用DLL函數(shù)

今天就跟大家聊聊有關(guān)C#中怎么調(diào)用DLL函數(shù),可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

創(chuàng)新互聯(lián)專(zhuān)注為客戶(hù)提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站制作、做網(wǎng)站、長(zhǎng)汀網(wǎng)絡(luò)推廣、成都微信小程序、長(zhǎng)汀網(wǎng)絡(luò)營(yíng)銷(xiāo)、長(zhǎng)汀企業(yè)策劃、長(zhǎng)汀品牌公關(guān)、搜索引擎seo、人物專(zhuān)訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供長(zhǎng)汀建站搭建服務(wù),24小時(shí)服務(wù)熱線(xiàn):13518219792,官方網(wǎng)址:www.cdcxhl.com

因?yàn)镃#中使用DllImport是不能像動(dòng)態(tài)load/unload assembly那樣,所以只能借助API函數(shù)了。在kernel32.dll中,與動(dòng)態(tài)庫(kù)調(diào)用有關(guān)的函數(shù)包括[3]:

①LoadLibrary(或MFC 的AfxLoadLibrary),裝載動(dòng)態(tài)庫(kù)。

②GetProcAddress,獲取要引入的函數(shù),將符號(hào)名或標(biāo)識(shí)號(hào)轉(zhuǎn)換為DLL內(nèi)部地址。

③FreeLibrary(或MFC的AfxFreeLibrary),釋放動(dòng)態(tài)鏈接庫(kù)。

它們的原型分別是:

HMODULE LoadLibrary(LPCTSTR lpFileName);

FARPROC GetProcAddress(HMODULE hModule, LPCWSTR lpProcName);

BOOL FreeLibrary(HMODULE hModule);

現(xiàn)在,我們可以用IntPtr hModule=LoadLibrary(“Count.dll”);來(lái)獲得Dll的句柄,用IntPtr farProc=GetProcAddress(hModule,”_count@4”);來(lái)獲得函數(shù)的入口地址。

但是,知道函數(shù)的入口地址后,怎樣調(diào)用這個(gè)函數(shù)呢?因?yàn)樵贑#中是沒(méi)有函數(shù)指針的,沒(méi)有像C++那樣的函數(shù)指針調(diào)用方式來(lái)調(diào)用函數(shù),所以我們得借助其它方法。經(jīng)過(guò)研究,發(fā)現(xiàn)我們可以通過(guò)結(jié)合使用System.Reflection.Emit及System.Reflection.Assembly里的類(lèi)和函數(shù)達(dá)到我們的目的。為了以后使用方便及實(shí)現(xiàn)代碼的復(fù)用,我們可以編寫(xiě)一個(gè)類(lèi)。

1) dld類(lèi)的編寫(xiě):

1.打開(kāi)項(xiàng)目“Test”,打開(kāi)類(lèi)視圖,右擊“Tzb”,選擇“添加”-->“類(lèi)”,類(lèi)名設(shè)置為“dld”,即dynamic loading dll 的每個(gè)單詞的開(kāi)頭字母。

2.添加所需的命名空間及聲明參數(shù)傳遞方式枚舉:

using System.Runtime.InteropServices; // 用DllImport 需用此命名空間   using System.Reflection; // 使用Assembly 類(lèi)需用此命名空間   using System.Reflection.Emit; // 使用ILGenerator 需用此命名空間

3. 在namespace test中,“public class dld”的上面,添加如下代碼聲明參數(shù)傳遞方式枚舉:

/// < summary>        /// 參數(shù)傳遞方式枚舉,ByValue 表示值傳遞,ByRef 表示址傳遞       /// < /summary>        public enum ModePass       {           ByValue = 0x0001,           ByRef = 0x0002   }

4、在public class DLD中,添加如下代碼:

public class DLD       {           [DllImport("kernel32.dll")]           public static extern IntPtr LoadLibrary(string lpFileName);               [DllImport("kernel32.dll")]           public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProceName);               [DllImport("kernel32", EntryPoint = "FreeLibrary", SetLastError = true)]           public static extern bool FreeLibrary(IntPtr hModule);               /// < summary>                /// Loadlibrary 返回的函數(shù)庫(kù)模塊的句柄                /// < /summary>                private IntPtr hModule = IntPtr.Zero;               /// < summary>                /// GetProcAddress 返回的函數(shù)指針                /// < /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(" 沒(méi)有找到 :" + lpFileName + "."));           }                   /// < summary>                /// 獲得函數(shù)指針                /// < /summary>                /// < param name="lpProcName"> 調(diào)用函數(shù)的名稱(chēng) < /param>                public void LoadFun(string lpProcName)           { // 若函數(shù)庫(kù)模塊的句柄為空,則拋出異常                    if (hModule == IntPtr.Zero)                       throw (new Exception(" 函數(shù)庫(kù)模塊的句柄為空 , 請(qǐng)確保已進(jìn)行 LoadDll 操作 !"));                   // 取得函數(shù)指針                    farProc = GetProcAddress(hModule, lpProcName);                   // 若函數(shù)指針,則拋出異常                    if (farProc == IntPtr.Zero)                       throw (new Exception(" 沒(méi)有找到 :" + lpProcName + " 這個(gè)函數(shù)的入口點(diǎn) "));               }               /// < summary>                /// 卸載 Dll                /// < /summary>                public void UnLoadDll()           {                   FreeLibrary(hModule);                   hModule = IntPtr.Zero;                   farProc = IntPtr.Zero;               }                   /// < summary>                /// 調(diào)用所設(shè)定的函數(shù)                /// < /summary>                /// < param name="ObjArray_Parameter"> 實(shí)參 < /param>                /// < param name="TypeArray_ParameterType"> 實(shí)參類(lèi)型 < /param>                /// < param name="ModePassArray_Parameter"> 實(shí)參傳送方式 < /param>                /// < param name="Type_Return"> 返回類(lèi)型 < /param>                /// < returns> 返回所調(diào)用函數(shù)的 object< /returns>                public object Invoke(object[] ObjArray_Parameter, Type[] TypeArray_ParameterType, ModePass[] ModePassArray_Parameter, Type Type_Return)           {                   // 下面 3 個(gè) if 是進(jìn)行安全檢查 , 若不能通過(guò) , 則拋出異常                    if (hModule == IntPtr.Zero)                       throw (new Exception(" 函數(shù)庫(kù)模塊的句柄為空 , 請(qǐng)確保已進(jìn)行 LoadDll 操作 !"));                   if (farProc == IntPtr.Zero)                       throw (new Exception(" 函數(shù)指針為空 , 請(qǐng)確保已進(jìn)行 LoadFun 操作 !"));                   if (ObjArray_Parameter.Length != ModePassArray_Parameter.Length)                       throw (new Exception(" 參數(shù)個(gè)數(shù)及其傳遞方式的個(gè)數(shù)不匹配 ."));                   // 下面是創(chuàng)建 MyAssemblyName 對(duì)象并設(shè)置其 Name 屬性                    AssemblyName MyAssemblyName = new AssemblyName();                   MyAssemblyName.Name = "InvokeFun";                   // 生成單模塊配件                    AssemblyBuilder MyAssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(MyAssemblyName, AssemblyBuilderAccess.Run);                   ModuleBuilder MyModuleBuilder = MyAssemblyBuilder.DefineDynamicModule("InvokeDll");                   // 定義要調(diào)用的方法 , 方法名為“ MyFun ”,返回類(lèi)型是“ Type_Return ”參數(shù)類(lèi)型是“ TypeArray_ParameterType ”                    MethodBuilder MyMethodBuilder = MyModuleBuilder.DefineGlobalMethod("MyFun", MethodAttributes.Public | MethodAttributes.Static, Type_Return, TypeArray_ParameterType);                   // 獲取一個(gè) ILGenerator ,用于發(fā)送所需的 IL                    ILGenerator IL = MyMethodBuilder.GetILGenerator();                   int i;                   for (i = 0; i <  ObjArray_Parameter.Length; i++)               {// 用循環(huán)將參數(shù)依次壓入堆棧                        switch (ModePassArray_Parameter[i])                   {                           case ModePass.ByValue:                               IL.Emit(OpCodes.Ldarg, i);                               break;                           case ModePass.ByRef:                               IL.Emit(OpCodes.Ldarga, i);                               break;                           default:                               throw (new Exception(" 第 " + (i + 1).ToString() + " 個(gè)參數(shù)沒(méi)有給定正確的傳遞方式 ."));                       }                   }                   if (IntPtr.Size == 4)               {// 判斷處理器類(lèi)型                        IL.Emit(OpCodes.Ldc_I4, farProc.ToInt32());                   }                   else if (IntPtr.Size == 8)               {                       IL.Emit(OpCodes.Ldc_I8, farProc.ToInt64());                   }                   else              {                       throw new PlatformNotSupportedException();                   }                   IL.EmitCalli(OpCodes.Calli, CallingConvention.StdCall, Type_Return, TypeArray_ParameterType);                   IL.Emit(OpCodes.Ret); // 返回值                    MyModuleBuilder.CreateGlobalFunctions();                   // 取得方法信息                    MethodInfo MyMethodInfo = MyModuleBuilder.GetMethod("MyFun");                   return MyMethodInfo.Invoke(null, ObjArray_Parameter);// 調(diào)用方法,并返回其值                }       }

2) dld類(lèi)的使用:

1.打開(kāi)項(xiàng)目“Test”,向“Form1”窗體中添加一個(gè)按鈕,和一個(gè)TestBox,Name改為txRet。視圖中雙擊按鈕,在“button1_Click”方法體上面添加代碼,創(chuàng)建一個(gè)dld類(lèi)實(shí)例,并進(jìn)行測(cè)試。具體如下:

private void button1_Click(object sender, EventArgs e)           {                   int ret = 0;               dld myDLD = new dld();                   myDLD.LoadDll("xxx.dll");                   myDLD.LoadFun("InitSDK");                   object[] Parameters = new object[] { }; // 實(shí)參為0                    Type[] ParameterTypes = new Type[] { }; // 實(shí)參類(lèi)型為int                    ModePass[] themode = new ModePass[] { }; // 傳送方式為值傳                   Type Type_Return = typeof(int); // 返回類(lèi)型為int                   ret = (int)myDLD.Invoke(Parameters, ParameterTypes, themode, Type_Return);               txRet.Text = ret.ToString();               if (ret != 1)               {                   MessageBox.Show("InitSDK failed !");               }               if (ret == 1)               {                   MessageBox.Show("InitSDK Sucessed !");               }           }

其中,xxx為要測(cè)試的dll名稱(chēng),InitSDK為dll中的要測(cè)試的函數(shù)。

看完上述內(nèi)容,你們對(duì)C#中怎么調(diào)用DLL函數(shù)有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。


標(biāo)題名稱(chēng):C#中怎么調(diào)用DLL函數(shù)
鏈接分享:http://weahome.cn/article/jiesho.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部