国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
C#中DllImport用法和路徑問(wèn)題

DllImport是System.Runtime.InteropServices命名空間下的一個(gè)屬性類(lèi),其功能是提供從非托管DLL導(dǎo)出的函數(shù)的必要調(diào)用信息。
    DllImport屬性應(yīng)用于方法,要求最少要提供包含入口點(diǎn)的dll的名稱(chēng)。
    DllImport的定義如下:
[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)名稱(chēng)
      public bool ExactSpelling;                              //是否必須與指示的入口點(diǎn)拼寫(xiě)完全一致,默認(rèn)false
      public bool PreserveSig;                                 //方法的簽名是被保留還是被轉(zhuǎn)換
      public bool SetLastError;                                 //FindLastError方法的返回值保存在這里
      public string Value { get {…} }
     }
    用法示例:
    [DllImport("kernel32")]
    private static extern long WritePrivateProfileString(stringsection,string key,string val,string filePath);
    以上是用來(lái)寫(xiě)入ini文件的一個(gè)win32api。
    
   用此方式調(diào)用Win32API的數(shù)據(jù)類(lèi)型對(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è)目錄下 就可以不用寫(xiě)路徑了 
或者可以這樣
server.MapPath(.\bin\*.dll)web中的,同時(shí)也是應(yīng)用程序中的后來(lái)發(fā)現(xiàn)用[DllImport(@"C:\OJ\Bin\Judge.dll")]這樣指定DLL的絕對(duì)路徑就可以正常裝載。這個(gè)問(wèn)題最常出現(xiàn)在使用第三方非托管DLL組件的時(shí)候,我的也同樣是這時(shí)出的問(wèn)題,Asp.Net Team的官方解決方案如下:首先需要確認(rèn)你引用了哪些組件,那些是托管的,哪些是非托管的.托管的很好辦,直接被使用的需要引用,間接使用的需要拷貝到bin目錄下.非托管的處理會(huì)比較麻煩.實(shí)際上,你拷貝到bin沒(méi)有任何幫助,因?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è)解決辦法,然而,如果我們用的是虛擬空間,我們是沒(méi)辦法把注冊(cè)PATH變量或者把我們自己的DLL拷到system32目錄的。同時(shí)我們也不一定知道我們的Dll的物理路徑。DllImport里面只能用字符串常量,而不能夠用Server.MapPath(@"~/Bin/Judge.dll")來(lái)確定物理路徑。ASP.NET中要使用DllImport的,必須在先“using System.Runtime.InteropServices;”不過(guò),我發(fā)現(xiàn),調(diào)用這種"非托管Dll”相當(dāng)?shù)穆?,可能是因?yàn)槲业姆椒ㄐ枰h(yuǎn)程驗(yàn)證吧,但是實(shí)在是太慢了。經(jīng)過(guò)一翻研究,終于想到了一個(gè)完美的解決辦法首先我們用[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ù)的地址,再通過(guò)這兩個(gè)函數(shù)來(lái)取得我們的DLL里面的函數(shù)。我們可以先用Server.MapPath(@"~/Bin/Judge.dll")來(lái)取得我們的DLL的物理路徑,然后再用LoadLibrary進(jìn)行載入,最后用GetProcAddress取得要用的函數(shù)地址以下自定義類(lèi)的代碼完成LoadLibrary的裝載和函數(shù)調(diào)用: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)用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ì)問(wèn):為什么我們要為一些已經(jīng)存在的功能(比如Windows中的一些功能,C++中已經(jīng)編寫(xiě)好的一些方法)要重新編寫(xiě)代碼,C#有沒(méi)有方法可以直接都用這些原本已經(jīng)存在的功能呢?答案是肯定的,大家可以通過(guò)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 的名稱(chēng)。    DllImport 屬性定義如下:     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 {...} }    }   }        說(shuō)明:        1、DllImport只能放置在方法聲明上。       2、DllImport具有單個(gè)定位參數(shù):指定包含被導(dǎo)入方法的 dll 名稱(chēng)的 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)的名稱(chēng)。如果未指定 EntryPoint,則使用方法本身的名稱(chēng)。         d、ExactSpelling 參數(shù)指示 EntryPoint 是否必須與指示的入口點(diǎn)的拼寫(xiě)完全匹配。如果未指定 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、它是一次性屬性類(lèi)。        5、此外,用 DllImport 屬性修飾的方法必須具有 extern 修飾符。    DllImport的用法:       DllImport("MyDllImport.dll")]
       private static extern int mySum(int a,int b);
