最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c#的dllimport使用方法詳解

 更新時(shí)間:2014年01月29日 10:06:29   作者:  
DllImport是System.Runtime.InteropServices命名空間下的一個(gè)屬性類,其功能是提供從非托管DLL導(dǎo)出的函數(shù)的必要調(diào)用信息

DllImport是System.Runtime.InteropServices命名空間下的一個(gè)屬性類,其功能是提供從非托管DLL導(dǎo)出的函數(shù)的必要調(diào)用信息

DllImport屬性應(yīng)用于方法,要求最少要提供包含入口點(diǎn)的dll的名稱。
DllImport的定義如下:

復(fù)制代碼 代碼如下:

[AttributeUsage(AttributeTargets.Method)]
public class DllImportAttribute: System.Attribute
{
public DllImportAttribute(string dllName) {…} //定位參數(shù)為dllName
public CallingConvention CallingConvention; //入口點(diǎn)調(diào)用約定
public CharSet CharSet;                                   //入口點(diǎn)采用的字符接
public string EntryPoint;  //入口點(diǎn)名稱
public bool ExactSpelling;   //是否必須與指示的入口點(diǎn)拼寫完全一致,默認(rèn)false
public bool PreserveSig;  //方法的簽名是被保留還是被轉(zhuǎn)換
public bool SetLastError;  //FindLastError方法的返回值保存在這里
public string Value { get {…} }
}

用法示例:

復(fù)制代碼 代碼如下:

[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section,string key,string val,string filePath);

以上是用來寫入ini文件的一個(gè)win32api。          用此方式調(diào)用Win32API的數(shù)據(jù)類型對(duì)應(yīng):DWORD=int或uint,BOOL=bool,預(yù)定義常量=enum,結(jié)構(gòu)=struct。 

DllImport會(huì)按照順序自動(dòng)去尋找的地方: 1、exe所在目錄 2、System32目錄 3、環(huán)境變量目錄所以只需要你把引用的DLL 拷貝到這三個(gè)目錄下 就可以不用寫路徑了 或者可以這樣server.MapPath(.\bin\*.dll)web中的,同時(shí)也是應(yīng)用程序中的 后來發(fā)現(xiàn)用[DllImport(@"C:\OJ\Bin\Judge.dll")]這樣指定DLL的絕對(duì)路徑就可以正常裝載。 這個(gè)問題最常出現(xiàn)在使用第三方非托管DLL組件的時(shí)候,我的也同樣是這時(shí)出的問題,Asp.Net Team的官方解決方案如下: 首先需要確認(rèn)你引用了哪些組件,那些是托管的,哪些是非托管的.托管的很好辦,直接被使用的需要引用,間接使用的需要拷貝到bin目錄下.非托管的處理會(huì)比較麻煩.實(shí)際上,你拷貝到bin沒有任何幫助,因?yàn)镃LR會(huì)把文件拷貝到一個(gè)臨時(shí)目錄下,然后在那運(yùn)行web,而CLR只會(huì)拷貝托管文件,這就是為什么我們明明把非托管的dll放在了bin下卻依然提示不能加載模塊了.  具體做法如下:  首先我們?cè)诜?wù)器上隨便找個(gè)地方新建一個(gè)目錄,假如為C:\DLL  然后,在環(huán)境變量中,給Path變量添加這個(gè)目錄  最后,把所有的非托管文件都拷貝到C:\DLL中.  或者更干脆的把DLL放到system32目錄  對(duì)于可以自己部署的應(yīng)用程序,這樣未償不是一個(gè)解決辦法,然而,如果我們用的是虛擬空間,我們是沒辦法把注冊(cè)PATH變量或者把我們自己的DLL拷到system32目錄的。同時(shí)我們也不一定知道我們的Dll的物理路徑?! llImport里面只能用字符串常量,而不能夠用Server.MapPath(@"~/Bin/Judge.dll")來確定物理路徑。ASP.NET中要使用DllImport的,必須在先“using System.Runtime.InteropServices;”不過,我發(fā)現(xiàn),調(diào)用這種"非托管Dll”相當(dāng)?shù)穆?,可能是因?yàn)槲业姆椒ㄐ枰h(yuǎn)程驗(yàn)證吧,但是實(shí)在是太慢了。經(jīng)過一翻研究,終于想到了一個(gè)完美的解決辦法首先我們用

復(fù)制代碼 代碼如下:

[DllImport("kernel32.dll")]
private extern static IntPtr LoadLibrary(String path);

[DllImport("kernel32.dll")]
private extern static IntPtr GetProcAddress(IntPtr lib, String funcName);

[DllImport("kernel32.dll")]
private extern static bool FreeLibrary(IntPtr lib);

