æå¨èªå·±æè¿çç¼ç¨ä¸æ³¨æå°ä¸ä¸ªè¶å¿ï¼æ£æ¯è¿ä¸ªè¶å¿æå¼åºæ¬æçä¸æ 主é¢ãæè¿ï¼æå¨åºäºMicrosoft.NETFrameworkçåºç¨ç¨åºä¸å®æäºå¤§éçWin32Interopãæ并ä¸æ¯è¦è¯´æçåºç¨ç¨åºå 满äºèªå®ä¹çinterop代ç ï¼ä½ææ¶æä¼å¨.NETFrameworkç±»åºä¸ç¢°å°ä¸äºæ¬¡è¦ä½åç¹çµ®ãä¸å åçå 容ï¼éè¿è°ç¨è¯¥WindowsAPIï¼å¯ä»¥å¿«éåå°è¿æ ·ç麻ç¦ã
ããå æ¤æ认为ï¼.NETFramework1.0æ1.1çç±»åºä¸åå¨ä»»ä½Windowsæ没æçåè½*é½ä¸è¶³ä¸ºæªãæ¯ç«ï¼32ä½çWindowsï¼ä¸ç®¡ä½ç§çæ¬ï¼æ¯ä¸ä¸ªæççæä½ç³»ç»ï¼ä¸ºå¹¿å¤§å®¢æ·æå¡äºåå¤å¹´ãç¸æ¯ä¹ä¸ï¼.NETFrameworkå´æ¯ä¸ä¸ªæ°äºç©ã
ããéçè¶æ¥è¶å¤çå¼å人åå°ç产åºç¨ç¨åºè½¬å°æ管代ç ï¼å¼å人åæ´é¢ç¹å°ç 究åºå±æä½ç³»ç»ä»¥å¾æ¾åºä¸äºå ³é®åè½æ¾å¾å¾èªç¶-è³å°ç®åæ¯å¦æ¤ã
ããå¼å¾åºå¹¸çæ¯ï¼å ¬å ±è¯è¨è¿è¡åº(CLR)çinteropåè½ï¼ç§°ä¸ºå¹³å°è°ç¨(P/Invoke)ï¼é常å®åãå¨æ¬ä¸æ ä¸ï¼æå°éç¹ä»ç»å¦ä½å®é 使ç¨P/Invokeæ¥è°ç¨WindowsAPIå½æ°ãå½æCLRçCOMInteropåè½æ¶ï¼P/Invokeå½ä½åè¯ä½¿ç¨ï¼å½æ该åè½ç使ç¨æ¶ï¼åå°å ¶å½ä½å¨è¯ä½¿ç¨ãæ并ä¸æç®ç´æ¥ä»ç»COMInteropï¼å 为å®æ¯P/Invokeå ·ææ´å¥½çå¯è®¿é®æ§ï¼å´æ´å å¤æï¼è¿æç¹èªç¸çç¾ï¼è¿ä½¿å¾å°COMInteropä½ä¸ºä¸æ 主é¢æ¥è®¨è®ºä¸å¤ªç®ææ¼è¦ã
ããè¯ä»-å¨Cä¸éè¿PInvokeè°ç¨Win32DLLã
ããèµ°è¿P/Invokeã
ããé¦å ä»èå¯ä¸ä¸ªç®åçP/Invoke示ä¾å¼å§ã让æ们çä¸çå¦ä½è°ç¨Win32MessageBeepå½æ°ï¼å®çéæ管声æå¦ä»¥ä¸ä»£ç æ示ï¼BOOLMessageBeep(UINTuType//beeptype);ã
ãã为äºè°ç¨MessageBeepï¼æ¨éè¦å¨C#ä¸å°ä»¥ä¸ä»£ç æ·»å å°ä¸ä¸ªç±»æç»æå®ä¹ä¸ï¼[DllImport("User32.dll")]staticexternBooleanMessageBeep(UInt32beepType);ã
ãã令人æ讶çæ¯ï¼åªéè¦è¿æ®µä»£ç å°±å¯ä»¥ä½¿æ管代ç è°ç¨éæ管çMessageBeepAPIãå®ä¸æ¯ä¸ä¸ªæ¹æ³è°ç¨ï¼èæ¯ä¸ä¸ªå¤é¨æ¹æ³å®ä¹ãï¼å¦å¤ï¼å®æ¥è¿äºä¸ä¸ªæ¥èªCèC#å 许çç´æ¥ç«¯å£ï¼å æ¤ä»¥å®ä¸ºèµ·ç¹æ¥ä»ç»ä¸äºæ¦å¿µæ¯æ帮å©çãï¼æ¥èªæ管代ç çå¯è½è°ç¨å¦ä¸æ示ï¼MessageBeep(0);ã
ããè¯ä»-å¨Cä¸éè¿PInvokeè°ç¨Win32DLLã
ãã请注æï¼ç°å¨MessageBeepæ¹æ³è¢«å£°æ为staticãè¿æ¯P/Invokeæ¹æ³æè¦æ±çï¼å 为å¨è¯¥WindowsAPIä¸æ²¡æä¸è´çå®ä¾æ¦å¿µãæ¥ä¸æ¥ï¼è¿è¦æ³¨æ该æ¹æ³è¢«æ 记为externãè¿æ¯æ示ç¼è¯å¨è¯¥æ¹æ³æ¯éè¿ä¸ä¸ªä»DLL导åºçå½æ°å®ç°çï¼å æ¤ä¸éè¦æä¾æ¹æ³ä½ã
ãã说å°ç¼ºå°æ¹æ³ä½ï¼æ¨æ¯å¦æ³¨æå°MessageBeep声æ并没æå å«ä¸ä¸ªæ¹æ³ä½ï¼ä¸å¤§å¤æ°ç®æ³ç±ä¸é´è¯è¨(IL)æ令ç»æçæ管æ¹æ³ä¸åï¼P/Invokeæ¹æ³åªæ¯å æ°æ®ï¼å®æ¶(JIT)ç¼è¯å¨å¨è¿è¡æ¶éè¿å®å°æ管代ç ä¸éæ管çDLLå½æ°è¿æ¥èµ·æ¥ãæ§è¡è¿ç§å°éæ管ä¸ççè¿æ¥æéçä¸ä¸ªéè¦ä¿¡æ¯å°±æ¯å¯¼åºéæ管æ¹æ³çDLLçå称ãè¿ä¸ä¿¡æ¯æ¯ç±MessageBeepæ¹æ³å£°æä¹åçDllImportèªå®ä¹å±æ§æä¾çãå¨æ¬ä¾ä¸ï¼å¯ä»¥çå°ï¼MessageBeepéæ管APIæ¯ç±Windowsä¸çUser32.dll导åºçã
ããå°ç°å¨ä¸ºæ¢ï¼å ³äºè°ç¨MessageBeepå°±å©ä¸¤ä¸ªè¯é¢æ²¡æä»ç»ï¼è¯·å顾ä¸ä¸ï¼è°ç¨ç代ç ä¸ä»¥ä¸æ示代ç ç段é常ç¸ä¼¼ï¼[DllImport("User32.dll")]staticexternBooleanMessageBeep(UInt32beepType);ã
ããæåè¿ä¸¤ä¸ªè¯é¢æ¯ä¸æ°æ®å°éå¤ç(datamarshaling)åä»æ管代ç å°éæ管å½æ°çå®é æ¹æ³è°ç¨æå ³çè¯é¢ãè°ç¨éæ管MessageBeepå½æ°å¯ä»¥ç±æ¾å°ä½ç¨åå çexternMessageBeep声æçä»»ä½æ管代ç æ§è¡ã该è°ç¨ç±»ä¼¼äºä»»ä½å ¶ä»å¯¹éææ¹æ³çè°ç¨ãå®ä¸å ¶ä»ä»»ä½æ管æ¹æ³è°ç¨çå ±åä¹å¤å¨äºå¸¦æ¥äºæ°æ®å°éå¤ççéè¦ã
ããC#çè§åä¹ä¸æ¯å®çè°ç¨è¯æ³åªè½è®¿é®CLRæ°æ®ç±»åï¼ä¾å¦System.UInt32åSystem.BooleanãC#æ¾ç¶ä¸è¯å«WindowsAPIä¸ä½¿ç¨çåºäºCçæ°æ®ç±»åï¼ä¾å¦UINTåBOOLï¼ï¼è¿äºç±»ååªæ¯Cè¯è¨ç±»åçç±»åå®ä¹èå·²ãæ以å½WindowsAPIå½æ°MessageBeepæ以ä¸æ¹å¼ç¼åæ¶BOOLMessageBeep(UINTuType)ã
ããå¤é¨æ¹æ³å°±å¿ 须使ç¨CLRç±»åæ¥å®ä¹ï¼å¦æ¨å¨åé¢ç代ç ç段ä¸æçå°çãéè¦ä½¿ç¨ä¸åºç¡APIå½æ°ç±»åä¸åä½ä¸ä¹å ¼å®¹çCLRç±»åæ¯P/Invokeè¾é¾ä½¿ç¨çä¸ä¸ªæ¹é¢ãå æ¤ï¼å¨æ¬ä¸æ çåé¢æå°ç¨å®æ´çç« èæ¥ä»ç»æ°æ®å°éå¤çã
ããæ ·å¼ã
ããå¨C#ä¸å¯¹WindowsAPIè¿è¡P/Invokeè°ç¨æ¯å¾ç®åçãä½å¦æç±»åºæç»ä½¿æ¨çåºç¨ç¨åºååºå声ï¼åºè¯¥æ³æ¹è®¾æ³è°ç¨Windows使å®è¿è¡è¿é¡¹å·¥ä½ï¼æ¯åï¼ã
ããæ¯çãä½æ¯ä¸éæ©çæ¹æ³æå ³ï¼èä¸å ³ç³»ç大ï¼é常ï¼å¦æç±»åºæä¾æç§éå¾æ¥å®ç°æ¨çæå¾ï¼åæ好使ç¨APIèä¸è¦ç´æ¥è°ç¨éæ管代ç ï¼å 为CLRç±»ååWin32ä¹é´å¨æ ·å¼ä¸æå¾å¤§çä¸åãæå¯ä»¥å°å ³äºè¿ä¸ªé®é¢ç建议å½ç»ä¸ºä¸å¥è¯ãå½æ¨è¿è¡P/Invokeæ¶ï¼ä¸è¦ä½¿åºç¨ç¨åºé»è¾ç´æ¥å±äºä»»ä½å¤é¨æ¹æ³æå ¶ä¸çæ件ãå¦ææ¨éµå¾ªè¿ä¸ªå°è§åï¼ä»é¿è¿çç»å¸¸ä¼çå»è®¸å¤ç麻ç¦ã
ããå¾1ä¸ç代ç æ¾ç¤ºäºææ讨论çMessageBeepå¤é¨æ¹æ³çæå°éå 代ç ãå¾1ä¸å¹¶æ²¡æä»»ä½æ¾èçååï¼èåªæ¯å¯¹æ å è£ çå¤é¨æ¹æ³è¿è¡ä¸äºæ®éçæ¹è¿ï¼è¿å¯ä»¥ä½¿å·¥ä½æ´å è½»æ¾ä¸äºãä»é¡¶é¨å¼å§ï¼æ¨ä¼æ³¨æå°ä¸ä¸ªå为Soundçå®æ´ç±»åï¼å®ä¸ç¨äºMessageBeepãå¦ææéè¦ä½¿ç¨WindowsAPIå½æ°PlaySoundæ¥æ·»å 对ææ¾æ³¢å½¢çæ¯æï¼åå¯ä»¥éç¨Soundç±»åãç¶èï¼æä¸ä¼å å ¬å¼åä¸ªå ¬å ±éææ¹æ³çç±»åèçæ°ãæ¯ç«è¿åªæ¯åºç¨ç¨åºä»£ç èå·²ãè¿åºè¯¥æ³¨æå°ï¼Soundæ¯å¯å°çï¼å¹¶å®ä¹äºä¸ä¸ªç©ºçç§ææé å½æ°ãè¿äºåªæ¯ä¸äºç»èï¼ç®çæ¯ä½¿ç¨æ·ä¸ä¼é误å°ä»Soundæ´¾çç±»æè å建å®çå®ä¾ã
ããå¾1ä¸ç代ç çä¸ä¸ä¸ªç¹å¾æ¯ï¼P/Invokeåºç°ä½ç½®çå®é å¤é¨æ¹æ³æ¯Soundçç§ææ¹æ³ãè¿ä¸ªæ¹æ³åªæ¯ç±å ¬å ±MessageBeepæ¹æ³é´æ¥å ¬å¼ï¼åè æ¥åBeepTypesç±»åçåæ°ãè¿ä¸ªé´æ¥çé¢å¤å±æ¯ä¸ä¸ªå¾å ³é®çç»èï¼å®æä¾äºä»¥ä¸å¥½å¤ãé¦å ï¼åºè¯¥å¨ç±»åºä¸å¼å ¥ä¸ä¸ªæªæ¥çbeepæ管æ¹æ³ï¼å¯ä»¥éå¤å°éè¿å ¬å ±MessageBeepæ¹æ³æ¥ä½¿ç¨æ管APIï¼èä¸å¿ æ´æ¹åºç¨ç¨åºä¸çå ¶ä½ä»£ç ã
ãã该å è£ æ¹æ³ç第äºä¸ªå¥½å¤æ¯ï¼å½æ¨è¿è¡P/Invokeè°ç¨æ¶ï¼æ¨æ¾å¼äºå å访é®å²çªåå ¶ä»ä½çº§ç ´åçæå©ï¼è¿é常æ¯ç±CLRæä¾çãç¼å²æ¹æ³å¯ä»¥ä¿æ¤æ¨çåºç¨ç¨åºçå ¶ä½é¨åå å访é®å²çªå类似é®é¢çå½±åï¼å³ä½¿å®ä¸åä»»ä½äºèåªæ¯ä¼ éåæ°ï¼ã该ç¼å²æ¹æ³å°ç±P/Invokeè°ç¨å¼å ¥çä»»ä½æ½å¨çé误æ¬å°åã
ããå°ç§æå¤é¨æ¹æ³éèå¨å ¬å ±å è£ åé¢ç第ä¸åæ¶ä¹æ¯æåçä¸ä¸ªå¥½å¤æ¯ï¼æä¾äºå该æ¹æ³æ·»å ä¸äºæå°çCLRæ ·å¼çæºä¼ãä¾å¦ï¼å¨å¾1ä¸ï¼æå°WindowsAPIå½æ°è¿åçBoolean失败转æ¢ææ´åCLRçå¼å¸¸ãæè¿å®ä¹äºä¸ä¸ªå为BeepTypesçæ举类åï¼å®çæå对åºäºå该WindowsAPIä¸èµ·ä½¿ç¨çå®ä¹å¼ãç±äºC#ä¸æ¯æå®ä¹ï¼å æ¤å¯ä»¥ä½¿ç¨æ管æ举类åæ¥é¿å å¹»æ°åæ´ä¸ªåºç¨ç¨åºä»£ç æ©æ£ã
ããå è£ æ¹æ³çæåä¸ä¸ªå¥½å¤å¯¹äºç®åçWindowsAPIå½æ°ï¼å¦MessageBeepï¼è¯ç¶æ¯å¾®ä¸è¶³éçãä½æ¯å½æ¨å¼å§è°ç¨æ´å¤æçéæ管å½æ°æ¶ï¼æ¨ä¼åç°ï¼æå¨å°WindowsAPIæ ·å¼è½¬æ¢æ对CLRæ´å å好çæ¹æ³æ带æ¥ç好å¤ä¼è¶æ¥è¶å¤ãè¶æ¯æç®å¨æ´ä¸ªåºç¨ç¨åºä¸éç¨interopåè½ï¼è¶æ¯åºè¯¥è®¤çå°èèå è£ ç设计ãåæ¶æ认为ï¼å¨éé¢å对象çéæå è£ æ¹æ³ä¸ä½¿ç¨å¯¹CLRå好çåæ°ä¹å¹¶éä¸å¯ä»¥ã
ããDLLImportå±æ§ã
ããç°å¨æ¯æ´æ·±å ¥å°è¿è¡æ¢è®¨çæ¶åäºãå¨å¯¹æ管代ç è¿è¡P/Invokeè°ç¨æ¶ï¼DllImportAttributeç±»åæ®æ¼çéè¦çè§è²ãDllImportAttributeç主è¦ä½ç¨æ¯ç»CLRæ示åªä¸ªDLL导åºæ¨æ³è¦è°ç¨çå½æ°ãç¸å ³DLLçå称被ä½ä¸ºä¸ä¸ªæé å½æ°åæ°ä¼ éç»DllImportAttributeã
ããå¦ææ¨æ æ³è¯å®åªä¸ªDLLå®ä¹äºæ¨è¦ä½¿ç¨çWindowsAPIå½æ°ï¼PlatformSDKææ¡£å°ä¸ºæ¨æä¾æ好ç帮å©èµæºãå¨WindowsAPIå½æ°ä¸»é¢æå临è¿ç»å°¾çä½ç½®ï¼SDKææ¡£æå®äºCåºç¨ç¨åºè¦ä½¿ç¨è¯¥å½æ°å¿ é¡»é¾æ¥ç.libæ件ãå¨å ä¹ææçæ åµä¸ï¼è¯¥.libæä»¶å ·æä¸å®ä¹è¯¥å½æ°çç³»ç»DLLæ件ç¸åçå称ãä¾å¦ï¼å¦æ该å½æ°éè¦Cåºç¨ç¨åºé¾æ¥å°Kernel32.libï¼å该å½æ°å°±å®ä¹å¨Kernel32.dllä¸ãæ¨å¯ä»¥å¨MessageBeepä¸æ¾å°æå ³MessageBeepçPlatformSDKæ档主é¢ãå¨è¯¥ä¸»é¢ç»å°¾å¤ï¼æ¨ä¼æ³¨æå°å®æåºåºæ件æ¯User32.libï¼è¿è¡¨æMessageBeepæ¯ä»User32.dllä¸å¯¼åºçã
ããå¯éçDllImportAttributeå±æ§ã
ããé¤äºæåºå®¿ä¸»DLLå¤ï¼DllImportAttributeè¿å å«äºä¸äºå¯éå±æ§ï¼å ¶ä¸å个ç¹å«æ趣ï¼EntryPointãCharSetãSetLastErroråCallingConventionã
ããEntryPointå¨ä¸å¸æå¤é¨æ管æ¹æ³å ·æä¸DLL导åºç¸åçå称çæ åµä¸ï¼å¯ä»¥è®¾ç½®è¯¥å±æ§æ¥æ示导åºçDLLå½æ°çå ¥å£ç¹å称ãå½æ¨å®ä¹ä¸¤ä¸ªè°ç¨ç¸åéæ管å½æ°çå¤é¨æ¹æ³æ¶ï¼è¿ç¹å«æç¨ãå¦å¤ï¼å¨Windowsä¸è¿å¯ä»¥éè¿å®ä»¬çåºå·å¼ç»å®å°å¯¼åºçDLLå½æ°ãå¦ææ¨éè¦è¿æ ·åï¼å诸å¦"#1"æ"#129"çEntryPointå¼æ示DLLä¸éæ管å½æ°çåºå·å¼èä¸æ¯å½æ°åãCharSet对äºå符éï¼å¹¶éææçæ¬çWindowsé½æ¯åæ ·å建çãWindows9xç³»å产å缺å°éè¦çUnicodeæ¯æï¼èWindowsNTåWindowsCEç³»ååä¸å¼å§å°±ä½¿ç¨Unicodeãå¨è¿äºæä½ç³»ç»ä¸è¿è¡çCLRå°Unicodeç¨äºStringåCharæ°æ®çå é¨è¡¨ç¤ºãä½ä¹ä¸å¿ æ å¿-å½è°ç¨Windows9xAPIå½æ°æ¶ï¼CLRä¼èªå¨è¿è¡å¿ è¦ç转æ¢ï¼å°å ¶ä»Unicode转æ¢ä¸ºANSIãå¦æDLLå½æ°ä¸ä»¥ä»»ä½æ¹å¼å¤çææ¬ï¼åå¯ä»¥å¿½ç¥DllImportAttributeçCharSetå±æ§ãç¶èï¼å½CharæStringæ°æ®æ¯çå¼çä¸é¨åæ¶ï¼åºè¯¥å°CharSetå±æ§è®¾ç½®ä¸ºCharSet.Autoãè¿æ ·å¯ä»¥ä½¿CLRæ ¹æ®å®¿ä¸»OS使ç¨éå½çå符éãå¦æ没ææ¾å¼å°è®¾ç½®CharSetå±æ§ï¼åå ¶é»è®¤å¼ä¸ºCharSet.Ansiãè¿ä¸ªé»è®¤å¼æ¯æ缺ç¹çï¼å 为对äºå¨Windows2000ãWindowsXPåWindowsNTä¸è¿è¡çinteropè°ç¨ï¼å®ä¼æ¶æå°å½±åææ¬åæ°å°éå¤ççæ§è½ã
ããåºè¯¥æ¾å¼å°éæ©CharSet.AnsiæCharSet.UnicodeçCharSetå¼èä¸æ¯ä½¿ç¨CharSet.Autoçå¯ä¸æ åµæ¯ï¼æ¨æ¾å¼å°æå®äºä¸ä¸ªå¯¼åºå½æ°ï¼è该å½æ°ç¹å®äºè¿ä¸¤ç§Win32OSä¸çæä¸ç§ãReadDirectoryChangesWAPIå½æ°å°±æ¯è¿æ ·çä¸ä¸ªä¾åï¼å®åªåå¨äºåºäºWindowsNTçæä½ç³»ç»ä¸ï¼å¹¶ä¸åªæ¯æUnicodeï¼å¨è¿ç§æ åµä¸ï¼æ¨åºè¯¥æ¾å¼å°ä½¿ç¨CharSet.Unicodeã
ããææ¶ï¼WindowsAPIæ¯å¦æå符éå ³ç³»å¹¶ä¸ææ¾ãä¸ç§å³ä¸ä¼æéç确认æ¹æ³æ¯å¨PlatformSDKä¸æ£æ¥è¯¥å½æ°çCè¯è¨å¤´æ件ãï¼å¦ææ¨æ æ³è¯å®è¦çåªä¸ªå¤´æ件ï¼åå¯ä»¥æ¥çPlatformSDKææ¡£ä¸ååºçæ¯ä¸ªAPIå½æ°ç头æ件ãï¼å¦ææ¨åç°è¯¥APIå½æ°ç¡®å®å®ä¹ä¸ºä¸ä¸ªæ å°å°ä»¥AæWç»å°¾çå½æ°åçå®ï¼åå符éä¸æ¨å°è¯è°ç¨çå½æ°æå ³ç³»ãWindowsAPIå½æ°çä¸ä¸ªä¾åæ¯å¨WinUser.hä¸å£°æçGetMessageAPIï¼æ¨ä¹è®¸ä¼æ讶å°åç°å®æAåW两ç§çæ¬ã
ããSetLastErroré误å¤çé常éè¦ï¼ä½å¨ç¼ç¨æ¶ç»å¸¸è¢«éå¿ãå½æ¨è¿è¡P/Invokeè°ç¨æ¶ï¼ä¹ä¼é¢ä¸´å ¶ä»çææ-å¤çæ管代ç ä¸WindowsAPIé误å¤çåå¼å¸¸ä¹é´çåºå«ãæå¯ä»¥ç»æ¨ä¸ç¹å»ºè®®ã
ããå¦ææ¨æ£å¨ä½¿ç¨P/Invokeè°ç¨WindowsAPIå½æ°ï¼è对äºè¯¥å½æ°ï¼æ¨ä½¿ç¨GetLastErroræ¥æ¥æ¾æ©å±çé误信æ¯ï¼ååºè¯¥å¨å¤é¨æ¹æ³çDllImportAttributeä¸å°SetLastErrorå±æ§è®¾ç½®ä¸ºtrueãè¿éç¨äºå¤§å¤æ°å¤é¨æ¹æ³ã
ããè¿ä¼å¯¼è´CLRå¨æ¯æ¬¡è°ç¨å¤é¨æ¹æ³ä¹åç¼åç±APIå½æ°è®¾ç½®çé误ãç¶åï¼å¨å è£ æ¹æ³ä¸ï¼å¯ä»¥éè¿è°ç¨ç±»åºçSystem.Runtime.InteropServices.Marshalç±»åä¸å®ä¹çMarshal.GetLastWin32Erroræ¹æ³æ¥è·åç¼åçé误å¼ãæç建议æ¯æ£æ¥è¿äºæææ¥èªAPIå½æ°çé误å¼ï¼å¹¶ä¸ºè¿äºå¼å¼åä¸ä¸ªå¯æç¥çå¼å¸¸ã对äºå ¶ä»ææ失败æ åµï¼å æ¬æ ¹æ¬å°±æ²¡ææå°ç失败æ åµï¼ï¼åå¼åå¨System.ComponentModelå½å空é´ä¸å®ä¹çWin32Exceptionï¼å¹¶å°Marshal.GetLastWin32Errorè¿åçå¼ä¼ éç»å®ãå¦ææ¨å头çä¸ä¸å¾1ä¸ç代ç ï¼æ¨ä¼çå°æå¨externMessageBeepæ¹æ³çå ¬å ±å è£ ä¸å°±éç¨äºè¿ç§æ¹æ³ã
ããCallingConventionæå°å¨æ¤ä»ç»çæåä¹å¯è½æ¯æä¸éè¦çä¸ä¸ªDllImportAttributeå±æ§æ¯CallingConventionãéè¿æ¤å±æ§ï¼å¯ä»¥ç»CLRæ示åºè¯¥å°åªç§å½æ°è°ç¨çº¦å®ç¨äºå æ ä¸çåæ°ãCallingConvention.Winapiçé»è®¤å¼æ¯æ好çéæ©ï¼å®å¨å¤§å¤æ°æ åµä¸é½å¯è¡ãç¶èï¼å¦æ该è°ç¨ä¸èµ·ä½ç¨ï¼åå¯ä»¥æ£æ¥PlatformSDKä¸ç声æ头æ件ï¼ççæ¨è°ç¨çAPIå½æ°æ¯å¦æ¯ä¸ä¸ªä¸ç¬¦åè°ç¨çº¦å®æ åçå¼å¸¸APIã
ããé常ï¼æ¬æºå½æ°ï¼ä¾å¦WindowsAPIå½æ°æC-è¿è¡æ¶DLLå½æ°ï¼çè°ç¨çº¦å®æè¿°äºå¦ä½å°åæ°æ¨å ¥çº¿ç¨å æ æä»çº¿ç¨å æ ä¸æ¸ é¤ã大å¤æ°WindowsAPIå½æ°é½æ¯é¦å å°å½æ°çæåä¸ä¸ªåæ°æ¨å ¥å æ ï¼ç¶åç±è¢«è°ç¨çå½æ°è´è´£æ¸ ç该å æ ãç¸åï¼è®¸å¤C-è¿è¡æ¶DLLå½æ°é½è¢«å®ä¹ä¸ºæç §æ¹æ³åæ°å¨æ¹æ³ç¾åä¸åºç°ç顺åºå°å ¶æ¨å ¥å æ ï¼å°å æ æ¸ çå·¥ä½äº¤ç»è°ç¨è ã
ãã幸è¿çæ¯ï¼è¦è®©P/Invokeè°ç¨å·¥ä½åªéè¦è®©*设å¤ç解è°ç¨çº¦å®å³å¯ãé常ï¼ä»é»è®¤å¼CallingConvention.Winapiå¼å§æ¯æ好çéæ©ãç¶åï¼å¨Cè¿è¡æ¶DLLå½æ°åå°æ°å½æ°ä¸ï¼å¯è½éè¦å°çº¦å®æ´æ¹ä¸ºCallingConvention.Cdeclã
ããæ°æ®å°éå¤çã
ããæ°æ®å°éå¤çæ¯P/Invokeå ·ææææ§çæ¹é¢ãå½å¨æ管åéæ管代ç ä¹é´ä¼ éæ°æ®æ¶ï¼CLRéµå¾ªè®¸å¤è§åï¼å¾å°æå¼å人åä¼ç»å¸¸éå°å®ä»¬ç´è³å¯å°è¿äºè§åè®°ä½ãé¤éæ¨æ¯ä¸åç±»åºå¼å人åï¼å¦åå¨é常æ åµä¸æ²¡æå¿ è¦ææ¡å ¶ç»èã为äºæææå°å¨CLRä¸ä½¿ç¨P/Invokeï¼å³ä½¿åªå¶å°éè¦interopçåºç¨ç¨åºå¼å人åä»ç¶åºè¯¥ç解æ°æ®å°éå¤ççä¸äºåºç¡ç¥è¯ã
ããå¨æ¬æä¸æ çå©ä½é¨åä¸ï¼æå°è®¨è®ºç®åæ°ååå符串æ°æ®çæ°æ®å°éå¤çãæå°ä»æåºæ¬çæ°åæ°æ®å°éå¤çå¼å§ï¼ç¶åä»ç»ç®åçæéå°éå¤çåå符串å°éå¤çã
ããå°éæ°ååé»è¾æ éã
ããWindowsOS大é¨åæ¯ç¨Cç¼åçãå æ¤ï¼WindowsAPIæç¨å°çæ°æ®ç±»åè¦ä¹æ¯Cç±»åï¼è¦ä¹æ¯éè¿ç±»åå®ä¹æå®å®ä¹éæ°æ è®°çCç±»åã让æ们çç没ææéçæ°æ®å°éå¤çãç®åèµ·è§ï¼é¦å éç¹è®¨è®ºçæ¯æ°ååå¸å°å¼ã
ããå½éè¿å¼åWindowsAPIå½æ°ä¼ éåæ°æ¶ï¼éè¦ç¥é以ä¸é®é¢ç*ï¼æ°æ®ä»æ ¹æ¬ä¸è®²æ¯æ´åçè¿æ¯æµ®ç¹åçï¼å¦ææ°æ®æ¯æ´åçï¼åå®æ¯æ符å·çè¿æ¯æ 符å·çï¼å¦ææ°æ®æ¯æ´åçï¼åå®çä½æ°æ¯å¤å°ï¼å¦ææ°æ®æ¯æµ®ç¹åçï¼åå®æ¯å精度çè¿æ¯å精度çï¼ææ¶*å¾ææ¾ï¼ä½ææ¶å´ä¸ææ¾ãWindowsAPI以åç§æ¹å¼éæ°å®ä¹äºåºæ¬çCæ°æ®ç±»åãå¾2ååºäºCåWin32çä¸äºå ¬å ±æ°æ®ç±»ååå ¶è§èï¼ä»¥åä¸ä¸ªå ·æå¹é è§èçå ¬å ±è¯è¨è¿è¡åºç±»åã
ããé常ï¼åªè¦æ¨éæ©ä¸ä¸ªå ¶è§èä¸è¯¥åæ°çWin32ç±»åç¸å¹é çCLRç±»åï¼æ¨ç代ç å°±è½å¤æ£å¸¸å·¥ä½ãä¸è¿ä¹æä¸äºç¹ä¾ãä¾å¦ï¼å¨WindowsAPIä¸å®ä¹çBOOLç±»åæ¯ä¸ä¸ªæ符å·ç32ä½æ´åãç¶èï¼BOOLç¨äºæ示Booleanå¼trueæfalseãè½ç¶æ¨ä¸ç¨å°BOOLåæ°ä½ä¸ºSystem.Int32å¼å°éï¼ä½æ¯å¦æ使ç¨System.Booleanç±»åï¼å°±ä¼è·å¾æ´åéçæ å°ãå符类åçæ å°ç±»ä¼¼äºBOOLï¼å 为æä¸ä¸ªç¹å®çCLRç±»å(System.Char)æåºå符çå«ä¹ã
ããå¨äºè§£è¿äºä¿¡æ¯ä¹åï¼éæ¥ä»ç»ç¤ºä¾å¯è½æ¯æ帮å©çãä¾ç¶éç¨beep主é¢ä½ä¸ºä¾åï¼è®©æ们æ¥è¯ä¸ä¸Kernel32.dllä½çº§Beepï¼å®ä¼éè¿è®¡ç®æºçæ¬å£°å¨åçå声ãè¿ä¸ªæ¹æ³çPlatformSDKææ¡£å¯ä»¥å¨Beepä¸æ¾å°ãæ¬æºAPIæ以ä¸æ¹å¼è¿è¡è®°å½ï¼BOOLBeep(DWORDdwFreq,//FrequencyDWORDdwDuration//Durationinmilliseconds);ã
ããå¨åæ°å°éå¤çæ¹é¢ï¼æ¨çå·¥ä½æ¯äºè§£ä»ä¹CLRæ°æ®ç±»åä¸BeepAPIå½æ°æ使ç¨çDWORDåBOOLæ°æ®ç±»åç¸å ¼å®¹ãå顾ä¸ä¸å¾2ä¸çå¾è¡¨ï¼æ¨å°çå°DWORDæ¯ä¸ä¸ª32ä½çæ 符å·æ´æ°å¼ï¼å¦åCLRç±»åSystem.UInt32ãè¿æå³çæ¨å¯ä»¥ä½¿ç¨UInt32å¼ä½ä¸ºéå¾Beepç两个åæ°ãBOOLè¿åå¼æ¯ä¸ä¸ªé常æ趣çæ åµï¼å 为该å¾è¡¨åè¯æ们ï¼å¨Win32ä¸ï¼BOOLæ¯ä¸ä¸ª32ä½çæ符å·æ´æ°ãå æ¤ï¼æ¨å¯ä»¥ä½¿ç¨System.Int32å¼ä½ä¸ºæ¥èªBeepçè¿åå¼ãç¶èï¼CLRä¹å®ä¹äºSystem.Booleanç±»åä½ä¸ºBooleanå¼çè¯ä¹ï¼æ以åºè¯¥ä½¿ç¨å®æ¥æ¿ä»£ãCLRé»è®¤å°System.Booleanå¼å°é为32ä½çæ符å·æ´æ°ãæ¤å¤ææ¾ç¤ºçå¤é¨æ¹æ³å®ä¹æ¯ç¨äºBeepçç»æP/Invokeæ¹æ³ï¼[DllImport("Kernel32.dll",SetLastError=true)]staticexternBooleanBeep(UInt32frequency,UInt32duration);ã
ããæéåæ°ã
ãã许å¤WindowsAPIå½æ°å°æéä½ä¸ºå®ä»¬çä¸ä¸ªæå¤ä¸ªåæ°ãæéå¢å äºå°éæ°æ®çå¤ææ§ï¼å 为å®ä»¬å¢å äºä¸ä¸ªé´æ¥å±ãå¦æ没ææéï¼æ¨å¯ä»¥éè¿å¼å¨çº¿ç¨å æ ä¸ä¼ éæ°æ®ãæäºæéï¼åå¯ä»¥éè¿å¼ç¨ä¼ éæ°æ®ï¼æ¹æ³æ¯å°è¯¥æ°æ®çå åå°åæ¨å ¥çº¿ç¨å æ ä¸ãç¶åï¼å½æ°éè¿å åå°åé´æ¥è®¿é®æ°æ®ã使ç¨æ管代ç 表示æ¤éå é´æ¥å±çæ¹å¼æå¤ç§ã
ããå¨C#ä¸ï¼å¦æå°æ¹æ³åæ°å®ä¹ä¸ºrefæoutï¼åæ°æ®éè¿å¼ç¨èä¸æ¯éè¿å¼ä¼ éãå³ä½¿æ¨æ²¡æ使ç¨Interopä¹æ¯è¿æ ·ï¼ä½åªæ¯ä»ä¸ä¸ªæ管æ¹æ³è°ç¨å°å¦ä¸ä¸ªæ管æ¹æ³ãä¾å¦ï¼å¦æéè¿refä¼ éSystem.Int32åæ°ï¼åå¨çº¿ç¨å æ ä¸ä¼ éçæ¯è¯¥æ°æ®çå°åï¼èä¸æ¯æ´æ°å¼æ¬èº«ãä¸é¢æ¯ä¸ä¸ªå®ä¹ä¸ºéè¿å¼ç¨æ¥æ¶æ´æ°å¼çæ¹æ³ç示ä¾ï¼voidFlipInt32(refInt32num){num=-num;}ã
ããè¿éï¼FlipInt32æ¹æ³è·åä¸ä¸ªInt32å¼çå°åã访é®æ°æ®ã对å®æ±åï¼ç¶åå°æ±åè¿çå¼èµç»åå§åéãå¨ä»¥ä¸ä»£ç ä¸ï¼FlipInt32æ¹æ³ä¼å°è°ç¨ç¨åºçåéxçå¼ä»10æ´æ¹ä¸º-10ï¼Int32x=10;FlipInt32(refx);ã
ããå¨æ管代ç ä¸å¯ä»¥éç¨è¿ç§è½åï¼å°æéä¼ éç»éæ管代ç ãä¾å¦ï¼FileEncryptionStatusAPIå½æ°ä»¥32ä½æ 符å·ä½æ©ç çå½¢å¼è¿åæ件å å¯ç¶æã该APIæ以ä¸æ示æ¹å¼è¿è¡è®°å½ï¼BOOLFileEncryptionStatus(LPCTSTRlpFileName,//filenameLPDWORDlpStatus//encryptionstatus);ã
ãã请注æï¼è¯¥å½æ°å¹¶ä¸ä½¿ç¨å®çè¿åå¼è¿åç¶æï¼èæ¯è¿åä¸ä¸ªBooleanå¼ï¼æ示è°ç¨æ¯å¦æåãå¨æåçæ åµä¸ï¼å®é çç¶æå¼æ¯éè¿ç¬¬äºä¸ªåæ°è¿åçãå®çå·¥ä½æ¹å¼æ¯è°ç¨ç¨åºå该å½æ°ä¼ éæåä¸ä¸ªDWORDåéçæéï¼è该APIå½æ°ç¨ç¶æå¼å¡«å æåçå åä½ç½®ã以ä¸ä»£ç ç段æ¾ç¤ºäºä¸ä¸ªè°ç¨éæ管FileEncryptionStatuså½æ°çå¯è½å¤é¨æ¹æ³å®ä¹ï¼[DllImport("Advapi32.dll",CharSet=CharSet.Auto)]staticexternBooleanFileEncryptionStatus(Stringfilename,outUInt32status);ã
ãã该å®ä¹ä½¿ç¨outå ³é®åæ¥ä¸ºUInt32ç¶æå¼æ示by-refåæ°ãè¿éæä¹å¯ä»¥éæ©refå ³é®åï¼å®é ä¸å¨è¿è¡æ¶ä¼äº§çç¸åçæºå¨ç ãoutå ³é®ååªæ¯ä¸ä¸ªby-refåæ°çè§èï¼å®åC#ç¼è¯å¨æ示æä¼ éçæ°æ®åªå¨è¢«è°ç¨çå½æ°å¤é¨ä¼ éãç¸åï¼å¦æ使ç¨refå ³é®åï¼åç¼è¯å¨ä¼åå®æ°æ®å¯ä»¥å¨è¢«è°ç¨çå½æ°çå é¨åå¤é¨ä¼ éã
ããæ管代ç ä¸outårefåæ°çå¦ä¸ä¸ªå¾å¥½çæ¹é¢æ¯ï¼å°åä½ä¸ºby-refåæ°ä¼ éçåéå¯ä»¥æ¯çº¿ç¨å æ ä¸çä¸ä¸ªæ¬å°åéãä¸ä¸ªç±»æç»æçå ç´ ï¼ä¹å¯ä»¥æ¯å ·æåéæ°æ®ç±»åçæ°ç»ä¸çä¸ä¸ªå ç´ å¼ç¨ãè°ç¨ç¨åºçè¿ç§çµæ´»æ§ä½¿å¾by-refåæ°æ为å°éç¼å²åºæé以ååæ°å¼æéçä¸ä¸ªå¾å¥½çèµ·ç¹ãåªæå¨æåç°refæoutåæ°ä¸ç¬¦åæçéè¦çæ åµä¸ï¼ææä¼èèå°æéå°é为æ´å¤æçCLRç±»åï¼ä¾å¦ç±»ææ°ç»å¯¹è±¡ï¼ã
ããå¦ææ¨ä¸çæCè¯æ³æè è°ç¨WindowsAPIå½æ°ï¼ææ¶å¾é¾ç¥éä¸ä¸ªæ¹æ³åæ°æ¯å¦éè¦æéãä¸ä¸ªå¸¸è§çæ示符æ¯çåæ°ç±»åæ¯å¦æ¯ä»¥åæ¯PæLPå¼å¤´çï¼ä¾å¦LPDWORDæPINTãå¨è¿ä¸¤ä¸ªä¾åä¸ï¼LPåPæ示åæ°æ¯ä¸ä¸ªæéï¼èå®ä»¬æåçæ°æ®ç±»ååå«ä¸ºDWORDæINTãç¶èï¼å¨æäºæ åµä¸ï¼å¯ä»¥ç´æ¥ä½¿ç¨Cè¯è¨è¯æ³ä¸çæå·(*)å°APIå½æ°å®ä¹ä¸ºæéã以ä¸ä»£ç ç段å±ç¤ºäºè¿æ¹é¢ç示ä¾ï¼voidTakesAPointer(DWORD*pNum);ã
ããå¯ä»¥çå°ï¼ä¸è¿°å½æ°çå¯ä¸ä¸ä¸ªåæ°æ¯æåDWORDåéçæéã
ããå½éè¿P/Invokeå°éæéæ¶ï¼refåoutåªç¨äºæ管代ç ä¸çå¼ç±»åãå½ä¸ä¸ªåæ°çCLRç±»å使ç¨structå ³é®åå®ä¹æ¶ï¼å¯ä»¥è®¤ä¸ºè¯¥åæ°æ¯ä¸ä¸ªå¼ç±»åãOutårefç¨äºå°éæåè¿äºæ°æ®ç±»åçæéï¼å 为é常å¼ç±»ååéæ¯å¯¹è±¡ææ°æ®ï¼èå¨æ管代ç ä¸å¹¶æ²¡æ对å¼ç±»åçå¼ç¨ãç¸åï¼å½å°éå¼ç¨ç±»å对象æ¶ï¼å¹¶ä¸éè¦refåoutå ³é®åï¼å 为åéå·²ç»æ¯å¯¹è±¡çå¼ç¨äºãå¦ææ¨å¯¹å¼ç¨ç±»ååå¼ç±»åä¹é´çå·®å«ä¸æ¯å¾çæï¼è¯·æ¥é 2000å¹´12æåè¡çMSDNMagazineï¼å¨.NETä¸æ ç主é¢ä¸å¯ä»¥æ¾å°æ´å¤ä¿¡æ¯ã大å¤æ°CLRç±»åé½æ¯å¼ç¨ç±»åï¼ç¶èï¼é¤äºSystem.StringåSystem.Objectï¼ææçåºå ç±»åï¼ä¾å¦System.Int32åSystem.Booleanï¼é½æ¯å¼ç±»åãå°éä¸éæ(Opaque)æéï¼ä¸ç§ç¹æ®æ åµã
ããææ¶å¨WindowsAPIä¸ï¼æ¹æ³ä¼ éæè¿åçæéæ¯ä¸éæçï¼è¿æå³ç该æéå¼ä»ææ¯è§åº¦è®²æ¯ä¸ä¸ªæéï¼ä½ä»£ç å´ä¸ç´æ¥ä½¿ç¨å®ãç¸åï¼ä»£ç å°è¯¥æéè¿åç»Windows以便éåè¿è¡éç¨ã
ããä¸ä¸ªé常常è§çä¾åå°±æ¯å¥æçæ¦å¿µãå¨Windowsä¸ï¼å é¨æ°æ®ç»æï¼ä»æ件å°å±å¹ä¸çæé®ï¼å¨åºç¨ç¨åºä»£ç ä¸é½è¡¨ç¤ºä¸ºå¥æãå¥æå ¶å®å°±æ¯ä¸éæçæéææçæé宽度çæ°å¼ï¼åºç¨ç¨åºç¨å®æ¥è¡¨ç¤ºå é¨çOSæé ã
ããå°æ°æ åµä¸ï¼APIå½æ°ä¹å°ä¸éææéå®ä¹ä¸ºPVOIDæLPVOIDç±»åãå¨WindowsAPIçå®ä¹ä¸ï¼è¿äºç±»åææå°±æ¯è¯´è¯¥æé没æç±»åã
ããå½ä¸ä¸ªä¸éææéè¿åç»æ¨çåºç¨ç¨åºï¼æè æ¨çåºç¨ç¨åºææå¾å°ä¸ä¸ªä¸éææéï¼æ¶ï¼æ¨åºè¯¥å°åæ°æè¿åå¼å°é为CLRä¸çä¸ç§ç¹æ®ç±»å-System.IntPtrãå½æ¨ä½¿ç¨IntPtrç±»åæ¶ï¼é常ä¸ä½¿ç¨outærefåæ°ï¼å 为IntPtræ为ç´æ¥æææéãä¸è¿ï¼å¦ææ¨å°ä¸ä¸ªæéå°é为ä¸ä¸ªæéï¼å对IntPtr使ç¨by-refåæ°æ¯åéçã
ããå¨CLRç±»åç³»ç»ä¸ï¼System.IntPtrç±»åæä¸ä¸ªç¹æ®çå±æ§ãä¸åç³»ç»ä¸çå ¶ä»åºç±»åï¼IntPtr并没æåºå®ç大å°ãç¸åï¼å®å¨è¿è¡æ¶ç大å°æ¯ä¾åºå±æä½ç³»ç»çæ£å¸¸æé大å°èå®çãè¿æå³çå¨32ä½çWindowsä¸ï¼IntPtråéç宽度æ¯32ä½çï¼èå¨64ä½çWindowsä¸ï¼å®æ¶ç¼è¯å¨ç¼è¯ç代ç ä¼å°IntPtrå¼çä½64ä½çå¼ãå½å¨æ管代ç åéæ管代ç ä¹é´å°éä¸éææéæ¶ï¼è¿ç§èªå¨è°è大å°çç¹ç¹ååæç¨ã
ãã请记ä½ï¼ä»»ä½è¿åææ¥åå¥æçAPIå½æ°å ¶å®æä½çå°±æ¯ä¸éææéãæ¨ç代ç åºè¯¥å°Windowsä¸çå¥æå°éæSystem.IntPtrå¼ã
ããæ¨å¯ä»¥å¨æ管代ç ä¸å°IntPtrå¼å¼ºå¶è½¬æ¢ä¸º32ä½æ64ä½çæ´æ°å¼ï¼æå°åè 强å¶è½¬æ¢ä¸ºåè ãç¶èï¼å½ä½¿ç¨WindowsAPIå½æ°æ¶ï¼å 为æéåºæ¯ä¸éæçï¼æ以é¤äºåå¨åä¼ éç»å¤é¨æ¹æ³å¤ï¼ä¸è½å°å®ä»¬å¦åå®ç¨ãè¿ç§"åªéåå¨åä¼ é"è§åç两个ç¹ä¾æ¯å½æ¨éåå¤é¨æ¹æ³ä¼ énullæéå¼åéè¦æ¯è¾IntPtrå¼ä¸nullå¼çæ åµã为äºåå°è¿ä¸ç¹ï¼æ¨ä¸è½å°é¶å¼ºå¶è½¬æ¢ä¸ºSystem.IntPtrï¼èåºè¯¥å¨IntPtrç±»åä¸ä½¿ç¨Int32.Zeroéæå ¬å ±å段ï¼ä»¥ä¾¿è·å¾ç¨äºæ¯è¾æèµå¼çnullå¼ã
ããå°éææ¬ã
ããå¨ç¼ç¨æ¶ç»å¸¸è¦å¯¹ææ¬æ°æ®è¿è¡å¤çãææ¬ä¸ºinteropå¶é äºä¸äºéº»ç¦ï¼è¿æ两个åå ãé¦å ï¼åºå±æä½ç³»ç»å¯è½ä½¿ç¨Unicodeæ¥è¡¨ç¤ºå符串ï¼ä¹å¯è½ä½¿ç¨ANSIãå¨æå°æ°æ åµä¸ï¼ä¾å¦MultiByteToWideCharAPIå½æ°ç两个åæ°å¨å符éä¸æ¯ä¸ä¸è´çã
ãã第äºä¸ªåå æ¯ï¼å½éè¦è¿è¡P/Invokeæ¶ï¼è¦å¤çææ¬è¿éè¦ç¹å«äºè§£å°CåCLRå¤çææ¬çæ¹å¼æ¯ä¸åçãå¨Cä¸ï¼å符串å®é ä¸åªæ¯ä¸ä¸ªå符å¼æ°ç»ï¼é常以nullä½ä¸ºç»æ符ã大å¤æ°WindowsAPIå½æ°æ¯æç §ä»¥ä¸æ¡ä»¶å¤çå符串çï¼å¯¹äºANSIï¼å°å ¶ä½ä¸ºå符å¼æ°ç»ï¼å¯¹äºUnicodeï¼å°å ¶ä½ä¸ºå®½å符å¼æ°ç»ã
ãã幸è¿çæ¯ï¼CLR被设计å¾ç¸å½çµæ´»ï¼å½å°éææ¬æ¶é®é¢å¾ä»¥è½»æ¾è§£å³ï¼èä¸ç¨å¨æWindowsAPIå½æ°ææä»æ¨çåºç¨ç¨åºå¾å°çæ¯ä»ä¹ãè¿éæ¯ä¸äºéè¦è®°ä½ç主è¦èèäºé¡¹ï¼æ¯æ¨çåºç¨ç¨åºåAPIå½æ°ä¼ éææ¬æ°æ®ï¼è¿æ¯APIå½æ°åæ¨çåºç¨ç¨åºè¿åå符串æ°æ®ï¼æè äºè å ¼æï¼æ¨çå¤é¨æ¹æ³åºè¯¥ä½¿ç¨ä»ä¹æ管类åï¼APIå½æ°ææå¾å°çæ¯ä»ä¹æ ¼å¼çéæ管å符串ï¼æ们é¦å 解çæåä¸ä¸ªé®é¢ã大å¤æ°WindowsAPIå½æ°é½å¸¦æLPTSTRæLPCTSTRå¼ãï¼ä»å½æ°è§åº¦çï¼å®ä»¬åå«æ¯å¯ä¿®æ¹åä¸å¯ä¿®æ¹çç¼å²åºï¼å å«ä»¥nullç»æçå符æ°ç»ã"C"代表常æ°ï¼æå³ç使ç¨è¯¥åæ°ä¿¡æ¯ä¸ä¼ä¼ éå°å½æ°å¤é¨ãLPTSTRä¸ç"T"表æ该åæ°å¯ä»¥æ¯UnicodeæANSIï¼åå³äºæ¨éæ©çå符éååºå±æä½ç³»ç»çå符éãå 为å¨WindowsAPIä¸å¤§å¤æ°å符串åæ°é½æ¯è¿ä¸¤ç§ç±»åä¹ä¸ï¼æ以åªè¦å¨DllImportAttributeä¸éæ©CharSet.Autoï¼CLRå°±æé»è®¤çæ¹å¼å·¥ä½ã
ããç¶èï¼æäºAPIå½æ°æèªå®ä¹çDLLå½æ°éç¨ä¸åçæ¹å¼è¡¨ç¤ºå符串ãå¦ææ¨è¦ç¨å°ä¸ä¸ªè¿æ ·çå½æ°ï¼å°±å¯ä»¥éç¨MarshalAsAttribute修饰å¤é¨æ¹æ³çå符串åæ°ï¼å¹¶ææä¸ç§ä¸åäºé»è®¤LPTSTRçåç¬¦ä¸²æ ¼å¼ãæå ³MarshalAsAttributeçæ´å¤ä¿¡æ¯ï¼è¯·åé ä½äºMarshalAsAttributeClassçPlatformSDKæ档主é¢ã
ããç°å¨è®©æ们çä¸ä¸å符串信æ¯å¨æ¨ç代ç åéæ管å½æ°ä¹é´ä¼ éçæ¹åãæ两ç§æ¹å¼å¯ä»¥ç¥éå¤çå符串æ¶ä¿¡æ¯çä¼ éæ¹åã第ä¸ä¸ªä¹æ¯æå¯é çä¸ä¸ªæ¹æ³å°±æ¯é¦å ç解åæ°çç¨éãä¾å¦ï¼æ¨æ£è°ç¨ä¸ä¸ªåæ°ï¼å®çå称类似CreateMutex并带æä¸ä¸ªå符串ï¼åå¯ä»¥æ³å该å符串信æ¯æ¯ä»åºç¨ç¨åºåAPIå½æ°ä¼ éçãåæ¶ï¼å¦ææ¨è°ç¨GetUserNameï¼å该å½æ°çå称表æå符串信æ¯æ¯ä»è¯¥å½æ°åæ¨çåºç¨ç¨åºä¼ éçã
ããé¤äºè¿ç§æ¯è¾åççæ¹æ³å¤ï¼ç¬¬äºç§æ¥æ¾ä¿¡æ¯ä¼ éæ¹åçæ¹å¼å°±æ¯æ¥æ¾APIåæ°ç±»åä¸çåæ¯"C"ãä¾å¦ï¼GetUserNameAPIå½æ°ç第ä¸ä¸ªåæ°è¢«å®ä¹ä¸ºLPTSTRç±»åï¼å®ä»£è¡¨ä¸ä¸ªæåUnicodeæANSIå符串ç¼å²åºçé¿æéãä½æ¯CreateMutexçå称åæ°è¢«ç±»åå为LTCTSTRã请注æï¼è¿éçç±»åå®ä¹æ¯ä¸æ ·çï¼ä½å¢å ä¸ä¸ªåæ¯"C"æ¥è¡¨æç¼å²åºä¸ºå¸¸æ°ï¼APIå½æ°ä¸è½åå ¥ã
ããä¸æ¦æç¡®äºææ¬åæ°æ¯åªç¨ä½è¾å ¥è¿æ¯ç¨ä½è¾å ¥/è¾åºï¼å°±å¯ä»¥ç¡®å®ä½¿ç¨åªç§CLRç±»åä½ä¸ºåæ°ç±»åãè¿éæä¸äºè§åãå¦æå符串åæ°åªç¨ä½è¾å ¥ï¼å使ç¨System.Stringç±»åãå¨æ管代ç ä¸ï¼å符串æ¯ä¸åçï¼éåç¨äºä¸ä¼è¢«æ¬æºAPIå½æ°æ´æ¹çç¼å²åºã
ããå¦æå符串åæ°å¯ä»¥ç¨ä½è¾å ¥å/æè¾åºï¼å使ç¨System.StringBuilderç±»åãStringBuilderç±»åæ¯ä¸ä¸ªå¾æç¨çç±»åºç±»åï¼å®å¯ä»¥å¸®å©æ¨ææå°æ建å符串ï¼ä¹æ£å¥½å¯ä»¥å°ç¼å²åºä¼ éç»æ¬æºå½æ°ï¼ç±æ¬æºå½æ°ä¸ºæ¨å¡«å å符串æ°æ®ãä¸æ¦å½æ°è°ç¨è¿åï¼æ¨åªéè¦è°ç¨StringBuilder对象çToStringå°±å¯ä»¥å¾å°ä¸ä¸ªString对象ã
ããGetShortPathNameAPIå½æ°è½å¾å¥½å°ç¨äºæ¾ç¤ºä»ä¹æ¶å使ç¨Stringãä»ä¹æ¶å使ç¨StringBuilderï¼å 为å®åªå¸¦æä¸ä¸ªåæ°ï¼ä¸ä¸ªè¾å ¥å符串ãä¸ä¸ªè¾åºå符串åä¸ä¸ªææè¾åºç¼å²åºçå符é¿åº¦çåæ°ã
ããå¾3æ示为å 注éçéæ管GetShortPathNameå½æ°ææ¡£ï¼å®åæ¶æåºäºè¾å ¥åè¾åºå符串åæ°ãå®å¼åºäºæ管çå¤é¨æ¹æ³å®ä¹ï¼ä¹å¦å¾3æ示ã请注æ第ä¸ä¸ªåæ°è¢«å°é为System.Stringï¼å 为å®æ¯ä¸ä¸ªåªç¨ä½è¾å ¥çåæ°ã第äºä¸ªåæ°ä»£è¡¨ä¸ä¸ªè¾åºç¼å²åºï¼å®ä½¿ç¨äºSystem.StringBuilderã
ããå°ç»ã
ããæ¬æä¸æ æä»ç»çP/Invokeåè½è¶³å¤è°ç¨Windowsä¸ç许å¤APIå½æ°ãç¶èï¼å¦ææ¨å¤§éç¨å°interopï¼åä¼æç»åç°èªå·±å°éäºå¾å¤æçæ°æ®ç»æï¼çè³å¯è½éè¦å¨æ管代ç ä¸éè¿æéç´æ¥è®¿é®å åãå®é ä¸ï¼æ¬æºä»£ç ä¸çinteropå¯ä»¥æ¯ä¸ä¸ªå°ç»èåä½çº§æ¯ç¹èå¨éé¢ççæ£çæ½å¤æçåãCLRãC#åæ管C++æä¾äºè®¸å¤æç¨çåè½ï¼ä¹è®¸ä»¥åæä¼å¨æ¬ä¸æ ä»ç»é«çº§çP/Invokeè¯é¢ã
ããåæ¶ï¼åªè¦æ¨è§å¾.NETFrameworkç±»åºæ æ³ææ¾æ¨ç声é³æè 为æ¨æ§è¡å ¶ä»ä¸äºåè½ï¼æ¨å¯ä»¥ç¥éå¦ä½ååå§èä¼ç§çWindowsAPI寻æ±ä¸äºå¸®å©ã