項目:無線無源測溫軟體系統
項目中,用到使用P/Invoke在.NET調用win32API,實作對ini配置檔案的讀寫功能!因為有一些配置資訊需要儲存下來,以便在下一次啟動程式完成初始化,這實際上是一種類持久化。将
一些資訊寫入INI檔案(initialization file)中,可完成簡單的持久化支援。
Windows提供了API接口用于操作INI檔案,其支援的INI檔案格式一般如下:
===============================
[Section1]
Key11=value11
Key12=value12
[Section2]
Key21=value21
Key22=value22
...
[SectionN]
KeyN1=valueN1
KeyN2=valueN2
一般一個INI檔案可有N個節,每節可有n個鍵名及值對應,每個鍵名及其值以等式形式占一行。
一般鍵的名稱可任取,不過建議用有意義的字元及詞構成。值一般可為整數和字元串,其它類型要進行轉換。
常見的系統配置檔案:
C:/boot.ini
C:/WINDOWS/win.ini
C:/WINDOWS/system.ini
C:/WINDOWS/desktop.ini
C:/WINDOWS/Resources/Themes/Windows Classic.theme
注意,字元串存貯在INI檔案中時沒有引号;key和value之間的等号前後不容空格;注釋以分号“;”開頭。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLi0zaHRGcWdUYuVzVa9GczoVdG1mWfVGc5RHLwkzX39GZhh2csATMflHLwEzX4xSZz91ZsADMx8FdsYkRGZkRG9lcvx2bjxSa2EWNhJTW1AlUxEFeVRUUfRHelRHL2EzXlpXazxyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3PnVGcq5CZkBDOiFWOzITMmdjM1kTO0EWYzITM1ITMhRmM3QmNw8CX2AzLchDMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL1M3Lc9CX6MHc0RHaiojIsJye.jpeg)
但是令人遺憾的是C#所使用的.NET架構下的公共類庫并沒有提供直接操作INI檔案的類,是以唯一比較理想的方法就是調用API函數。
然後,.Net架構下的類庫是基于托管代碼的,而API函數是基于非托管代碼的,(在運作庫的控制下執行的代碼稱作托管代碼。相反,在運作庫之外運作的代碼稱作非托管代碼。)如何實作托管代碼與非托管代碼之間的操作呢?.Net架構的System.Runtime.InteropServices命名空間下提供各種各樣支援COM interop及平台調用服務的成員,
在受控代碼與非受控代碼進行互動時會産生一個事務(transition) ,這通常發生在使用平台調用服務(Platform Invocation Services),即P/Invoke
平台調用是一種服務,它使托管代碼能夠調用 DLL 中實作的非托管函數,如調用系統的 API 或與 COM 對象打交道,通過 System.Runtime.InteropServices 命名空間
為了從托管代碼中調用非托管的DLL中函數,你要建立一個P/Invoke包裝(Wrapper)。一個P/Invoke包裝是一個.net兼 容的方法聲明,用來建立P/Invoke包裝的文法與建立托管方法的聲明文法本質上是一樣的。唯一不同是P/Invoke包裝不包含函數體,而隻有方法 名、傳回值類型和參數資訊。并且,P/Invoke包裝使用了DllImport屬性。這個屬性是用來定位包含有目标函數的非托管的DLL。
其中最重要的屬性之一DllImportAttribute可以用來定義用于通路非托管API的平台調用方法,它提供了對從非托管DLL導出的函數進行調用所必需的資訊。下面就來看一下如何實作C#與API函數的互操作。
讀操作:
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string defVal, StringBuilder retVal, int size, string filePath);
section:要讀取的段落名
key: 要讀取的鍵
defVal: 讀取異常的情況下的預設值
retVal: key所對應的值,如果該key不存在則傳回空值
size: 值允許的大小
filePath: INI檔案的完整路徑和檔案名
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
section: 要寫入的段落名
key: 要寫入的鍵,如果該key存在則覆寫寫入
val: key所對應的值
歡迎關注微信公衆号:大資料從業者