国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

C#調用DLL函數方法(下)

開發 后端
本文繼續介紹了C#調用DLL函數方法。

本文的內容接著C#調用DLL函數方法(上)。

因為C#中使用DllImport是不能像動態load/unload assembly那樣,所以只能借助API函數了。在kernel32.dll中,與動態庫調用有關的函數包括[3]:

①LoadLibrary(或MFC 的AfxLoadLibrary),裝載動態庫。

②GetProcAddress,獲取要引入的函數,將符號名或標識號轉換為DLL內部地址。

③FreeLibrary(或MFC的AfxFreeLibrary),釋放動態鏈接庫。

它們的原型分別是:

HMODULE LoadLibrary(LPCTSTR lpFileName);

FARPROC GetProcAddress(HMODULE hModule, LPCWSTR lpProcName);

BOOL FreeLibrary(HMODULE hModule);

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

但是,知道函數的入口地址后,怎樣調用這個函數呢?因為在C#中是沒有函數指針的,沒有像C++那樣的函數指針調用方式來調用函數,所以我們得借助其它方法。經過研究,發現我們可以通過結合使用System.Reflection.Emit及System.Reflection.Assembly里的類和函數達到我們的目的。為了以后使用方便及實現代碼的復用,我們可以編寫一個類。

1) dld類的編寫:

1.打開項目“Test”,打開類視圖,右擊“Tzb”,選擇“添加”-->“類”,類名設置為“dld”,即dynamic loading dll 的每個單詞的開頭字母。

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

  1. using System.Runtime.InteropServices; // 用DllImport 需用此命名空間  
  2.  
  3. using System.Reflection; // 使用Assembly 類需用此命名空間  
  4.  
  5. using System.Reflection.Emit; // 使用ILGenerator 需用此命名空間  

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

   

  1. /// < summary>   
  2.  
  3.     /// 參數傳遞方式枚舉,ByValue 表示值傳遞,ByRef 表示址傳遞  
  4.  
  5.     /// < /summary>   
  6.  
  7.     public enum ModePass  
  8.  
  9.     {  
  10.  
  11.         ByValue = 0x0001,  
  12.  
  13.         ByRef = 0x0002  
  14.  
  15. }  
  16.  

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

   

  1. public class DLD  
  2.  
  3.     {  
  4.  
  5.         [DllImport("kernel32.dll")]  
  6.  
  7.         public static extern IntPtr LoadLibrary(string lpFileName);  
  8.  
  9.    
  10.  
  11.         [DllImport("kernel32.dll")]  
  12.  
  13.         public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProceName);  
  14.  
  15.    
  16.  
  17.         [DllImport("kernel32", EntryPoint = "FreeLibrary", SetLastError = true)]  
  18.  
  19.         public static extern bool FreeLibrary(IntPtr hModule);  
  20.  
  21.    
  22.  
  23.         /// < summary>   
  24.  
  25.    
  26.  
  27.         /// Loadlibrary 返回的函數庫模塊的句柄   
  28.  
  29.    
  30.  
  31.         /// < /summary>   
  32.  
  33.    
  34.  
  35.         private IntPtr hModule = IntPtr.Zero;  
  36.  
  37.    
  38.  
  39.         /// < summary>   
  40.  
  41.    
  42.  
  43.         /// GetProcAddress 返回的函數指針   
  44.  
  45.    
  46.  
  47.         /// < /summary>   
  48.  
  49.    
  50.  
  51.         private IntPtr farProc = IntPtr.Zero;  
  52.  
  53.    
  54.  
  55.         /// < summary>   
  56.  
  57.    
  58.  
  59.         /// 裝載 Dll   
  60.  
  61.    
  62.  
  63.         /// < /summary>   
  64.  
  65.    
  66.  
  67.         /// < param name="lpFileName">DLL 文件名 < /param>   
  68.  
  69.    
  70.  
  71.         public void LoadDll(string lpFileName)  
  72.  
  73.         {  
  74.  
  75.    
  76.  
  77.             hModule = LoadLibrary(lpFileName);  
  78.  
  79.    
  80.  
  81.             if (hModule == IntPtr.Zero)  
  82.  
  83.    
  84.  
  85.                 throw (new Exception(" 沒有找到 :" + lpFileName + "."));  
  86.  
  87.         }  
  88.  
  89.    
  90.  
  91.    
  92.  
  93.         /// < summary>   
  94.  
  95.    
  96.  
  97.         /// 獲得函數指針   
  98.  
  99.    
  100.  
  101.         /// < /summary>   
  102.  
  103.    
  104.  
  105.         /// < param name="lpProcName"> 調用函數的名稱 < /param>   
  106.  
  107.    
  108.  
  109.         public void LoadFun(string lpProcName)  
  110.  
  111.         { // 若函數庫模塊的句柄為空,則拋出異常   
  112.  
  113.    
  114.  
  115.             if (hModule == IntPtr.Zero)  
  116.  
  117.    
  118.  
  119.                 throw (new Exception(" 函數庫模塊的句柄為空 , 請確保已進行 LoadDll 操作 !"));  
  120.  
  121.    
  122.  
  123.             // 取得函數指針   
  124.  
  125.    
  126.  
  127.             farProc = GetProcAddress(hModule, lpProcName);  
  128.  
  129.    
  130.  
  131.             // 若函數指針,則拋出異常   
  132.  
  133.    
  134.  
  135.             if (farProc == IntPtr.Zero)  
  136.  
  137.    
  138.  
  139.                 throw (new Exception(" 沒有找到 :" + lpProcName + " 這個函數的入口點 "));  
  140.  
  141.    
  142.  
  143.         }  
  144.  
  145.    
  146.  
  147.         /// < summary>   
  148.  
  149.    
  150.  
  151.         /// 卸載 Dll   
  152.  
  153.    
  154.  
  155.         /// < /summary>   
  156.  
  157.    
  158.  
  159.         public void UnLoadDll()  
  160.  
  161.         {  
  162.  
  163.    
  164.  
  165.             FreeLibrary(hModule);  
  166.  
  167.    
  168.  
  169.             hModule = IntPtr.Zero;  
  170.  
  171.    
  172.  
  173.             farProc = IntPtr.Zero;  
  174.  
  175.    
  176.  
  177.         }  
  178.  
  179.    
  180.  
  181.    
  182.  
  183.         /// < summary>   
  184.  
  185.    
  186.  
  187.         /// 調用所設定的函數   
  188.  
  189.    
  190.  
  191.         /// < /summary>   
  192.  
  193.    
  194.  
  195.         /// < param name="ObjArray_Parameter"> 實參 < /param>   
  196.  
  197.    
  198.  
  199.         /// < param name="TypeArray_ParameterType"> 實參類型 < /param>   
  200.  
  201.    
  202.  
  203.         /// < param name="ModePassArray_Parameter"> 實參傳送方式 < /param>   
  204.  
  205.    
  206.  
  207.         /// < param name="Type_Return"> 返回類型 < /param>   
  208.  
  209.    
  210.  
  211.         /// < returns> 返回所調用函數的 object< /returns>   
  212.  
  213.    
  214.  
  215.         public object Invoke(object[] ObjArray_Parameter, Type[] TypeArray_ParameterType, ModePass[] ModePassArray_Parameter, Type Type_Return)  
  216.  
  217.         {  
  218.  
  219.    
  220.  
  221.             // 下面 3 個 if 是進行安全檢查 , 若不能通過 , 則拋出異常   
  222.  
  223.    
  224.  
  225.             if (hModule == IntPtr.Zero)  
  226.  
  227.    
  228.  
  229.                 throw (new Exception(" 函數庫模塊的句柄為空 , 請確保已進行 LoadDll 操作 !"));  
  230.  
  231.    
  232.  
  233.             if (farProc == IntPtr.Zero)  
  234.  
  235.    
  236.  
  237.                 throw (new Exception(" 函數指針為空 , 請確保已進行 LoadFun 操作 !"));  
  238.  
  239.    
  240.  
  241.             if (ObjArray_Parameter.Length != ModePassArray_Parameter.Length)  
  242.  
  243.    
  244.  
  245.                 throw (new Exception(" 參數個數及其傳遞方式的個數不匹配 ."));  
  246.  
  247.    
  248.  
  249.             // 下面是創建 MyAssemblyName 對象并設置其 Name 屬性   
  250.  
  251.    
  252.  
  253.             AssemblyName MyAssemblyName = new AssemblyName();  
  254.  
  255.    
  256.  
  257.             MyAssemblyName.Name = "InvokeFun";  
  258.  
  259.    
  260.  
  261.             // 生成單模塊配件   
  262.  
  263.    
  264.  
  265.             AssemblyBuilder MyAssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(MyAssemblyName, AssemblyBuilderAccess.Run);  
  266.  
  267.    
  268.  
  269.             ModuleBuilder MyModuleBuilder = MyAssemblyBuilder.DefineDynamicModule("InvokeDll");  
  270.  
  271.    
  272.  
  273.             // 定義要調用的方法 , 方法名為“ MyFun ”,返回類型是“ Type_Return ”參數類型是“ TypeArray_ParameterType ”   
  274.  
  275.    
  276.  
  277.             MethodBuilder MyMethodBuilder = MyModuleBuilder.DefineGlobalMethod("MyFun", MethodAttributes.Public | MethodAttributes.Static, Type_Return, TypeArray_ParameterType);  
  278.  
  279.    
  280.  
  281.             // 獲取一個 ILGenerator ,用于發送所需的 IL   
  282.  
  283.    
  284.  
  285.             ILGenerator IL = MyMethodBuilder.GetILGenerator();  
  286.  
  287.    
  288.  
  289.             int i;  
  290.  
  291.    
  292.  
  293.             for (i = 0; i <  ObjArray_Parameter.Length; i++)  
  294.  
  295.             {// 用循環將參數依次壓入堆棧   
  296.  
  297.    
  298.  
  299.                 switch (ModePassArray_Parameter[i])  
  300.  
  301.                 {  
  302.  
  303.    
  304.  
  305.                     case ModePass.ByValue:  
  306.  
  307.    
  308.  
  309.                         IL.Emit(OpCodes.Ldarg, i);  
  310.  
  311.    
  312.  
  313.                         break;  
  314.  
  315.    
  316.  
  317.                     case ModePass.ByRef:  
  318.  
  319.    
  320.  
  321.                         IL.Emit(OpCodes.Ldarga, i);  
  322.  
  323.    
  324.  
  325.                         break;  
  326.  
  327.    
  328.  
  329.                     default:  
  330.  
  331.    
  332.  
  333.                         throw (new Exception(" 第 " + (i + 1).ToString() + " 個參數沒有給定正確的傳遞方式 ."));  
  334.  
  335.    
  336.  
  337.                 }  
  338.  
  339.    
  340.  
  341.             }  
  342.  
  343.    
  344.  
  345.             if (IntPtr.Size == 4)  
  346.  
  347.             {// 判斷處理器類型   
  348.  
  349.    
  350.  
  351.                 IL.Emit(OpCodes.Ldc_I4, farProc.ToInt32());  
  352.  
  353.    
  354.  
  355.             }  
  356.  
  357.    
  358.  
  359.             else if (IntPtr.Size == 8)  
  360.  
  361.             {  
  362.  
  363.    
  364.  
  365.                 IL.Emit(OpCodes.Ldc_I8, farProc.ToInt64());  
  366.  
  367.    
  368.  
  369.             }  
  370.  
  371.    
  372.  
  373.             else 
  374.  
  375.             {  
  376.  
  377.    
  378.  
  379.                 throw new PlatformNotSupportedException();  
  380.  
  381.    
  382.  
  383.             }  
  384.  
  385.    
  386.  
  387.             IL.EmitCalli(OpCodes.Calli, CallingConvention.StdCall, Type_Return, TypeArray_ParameterType);  
  388.  
  389.    
  390.  
  391.             IL.Emit(OpCodes.Ret); // 返回值   
  392.  
  393.    
  394.  
  395.             MyModuleBuilder.CreateGlobalFunctions();  
  396.  
  397.    
  398.  
  399.             // 取得方法信息   
  400.  
  401.    
  402.  
  403.             MethodInfo MyMethodInfo = MyModuleBuilder.GetMethod("MyFun");  
  404.  
  405.    
  406.  
  407.             return MyMethodInfo.Invoke(null, ObjArray_Parameter);// 調用方法,并返回其值   
  408.  
  409.    
  410.  
  411.         }  
  412.  
  413.     }  
  414.  

2) dld類的使用:

1.打開項目“Test”,向“Form1”窗體中添加一個按鈕,和一個TestBox,Name改為txRet。視圖中雙擊按鈕,在“button1_Click”方法體上面添加代碼,創建一個dld類實例,并進行測試。具體如下:

  1. private void button1_Click(object sender, EventArgs e)  
  2.  
  3.         {  
  4.  
  5.    
  6.  
  7.             int ret = 0;  
  8.  
  9.             dld myDLD = new dld();  
  10.  
  11.    
  12.  
  13.             myDLD.LoadDll("xxx.dll");  
  14.  
  15.    
  16.  
  17.             myDLD.LoadFun("InitSDK");  
  18.  
  19.    
  20.  
  21.             object[] Parameters = new object[] { }; // 實參為0   
  22.  
  23.    
  24.  
  25.             Type[] ParameterTypes = new Type[] { }; // 實參類型為int   
  26.  
  27.    
  28.  
  29.             ModePass[] themode = new ModePass[] { }; // 傳送方式為值傳  
  30.  
  31.    
  32.  
  33.             Type Type_Return = typeof(int); // 返回類型為int  
  34.  
  35.    
  36.  
  37.             ret = (int)myDLD.Invoke(Parameters, ParameterTypes, themode, Type_Return);  
  38.  
  39.             txRet.Text = ret.ToString();  
  40.  
  41.             if (ret != 1)  
  42.  
  43.             {  
  44.  
  45.                 MessageBox.Show("InitSDK failed !");  
  46.  
  47.             }  
  48.  
  49.             if (ret == 1)  
  50.  
  51.             {  
  52.  
  53.                 MessageBox.Show("InitSDK Sucessed !");  
  54.  
  55.             }  
  56.  
  57.         }  
  58.  

