• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            為生存而奔跑

               :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
              271 Posts :: 0 Stories :: 58 Comments :: 0 Trackbacks

            留言簿(5)

            我參與的團隊

            搜索

            •  

            積分與排名

            • 積分 - 326993
            • 排名 - 74

            最新評論

            閱讀排行榜

            評論排行榜

             大家在實際工作學習C#的時候,可能會問:為什么我們要為一些已經(jīng)存在的功能(比如Windows中的一些功能,C++中已經(jīng)編寫好的一些方法)要重新編寫代碼,C#有沒有方法可以直接都用這些原本已經(jīng)存在的功能呢?答案是肯定的,大家可以通過C#中的DllImport直接調(diào)用這些功能。
                DllImport所在的名字空間 using System.Runtime.InteropServices;
                MSDN中對DllImportAttribute的解釋是這樣的:可將該屬性應用于方法。DllImportAttribute 屬性提供對從非托管 DLL 導出的函數(shù)進行調(diào)用所必需的信息。作為最低要求,必須提供包含入口點的 DLL 的名稱
                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 {...} } 
                } 
              }    
                說明:    
                1、DllImport只能放置在方法聲明上。   
                2、DllImport具有單個定位參數(shù):指定包含被導入方法的 dll 名稱的 dllName 參數(shù)。   
                3、DllImport具有五個命名參數(shù):    
                 a、CallingConvention 參數(shù)指示入口點的調(diào)用約定。如果未指定 CallingConvention,則使用默認值 CallingConvention.Winapi。    
                 b、CharSet 參數(shù)指示用在入口點中的字符集。如果未指定 CharSet,則使用默認值 CharSet.Auto。   
                 c、EntryPoint 參數(shù)給出 dll 中入口點的名稱。如果未指定 EntryPoint,則使用方法本身的名稱。    
                 d、ExactSpelling 參數(shù)指示 EntryPoint 是否必須與指示的入口點的拼寫完全匹配。如果未指定 ExactSpelling,則使用默認值 false。    
                 e、PreserveSig 參數(shù)指示方法的簽名應當被保留還是被轉(zhuǎn)換。當簽名被轉(zhuǎn)換時,它被轉(zhuǎn)換為一個具有 HRESULT 返回值和該返回值的一個名為 retval 的附加輸出參數(shù)的簽名。如果未指定 PreserveSig,則使用默認值 true。    
                 f、SetLastError 參數(shù)指示方法是否保留 Win32"上一錯誤"。如果未指定 SetLastError,則使用默認值 false。    
                4、它是一次性屬性類。    
                5、此外,用 DllImport 屬性修飾的方法必須具有 extern 修飾符。

                DllImport的用法:
                   DllImport("MyDllImport.dll")]
                   private static extern int mySum(int a,int b);

            一 在C#程序設計中使用Win32類庫
             常用對應類型:
            1、DWORD 是 4 字節(jié)的整數(shù),因此我們可以使用 int 或 uint 作為 C# 對應類型。
            2、bool 類型與 BOOL 對應。

            示例一:調(diào)用 Beep() API 來發(fā)出聲音
                Beep() 是在 kernel32.lib 中定義的,在MSDN 中的定義,Beep具有以下原型:
                BOOL Beep(DWORD dwFreq, // 聲音頻率 
                                       DWORD dwDuration // 聲音持續(xù)時間); 
            用 C# 編寫以下原型:
            [DllImport("kernel32.dll")] 
            public static extern bool Beep(int frequency, int duration);

            示例二:枚舉類型和常量
                MessageBeep() 是在 user32.lib 中定義的,在MSDN 中的定義,MessageBeep具有以下原型:
                BOOL MessageBeep(UINT uType // 聲音類型
                                                       ); 

            用C#編寫一下原型:
            public enum BeepType
            {
              SimpleBeep = -1,
              IconAsterisk = 0x00000040,
              IconExclamation = 0x00000030,
              IconHand = 0x00000010,
              IconQuestion = 0x00000020,
              Ok = 0x00000000,

            uType 參數(shù)實際上接受一組預先定義的常量,對于 uType 參數(shù),使用 enum 類型是合乎情理的。
            [DllImport("user32.dll")]
            public static extern bool MessageBeep(BeepType beepType);  

            示例三:處理結(jié)構(gòu)
                有時我需要確定我筆記本的電池狀況。Win32 為此提供了電源管理函數(shù),搜索 MSDN 可以找到GetSystemPowerStatus() 函數(shù)。 
                BOOL GetSystemPowerStatus( 
                                                                      LPSYSTEM_POWER_STATUS lpSystemPowerStatus 
                                                                        );
                此函數(shù)包含指向某個結(jié)構(gòu)的指針,我們尚未對此進行過處理。要處理結(jié)構(gòu),我們需要用 C# 定義結(jié)構(gòu)。我們從非托管的定義開始: 
            typedef struct _SYSTEM_POWER_STATUS { 
            BYTE  ACLineStatus; 
            BYTE  BatteryFlag; 
            BYTE  BatteryLifePercent; 
            BYTE  Reserved1; 
            DWORD BatteryLifeTime; 
            DWORD BatteryFullLifeTime; 
            } SYSTEM_POWER_STATUS, *LPSYSTEM_POWER_STATUS; 
               然后,通過用 C# 類型代替 C 類型來得到 C# 版本。 
            struct SystemPowerStatus 

              byte ACLineStatus; 
              byte batteryFlag; 
              byte batteryLifePercent; 
              byte reserved1; 
              int batteryLifeTime; 
              int batteryFullLifeTime; 

                這樣,就可以方便地編寫出 C# 原型: 
                [DllImport("kernel32.dll")] 
                public static extern bool GetSystemPowerStatus( 
              ref SystemPowerStatus systemPowerStatus); 
               在此原型中,我們用“ref”指明將傳遞結(jié)構(gòu)指針而不是結(jié)構(gòu)值。這是處理通過指針傳遞的結(jié)構(gòu)的一般方法。 
               此函數(shù)運行良好,但是最好將 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, 
               } 
            請注意,由于結(jié)構(gòu)的字段是一些字節(jié),因此我們使用 byte 作為該 enum 的基本類型

            示例四:處理字符串


            二 C# 中調(diào)用C++代碼
                int 類型 
            [DllImport(“MyDLL.dll")] 
            //返回個int 類型 
            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 類型 
            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 *類型 
            [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不會被改變
             return a+b; 
            }


            DLL 需傳出char *類型 
            [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ù)類型 
            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); 
             }

            posted on 2009-12-20 14:28 baby-fly 閱讀(324) 評論(0)  編輯 收藏 引用 所屬分類: C#
            久久精品视频一| 久久精品无码一区二区WWW| 亚洲欧美一级久久精品| 精品久久久久久无码人妻热| 国产精品久久亚洲不卡动漫| 久久99国产精品尤物| 国产成人久久AV免费| 国内精品久久久久影院免费| 久久美女人爽女人爽| 国产激情久久久久影院小草| 久久精品国产亚洲Aⅴ蜜臀色欲| 99久久精品九九亚洲精品| 久久99热精品| 久久这里只有精品视频99| 亚洲а∨天堂久久精品| 99精品久久久久久久婷婷| 无码久久精品国产亚洲Av影片 | 国产精品女同一区二区久久| 久久亚洲国产中v天仙www| 久久强奷乱码老熟女| 久久热这里只有精品在线观看| 精品无码久久久久久尤物| 久久综合九色综合欧美狠狠| 久久久国产一区二区三区| 久久久久se色偷偷亚洲精品av | 久久久久久久91精品免费观看| 久久中文字幕人妻熟av女| 国产精品久久久久影视不卡| 欧美伊人久久大香线蕉综合69| 嫩草伊人久久精品少妇AV| 亚洲国产成人久久精品影视| 久久福利资源国产精品999| 99久久人妻无码精品系列蜜桃| 成人a毛片久久免费播放| 亚洲午夜久久久久久久久电影网| 久久久中文字幕| 色婷婷综合久久久久中文一区二区 | 久久一日本道色综合久久| 国产精品成人精品久久久| 久久人人爽人人爽人人片AV不 | 久久午夜无码鲁丝片|