一 在C#程序設(shè)計(jì)中使用Win32類(lèi)庫(kù)
 常用對(duì)應(yīng)類(lèi)型:1、DWORD 是 4 字節(jié)的整數(shù),因此我們可以使用 int 或 uint 作為 C# 對(duì)應(yīng)類(lèi)型。2、bool 類(lèi)型與 BOOL 對(duì)應(yīng)。示例一:調(diào)用 Beep() API 來(lái)發(fā)出聲音    Beep() 是在 kernel32.lib 中定義的,在MSDN 中的定義,Beep具有以下原型:    BOOL Beep(DWORD dwFreq, // 聲音頻率                           DWORD dwDuration // 聲音持續(xù)時(shí)間); 用 C# 編寫(xiě)以下原型:[DllImport("kernel32.dll")] public static extern bool Beep(int frequency, int duration);示例二:枚舉類(lèi)型和常量    MessageBeep() 是在 user32.lib 中定義的,在MSDN 中的定義,MessageBeep具有以下原型:    BOOL MessageBeep(UINT uType // 聲音類(lèi)型                                           ); 用C#編寫(xiě)一下原型:public enum BeepType{SimpleBeep = -1,IconAsterisk = 0x00000040,IconExclamation = 0x00000030,IconHand = 0x00000010,IconQuestion = 0x00000020,Ok = 0x00000000,}uType 參數(shù)實(shí)際上接受一組預(yù)先定義的常量,對(duì)于 uType 參數(shù),使用 enum 類(lèi)型是合乎情理的。[DllImport("user32.dll")]public static extern bool MessageBeep(BeepType beepType);  示例三:處理結(jié)構(gòu)    有時(shí)我需要確定我筆記本的電池狀況。Win32 為此提供了電源管理函數(shù),搜索 MSDN 可以找到GetSystemPowerStatus() 函數(shù)。    BOOL GetSystemPowerStatus(                                                         LPSYSTEM_POWER_STATUS lpSystemPowerStatus                                                            );    此函數(shù)包含指向某個(gè)結(jié)構(gòu)的指針,我們尚未對(duì)此進(jìn)行過(guò)處理。要處理結(jié)構(gòu),我們需要用 C# 定義結(jié)構(gòu)。我們從非托管的定義開(kāi)始:typedef struct _SYSTEM_POWER_STATUS {BYTE  ACLineStatus;BYTE  BatteryFlag;BYTE  BatteryLifePercent;BYTE  Reserved1;DWORD BatteryLifeTime;DWORD BatteryFullLifeTime;} SYSTEM_POWER_STATUS, *LPSYSTEM_POWER_STATUS;然后,通過(guò)用 C# 類(lèi)型代替 C 類(lèi)型來(lái)得到 C# 版本。struct SystemPowerStatus{byte ACLineStatus;byte batteryFlag;byte batteryLifePercent;byte reserved1;int batteryLifeTime;int batteryFullLifeTime;}    這樣,就可以方便地編寫(xiě)出 C# 原型:    [DllImport("kernel32.dll")]    public static extern bool GetSystemPowerStatus(ref SystemPowerStatus systemPowerStatus);在此原型中,我們用“ref”指明將傳遞結(jié)構(gòu)指針而不是結(jié)構(gòu)值。這是處理通過(guò)指針傳遞的結(jié)構(gòu)的一般方法。此函數(shù)運(yùn)行良好,但是最好將 ACLineStatus 和 batteryFlag 字段定義為 enum:enum ACLineStatus: byte{Offline = 0,Online = 1,Unknown = 255,}enum BatteryFlag: byte{High = 1,Low = 2,Critical = 4,Charging = 8,NoSystemBattery = 128,Unknown = 255,}請(qǐng)注意,由于結(jié)構(gòu)的字段是一些字節(jié),因此我們使用 byte 作為該 enum 的基本類(lèi)型示例四:處理字符串二 C# 中調(diào)用C++代碼    int 類(lèi)型[DllImport(“MyDLL.dll")]//返回個(gè)int 類(lèi)型public static extern int mySum (int a1,int b1);//DLL中申明extern “C” __declspec(dllexport)  int WINAPI mySum(int a2,int b2){ //a2 b2不能改變a1 b1//a2=..//b2=... return a+b;}

//參數(shù)傳遞int 類(lèi)型
public static extern int mySum (ref int a1,ref int b1);
//DLL中申明
extern “C” __declspec(dllexport)  int WINAPI mySum(int *a2,int *b2)

//可以改變 a1, b1
*a2=...
*b2=...
 return a+b;
}


DLL 需傳入char *類(lèi)型
[DllImport(“MyDLL.dll")] 
//傳入值
public static extern int mySum (string  astr1,string bstr1);
//DLL中申明
extern “C” __declspec(dllexport)  int WINAPI mySum(char * astr2,char *bstr2)
{
//改變astr2 bstr 2  ,astr1 bstr1不會(huì)被改變
 return a+b;
}


DLL 需傳出char *類(lèi)型
[DllImport(“MyDLL.dll")]
// 傳出值
public static extern int mySum (StringBuilder abuf, StringBuilder bbuf);
//DLL中申明
extern “C” __declspec(dllexport)  int WINAPI mySum(char * astr,char *bstr)
{
//傳出char * 改變astr bstr -->abuf, bbuf可以被改變
 return a+b;
}
 
DLL 回調(diào)函數(shù)

BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)



using System;
using System.Runtime.InteropServices;
public delegate bool CallBack(int hwnd, int lParam); //定義委托函數(shù)類(lèi)型
public class EnumReportApp
{
[DllImport("user32")]
public static extern int EnumWindows(CallBack x, int y);
public static void Main() {
CallBack myCallBack = new CallBack(EnumReportApp.Report);EnumWindows(myCallBack, 0);
}
public static bool Report(int hwnd, int lParam)
{
Console.Write("Window handle is ");
Console.WriteLine(hwnd); return true;
}
}
 

DLL  傳遞結(jié)構(gòu) 
BOOL PtInRect(const RECT *lprc, POINT pt);

using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct Point {
 public int x;
public int y;
 }
[StructLayout(LayoutKind.Explicit)]
 public struct Rect
 {
[FieldOffset(0)] public int left;
[FieldOffset(4)] public int top;
[FieldOffset(8)] public int right;
[FieldOffset(12)] public int bottom;
 }
Class XXXX {
 [DllImport("User32.dll")]
public static extern bool PtInRect(ref  Rect r, Point p);
 }

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
計(jì)算機(jī)世界網(wǎng)-用Visual C#調(diào)用Windows API函數(shù)
C#DllImport的用法
[C#/C ]C#調(diào)用非托管DLL的APIs - .NET人字拖 - 博客園
C#調(diào)用windows API的一些方法
C#_對(duì)內(nèi)存的操作
C#調(diào)用C dll
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服