其中,xxx為要測試的dll名稱,InitSDK為dll中的要測試的函數。

至此,C#調用DLL函數方法就介紹完了,希望對大家有所幫助。

【編輯推薦】

  1. C#自定義事件步步 通
  2. 如何在C#中使用存儲過程(SQL Server 2000)
  3. 存儲過程自動轉成C#源碼過程
  4. C#事件處理和自定義事件
  5. 通過C#反射特性查看自定義特性
責任編輯:book05 來源: csdn
相關推薦

2009-08-05 09:30:39

C#調用DLL函數

2009-08-07 17:22:36

C#調用dll導出函數

2009-08-03 12:57:27

C#調用DLL

2009-08-05 09:09:14

C#調用VC DLL接

2011-04-08 09:52:44

C++C#DLL

2009-07-31 14:54:48

dll函數C#導出

2009-07-31 17:28:35

C#語言調用DLL

2009-08-05 17:06:39

ASP調用C# DLL

2009-08-07 17:12:07

C# DLL函數

2009-09-02 17:16:01

冒泡排序

2009-08-05 16:41:36

C#調用VC dll

2009-08-05 09:22:43

C#調用VC DLL

2009-08-05 15:04:14

C# dll注入

2009-08-05 16:49:42

C#中調用dll

2009-08-31 18:05:14

C#調用WalkTre

2009-08-31 16:33:28

C#調用Dispose

2009-08-03 13:34:57

C#調用Windows

2009-08-14 09:15:28

C#調用構造函數

2009-08-25 10:59:00

C#調用函數顯示值

2009-07-31 16:12:10

Windows APIC#
點贊
收藏

51CTO技術棧公眾號

亚洲第一成年网| 中文字幕亚洲一区在线观看| 亚洲精品一卡二卡三卡四卡| 欧美绝顶高潮抽搐喷水合集| 欧美伊人久久久久久久久影院| 日韩在线视频在线观看| 欧美在线高清| 91国内免费在线视频| 波多野结衣在线高清| 精品女厕一区二区三区| 亚洲第一狼人区| 高清日韩电视剧大全免费| 精品在线视频一区二区| 精品一区二区三| 欧美噜噜久久久xxx| 丁香花在线电影| 欧美无乱码久久久免费午夜一区| 男女羞羞网站| 不卡的av在线播放| 日韩欧美一区二区三区四区五区| 久久中文亚洲字幕| 久久99精品久久久久久青青91| 98色花堂精品视频在线观看| 欧美午夜影院一区| 樱花在线免费观看| 中文字幕在线观看一区| 国产真人做爰毛片视频直播| 毛片av一区二区三区| 国产一区二区三区黄| 午夜影院欧美| 国产精品最新在线观看| 老牛国内精品亚洲成av人片| 欧美成人激情图片网| 国产精品伦一区二区| 亚洲日韩第一页| gogo亚洲高清大胆美女人体| 精品视频久久久| 中文字幕乱码在线播放| 精品网站999www| 日本免费一区二区三区四区| 日韩久久视频| 国产日本欧洲亚洲| 91视频最新入口| jlzzjlzz亚洲日本少妇| heyzo亚洲| 久久精品一区蜜桃臀影院| 日本久久久精品视频| 国产亚洲一本大道中文在线| 成年人免费在线播放| 国产欧美日本一区视频| 妞干网2018| 午夜精品一区二区三区免费视频 | 国产亚洲精品久| 欧美一级视频免费看| 国产高清亚洲一区| 日韩伦理在线免费观看| 久久久99精品久久| 免费观看视频www| 亚洲一区电影777| 你懂的好爽在线观看| 欧美人妇做爰xxxⅹ性高电影| www在线视频| 亚洲色图五月天| 欧美经典一区| 国产精品r级在线| 在线观看国产精品入口| 欧美日韩国产免费一区二区三区 | 欧美一区2区三区4区公司二百| 99pao成人国产永久免费视频| 青青影院一区二区三区四区| 国产白丝精品91爽爽久久| 国产综合av在线| 亚洲欧美日韩综合aⅴ视频| 日本免费不卡| 日韩成人网免费视频| 亚洲毛片在线免费| 国产精品色婷婷视频| 国产欧美精品| 久久久亚洲国产精品| 亚洲男同1069视频| 麻豆传媒视频在线观看免费| 亚洲欧美日韩网| 五月激激激综合网色播| 国严精品久久久久久亚洲影视| 国产酒店精品激情| 国产美女av| 91精品福利在线一区二区三区 | 男女爱爱视频网站| 99re免费视频精品全部| 桃乃木かなav在线播放| 欧美成人一区二区三区| 国产厕拍一区| 快播亚洲色图| 国产精品美女久久久久aⅴ国产馆| 国产小视频福利在线| 亚洲色图偷窥自拍| 日韩理论电影| 免费视频爱爱太爽了| 疯狂欧美牲乱大交777| 欧美大片免费| 亚洲jizzjizz日本少妇| 成人精品电影在线观看| 六十路在线观看| 欧美成人第一页| 久久精品人人| 男女午夜网站| 精品偷拍各种wc美女嘘嘘| 久久人体视频| 欧美牲交a欧美牲交aⅴ免费真| 欧美丝袜第三区| 精品成人自拍视频| 中文字幕剧情在线观看一区| 亚洲va国产天堂va久久en| 99精品在免费线偷拍| 国产精品国产精品国产专区不卡| 久久蜜桃av一区二区天堂| 麻豆影视国产在线观看| 亲爱的老师9免费观看全集电视剧| 精品中文字幕一区二区| 神马电影在线观看| 欧美激情精品久久久久久大尺度| 日韩精品三区四区| 性欧美孕妇孕交| 久久久欧美一区二区| 久久精品国产亚洲aⅴ | 国产凹凸在线观看一区二区| 在线观看免费黄视频| 全亚洲最色的网站在线观看| 成人激情文学综合网| a级大胆欧美人体大胆666| 99在线首页视频| 亚洲国产精品嫩草影院| 国产精品调教| 日本中文字幕片| 综合欧美国产视频二区| 琪琪一区二区三区| 黄av在线播放| 国内一区二区在线视频观看| 欧美日韩激情小视频| 你懂的一区二区三区| 黄色免费网址大全| 中文字幕视频在线免费欧美日韩综合在线看 | 国产精品一区视频| 亚洲午夜精品17c| а√中文在线天堂精品| 777精品久无码人妻蜜桃| 亚洲免费一在线| 精品一区二区免费| 在线电影福利片| 久久久久资源| 在线不卡a资源高清| 国一区二区在线观看| 亚洲а∨精品天堂在线| 国产精品第2页| 一区二区三区精品| 欧美美乳视频| 精品视频在线播放| 国语自产精品视频在线看抢先版结局| 亚洲国产一区二区三区在线播| 69久久99精品久久久久婷婷| 国内精品久久久久久久影视蜜臀 | wwww国产精品欧美| 成人免费在线观看视频| 欧美黄色免费网址| 国产一区二区三区视频在线观看| 精品一区二区免费视频| av在线加勒比| eeuss中文| 中文字幕精品www乱入免费视频| 国产成人精品影院| 六九午夜精品视频| 精品这里只有精品| 欧美国产日产韩国视频| 综合精品久久久| 国产精品99视频| 黄色大片在线播放| 天天在线免费视频| 欧美精品一区二区免费| 亚洲精品日韩专区silk| 欧美阿v一级看视频| 国产乱妇乱子在线播视频播放网站| 中文精品视频一区二区在线观看| 在线性视频日韩欧美| 日韩码欧中文字| 黑丝一区二区三区| 草草视频在线| 中文字幕在线观看第三页| 国产美女精彩久久| 欧美日韩免费不卡视频一区二区三区| 亚洲先锋成人| 在线观看涩涩| 美女av在线免费观看| 动漫精品视频| 亚洲美女激情视频| 日韩理论片中文av| 亚洲欧美日韩精品一区二区 | 69av在线视频| 狠狠色狠色综合曰曰| 蜜桃在线一区二区三区| 亚洲一区二区免费在线观看|