.Net 開發(fā)中如果使用外部DLL,一般引用進(jìn)來就可以了,最多引用前將DLL注冊一下。下面是我所遇到的問題及解決的方法,希望能對大家有用。
1.在Visual Studio中引用C++寫的DLL時報以下錯誤:
未能添加引用,請確保此文件可訪問并且是一個有效的程序集或COM組件。
手工注冊該DLL也報錯:模塊已加載,但找不到入口點DLLRegisterServer, 請確保XXX為有效的DLL或OCA文件,然后重試。
經(jīng)查詢發(fā)現(xiàn)C++編譯的DLL并不一定能被C#直接使用,需通過C#中的DllImport直接調(diào)用這些功能。
代碼如下所示:
在程序開始時使用以下語句注冊方法。
[DllImport("Enc7481.dll", EntryPoint = "_Enc7481_Set_Encoder", ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
private extern static void _Enc7481_Set_Encoder(UInt16 intDirection, Int32 lngValue);
在程序中直接調(diào)用就可以了:
_Enc7481_Set_Encoder(0, 0);
2.找不到對應(yīng)的方法
使用以上的程序后,參考廠商所給的C++程序卻報找不到對應(yīng)的入口點,也就是函數(shù)名稱不對。C++DLL編譯后函數(shù)名稱會有變化,需使用eXeScope.exe查詢具體的函數(shù)名稱。
3.報內(nèi)存錯誤:
嘗試讀取或?qū)懭胧鼙Wo(hù)的內(nèi)存。這通常指示其他內(nèi)存已損壞。造成這種錯誤的情況很多,一般來說是對函數(shù)的使用錯誤造成的。對于我的程序來說是因為需要首先調(diào)用_Enc7481_Init()來初始化。
4.類型錯誤
終于將以上錯誤都解決,程序可以運行了,但發(fā)現(xiàn)取到的數(shù)據(jù)總是不對,再次檢查,發(fā)現(xiàn)原來是數(shù)據(jù)類型不對造成的。
VC++中主要字符串類型為:LPSTR,LPCSTR, LPCTSTR, string, CString, LPCWSTR, LPWSTR等
但轉(zhuǎn)為C#類型卻不完全相同,只有數(shù)據(jù)類型對應(yīng)正確才能取得正確的數(shù)據(jù)。
類型對照:
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.結(jié)構(gòu)體參數(shù)的傳遞
對于結(jié)構(gòu)體參數(shù)需要在C#中建立對應(yīng)的結(jié)構(gòu)體,并用Marshal類將結(jié)構(gòu)體轉(zhuǎn)換為指針地址傳給C++函數(shù),取得數(shù)據(jù)后再根據(jù)指針地址取得對應(yīng)的結(jié)構(gòu)。
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));