分別取得了LoadLibrary和GetProcAddress函數(shù)的地址,再通過這兩個(gè)函數(shù)來取得我們的DLL里面的函數(shù)。
我們可以先用Server.MapPath(@"~/Bin/Judge.dll")來取得我們的DLL的物理路徑,然后再用LoadLibrary進(jìn)行載入,最后用GetProcAddress取得要用的函數(shù)地址

以下自定義類的代碼完成LoadLibrary的裝載和函數(shù)調(diào)用

復(fù)制代碼 代碼如下:

public class DllInvoke
    {           
        [DllImport("kernel32.dll")]
        private extern static IntPtr LoadLibrary(String path);

        [DllImport("kernel32.dll")]  
        private extern static IntPtr GetProcAddress(IntPtr lib, String funcName);

        [DllImport("kernel32.dll")]    
        private extern static bool FreeLibrary(IntPtr lib);    

        private IntPtr hLib;  

        public DllInvoke(String DLLPath)  
        {          
            hLib = LoadLibrary(DLLPath); 
        }      

        ~DllInvoke()    
        {       
            FreeLibrary(hLib); 
        }       

        //將要執(zhí)行的函數(shù)轉(zhuǎn)換為委托 
        public Delegate Invoke(String APIName,Type t)    
        {          
            IntPtr api = GetProcAddress(hLib, APIName);  
            return (Delegate)Marshal.GetDelegateForFunctionPointer(api,t);    
        }
    }

下面代碼進(jìn)行調(diào)用

復(fù)制代碼 代碼如下:

public delegate int Compile(String command, StringBuilder inf);
            //編譯
            DllInvoke dll = new DllInvoke(Server.MapPath(@"~/Bin/Judge.dll"));
            Compile compile = (Compile)dll.Invoke("Compile", typeof(Compile));
            StringBuilder inf;
            compile(@“gcc a.c -o a.exe“,inf);//這里就是調(diào)用我的DLL里定義的Compile函數(shù)

大家在實(shí)際工作學(xué)習(xí)C#的時(shí)候,可能會(huì)問:為什么我們要為一些已經(jīng)存在的功能(比如Windows中的一些功能,C++中已經(jīng)編寫好的一些方法)要重新編寫代碼,C#有沒有方法可以直接都用這些原本已經(jīng)存在的功能呢?答案是肯定的,大家可以通過C#中的DllImport直接調(diào)用這些功能。   
DllImport所在的名字空間 using System.Runtime.InteropServices;   
MSDN中對(duì)DllImportAttribute的解釋是這樣的:可將該屬性應(yīng)用于方法。DllImportAttribute 屬性提供對(duì)從非托管 DLL
導(dǎo)出的函數(shù)進(jìn)行調(diào)用所必需的信息。作為最低要求,必須提供包含入口點(diǎn)的 DLL 的名稱。    DllImport 屬性定義如下:

復(fù)制代碼 代碼如下:

namespace System.Runtime.InteropServices  
 {    
     [AttributeUsage(AttributeTargets.Method)]  
     public class DllImportAttribute: System.Attribute 
     {    
         public DllImportAttribute(string dllName)
         {...}      

         public CallingConvention CallingConvention;  
         public CharSet CharSet;    
         public string EntryPoint;    
         public bool ExactSpelling;    
         public bool PreserveSig;      
         public bool SetLastError;    
         public string Value { get {...} }    
     }  
 }

說明:    
1、DllImport只能放置在方法聲明上。
2、DllImport具有單個(gè)定位參數(shù):指定包含被導(dǎo)入方法的 dll 名稱的
dllName 參數(shù)。    
3、DllImport具有五個(gè)命名參數(shù): 
a、CallingConvention
參數(shù)指示入口點(diǎn)的調(diào)用約定。如果未指定 CallingConvention,則使用默認(rèn)值
CallingConvention.Winapi。
b、CharSet 參數(shù)指示用在入口點(diǎn)中的字符集。如果未指定 CharSet,則使用默認(rèn)值
CharSet.Auto。       
c、EntryPoint 參數(shù)給出 dll 中入口點(diǎn)的名稱。如果未指定
EntryPoint,則使用方法本身的名稱。         
d、ExactSpelling 參數(shù)指示 EntryPoint
是否必須與指示的入口點(diǎn)的拼寫完全匹配。如果未指定 ExactSpelling,則使用默認(rèn)值 false。         
e、PreserveSig
參數(shù)指示方法的簽名應(yīng)當(dāng)被保留還是被轉(zhuǎn)換。當(dāng)簽名被轉(zhuǎn)換時(shí),它被轉(zhuǎn)換為一個(gè)具有 HRESULT返回值和該返回值的一個(gè)名為 retval
的附加輸出參數(shù)的簽名。如果未指定 PreserveSig,則使用默認(rèn)值 true。         
f、SetLastError 參數(shù)指示方法是否保留
Win32"上一錯(cuò)誤"。如果未指定 SetLastError,則使用默認(rèn)值 false。       
4、它是一次性屬性類。     
  
