C#引用C++開發的DLL


.Net 開發中如果使用外部DLL,一般引用進來就可以了,最多引用前將DLL注冊一下。最近做的項目中需要使用硬件廠家用C++開發的DLL,我還照原來的方式引用卻報錯,一步步用下來卻發現原來還有這么多技巧需注意。下面是我所遇到的問題及解決的方法,希望能對大家有用。

1.在Visual Studio中引用C++寫的DLL時報以下錯誤:

未能添加引用,請確保此文件可訪問並且是一個有效的程序集或COM組件。

手工注冊該DLL也報錯:模塊已加載,但找不到入口點DLLRegisterServer, 請確保XXX為有效的DLL或OCA文件,然后重試。

經查詢發現C++編譯的DLL並不一定能被C#直接使用,需通過C#中的DllImport直接調用這些功能。

代碼如下所示:

在程序開始時使用以下語句注冊方法。

 [DllImport("Enc7481.dll", EntryPoint = "_Enc7481_Set_Encoder", ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
 private extern static void _Enc7481_Set_Encoder(UInt16 intDirection, Int32 lngValue);

在程序中直接調用就可以了:

_Enc7481_Set_Encoder(0, 0);

2.找不到對應的方法

使用以上的程序后,參考廠商所給的C++程序卻報找不到對應的入口點,也就是函數名稱不對。C++DLL編譯后函數名稱會有變化,需使用eXeScope.exe查詢具體的函數名稱。

3.報內存錯誤:

嘗試讀取或寫入受保護的內存。這通常指示其他內存已損壞。造成這種錯誤的情況很多,一般來說是對函數的使用錯誤造成的。對於我的程序來說是因為需要首先調用_Enc7481_Init()來初始化。

4.類型錯誤

終於將以上錯誤都解決,程序可以運行了,但發現取到的數據總是不對,再次檢查,發現原來是數據類型不對造成的。

VC++中主要字符串類型為:LPSTR,LPCSTR, LPCTSTR, string, CString, LPCWSTR, LPWSTR等
但轉為C#類型卻不完全相同,只有數據類型對應正確才能取得正確的數據。

類型對照:

BSTR ---------  StringBuilder

LPCTSTR --------- StringBuilder

LPCWSTR ---------  IntPtr

handle---------IntPtr

hwnd-----------IntPtr

char *----------string

int * -----------ref int

int &-----------ref int

void *----------IntPtr

unsigned char *-----ref byte

5.結構體參數的傳遞

對於結構體參數需要在C#中建立對應的結構體,並用Marshal類將結構體轉換為指針地址傳給C++函數,取得數據后再根據指針地址取得對應的結構。

HREE structThree = new THREE();
            IntPtr ptrThree = Marshal.AllocHGlobal(Marshal.SizeOf(structThree));
            Marshal.StructureToPtr(structThree, ptrThree, false);
            _Enc7481_Get_ThreeEncoder2(ptrThree);
            structThree = (THREE)Marshal.PtrToStructure(ptrThree, typeof(THREE));


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM