C#.net調用動態庫dll注意事項
本文主要描述作者在工作中所遇到技術痛點及問題,最後提出相關的解決方案
情境
公司有個業務需求涉及到ID讀卡機,構建成在ID卡讀卡機一刷ID卡,系統就自動顯示其ID卡號以及該ID卡的基本資料和消費的記錄等資訊;
問題
在選購相關的ID讀卡機產品後,下載其開發包其中包含了用C++語言開發的動態庫DLL,在調用時出現以下問題:
1、無法載入 DLL“OUR_IDR.dll”: 找不到指定的模組。 (異常來自 HRESULT:0x8007007E)。
2、嘗試讀取或寫入受保護的記憶體。這通常指示其他記憶體已損壞
解決方案
1、第一個問題“無法載入 DLL“OUR_IDR.dll”: 找不到指定的模組。 (異常來自 HRESULT:0x8007007E)。”,解決很簡單,具體方法是將 dll複製到應用程式中的bin目錄即可。
2、
我在調用以下代碼時:
[DllImport("OUR_IDR.dll")]
public static extern byte[] idr_read(byte[] pserial);
就出現錯誤“嘗試讀取或寫入受保護的記憶體。這通常指示其他記憶體已損壞 ”。
解決方案是將byte[]改為IntPtr即可,如:
[DllImport("OUR_IDR.dll")]
public static extern IntPtr idr_read(IntPtr pserial);
在調用時:
IntPtr cardId = new IntPtr();
IntPtr result = Module.idr_read(cardId);
即可;
C#在調用C++動態庫DLL時,注意資料類型轉換
C# 與 C++ 資料類型對照
C++ C#
=====================================
WORD ushort
DWORD uint
UCHAR int/byte 大部分情況都可以使用int代替,而如果需要嚴格對齊的話則應該用bytebyte
UCHAR* string/IntPtr
unsigned char* [MarshalAs(UnmanagedType.LPArray)]byte[]/?(Intptr)
char* string
LPCTSTR string
LPTSTR [MarshalAs(UnmanagedType.LPTStr)] string
long int
ulong uint
Handle IntPtr
HWND IntPtr
void* IntPtr
int int
int* ref int
*int IntPtr
unsigned int uint
COLORREF uint