5、此外,用 DllImport 屬性修飾的方法必須具有 extern 修飾符。

相關(guān)文章

  • C#從windows剪貼板獲取并顯示文本內(nèi)容的方法

    C#從windows剪貼板獲取并顯示文本內(nèi)容的方法

    這篇文章主要介紹了C#從windows剪貼板獲取并顯示文本內(nèi)容的方法,涉及C#操作剪貼板的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • C#中截取字符串的的基本方法詳解

    C#中截取字符串的的基本方法詳解

    這篇文章主要介紹了C#中截取字符串的的基本方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • C#使用TimeSpan對(duì)象實(shí)現(xiàn)獲取時(shí)間間隔

    C#使用TimeSpan對(duì)象實(shí)現(xiàn)獲取時(shí)間間隔

    TimeSpan對(duì)象代表兩個(gè)時(shí)間段的間隔或跨度,使用TimeSpan對(duì)象可以方便地獲取兩個(gè)時(shí)間段的間隔,下面我們就來看看C#使用TimeSpan對(duì)象實(shí)現(xiàn)獲取時(shí)間間隔的具體操作吧
    2024-01-01
  • C#使用dynamic一行代碼實(shí)現(xiàn)反射操作

    C#使用dynamic一行代碼實(shí)現(xiàn)反射操作

    dynamic的出現(xiàn)讓C#具有了弱語言類型的特性。編譯器在編譯的時(shí)候不再對(duì)類型進(jìn)行檢查,編譯時(shí)默認(rèn)dynamic對(duì)象支持你想要的任何特性,這篇文章主要介紹了C#用dynamic一行代碼實(shí)現(xiàn)反射操作,需要的朋友可以參考下
    2023-04-04
  • C#中FlagsAttribute屬性在enum中的應(yīng)用詳解

    C#中FlagsAttribute屬性在enum中的應(yīng)用詳解

    這篇文章主要介紹了C#中FlagsAttribute屬性在enum中的應(yīng)用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • C#文件下載實(shí)例代碼(適用于各個(gè)瀏覽器)

    C#文件下載實(shí)例代碼(適用于各個(gè)瀏覽器)

    本文給大家分享一段實(shí)例代碼關(guān)于css實(shí)現(xiàn)文件下載功能,需要的的朋友參考下吧
    2017-05-05
  • C#關(guān)于Func和Action委托的介紹詳解

    C#關(guān)于Func和Action委托的介紹詳解

    委托是存有對(duì)某個(gè)方法的引用的一種引用類型變量,本文主要介紹了C#關(guān)于Func和Action委托的介紹,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C#程序中session的基本設(shè)置示例及清除session的方法

    C#程序中session的基本設(shè)置示例及清除session的方法

    這篇文章主要介紹了C#程序中session的基本設(shè)置示例及清除session的方法,是C#入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2016-04-04
  • C#利用遞歸算法解決漢諾塔問題

    C#利用遞歸算法解決漢諾塔問題

    這篇文章主要為大家介紹了C#如何利用遞歸算法解決經(jīng)典的漢諾塔問題,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C#有一定幫助,需要的可以參考一下
    2022-04-04
  • C#實(shí)現(xiàn)數(shù)組元素的數(shù)據(jù)類型轉(zhuǎn)換方法詳解

    C#實(shí)現(xiàn)數(shù)組元素的數(shù)據(jù)類型轉(zhuǎn)換方法詳解

    這篇文章主要為大家介紹了C#中一維數(shù)組如何快速實(shí)現(xiàn)數(shù)組元素的數(shù)據(jù)類型的轉(zhuǎn)換,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-04-04

最新評(píng)論

夏邑县| 卫辉市| 惠安县| 巫山县| 廉江市| 巴林左旗| 平邑县| 神木县| 文水县| 汾西县| 高邮市| 肥东县| 蒙阴县| 青浦区| 武清区| 左权县| 都安| 工布江达县| 扎囊县| 灵台县| 汉源县| 石城县| 大庆市| 康乐县| 湘乡市| 武川县| 开江县| 乳山市| 绥化市| 措美县| 色达县| 星子县| 泽普县| 神农架林区| 文登市| 和田县| 全南县| 遵义市| 濉溪县| 正安县| 门源|