[英]Call a C++ DLL method from a C# application
我正在嘗試在C#項目中使用C ++ DLL中的方法,但是我在正確調用它時遇到問題。 方法是這樣的:
如SDK手冊所述
DWORD WINAPI PrtRead(HANDLE hPrt,DWORD dwTimeout,DWORD * pdwType,LPDWORD pdwParArray,LPDWORD pdwArraySize,LPBYTE pbReadData,LPDWORD pdwReadDataLen)
如代碼中所定義
extern "C" __declspec(dllimport) DWORD PrtRead (HANDLE hPRT, DWORD dwTimeout, DWORD *pdwType, LPDWORD pdwParArray, LPDWORD pdwArraySize,LPBYTE pbReadData, LPDWORD pdwReadDataLen);
在SDK C ++示例中,他們這樣稱呼它:
DWORD dwPar[2];
pdwParArray = &dwPar[0];
dwPar[0] = 0;
dwPar[1] = 0;
DWORD dwRet = PrtRead(hPrinter, dwCurrentTimeout, &dwType, pdwParArray, &dwArraySize, NULL, &dwReadDataLen);
我的問題是獲取值LPDWORD pdwParArray。
DLL總是在位置[0]處返回以下值之一:1、2或20,在位置[1]處返回1、2或4,但是我不願意這樣做。
我嘗試過這樣定義導入:
[DllImport("HPRDH.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ulong PrtRead(IntPtr hPrt, ulong dwTimeout, ref ulong pdwType, XXXXXXXXX , ref ulong pdwArraySize, ref byte[] pbReadData, ref ulong pdwReadDataLen);
像這樣的XXXXXXXXX
方法定義:
out ulong[] pdwParArray
變量初始化:
ulong[] pdwParArray;
方法返回:
pdwParArray = null
方法定義:
ref ulong[] pdwParArray
變量初始化:
ulong[] pdwParArray = new ulong[2];
pdwParArray[0] = 0;
pdwParArray[1] = 0;
方法返回:pdwParArray [0] = 0; pdwParArray [1] =越界數組索引;
方法定義:out ulong pdwParArray
變量初始化:ulong [] pdwParArray = new ulong [2];
方法返回:pdwParArray [0] = 0; pdwParArray [1] = 0;
方法定義:ref ulong pdwParArray
變量初始化:ulong [] pdwParArray = new ulong [2];
方法返回:pdwParArray [0] = 0; pdwParArray [1] = 0;
如何在C#導入中定義LPDWORD pdwParArray,如何對其進行初始化和調用?
提前致謝
_
_
_
_
編輯: @TheMathemagician
對這些結果進行了以下嘗試:
定義:
[MarshalAs(UnManagedType.LPArray)] ulong [] pdwParArray
結果:
pdwParArray [0] = 0;
pdwParArray [1] = 0;
定義:
[MarshalAs(UnmanagedType.LPArray)] ulong [] pdwParArray
結果:
pdwParArray [0] = null;
pdwParArray [1] = null;
定義:
[MarshalAs(UnmanagedType.LPArray)] ulong pdwParArray
結果:
無法編組“參數4”:無效的托管/非托管類型組合(Int64 / UInt64必須與I8或U8配對)。
定義:
[MarshalAs(UnmaDefinition:nagedType.LPArray)]與ulpdwParArray
結果:
無法編組“參數4”:無效的托管/非托管類型組合(Int64 / UInt64必須與I8或U8配對)。
您說該方法是WINAPI調用,而不是在c#應用程序中將cdecl聲明為cdecl
嘗試將其聲明為[MarshalAs(UnManagedType.LPArray)] ulong [] pdwParArray
OK,C#中的ulong是一個64位整數(在Windows 7上),我發現如果我將所有的ulong都更改為Int32,那么它對我用相同簽名構造的DLL函數起作用。
所以我有:[DllImport(“ SPLibNet.dll”,CallingConvention = CallingConvention.StdCall)]公共靜態外部Int32 PrtRead(IntPtr hPtr,Int32 dwTimeout,ref Int32 pdwType,[MarshalAs(UnmanagedType.LPArray)] Int32 [] pdw ..
而且我的DLL能夠在pdwParArray中設置值
我注意到的一件事是您為導入的函數指定了錯誤的CallingConvention。
在C ++中,WINAPI被定義為
#define WINAPI __stdcall
因此,您的C#導入應為
[DllImport("HPRDH.dll", CallingConvention = CallingConvention.StdCall)]
public static extern ulong PrtRead(IntPtr hPrt, ulong dwTimeout, ref ulong pdwType, XXXXXXXXX , ref ulong pdwArraySize, ref byte[] pbReadData, ref ulong pdwReadDataLen);
使用此處的表格進行轉換,並更正調用約定: Pinvoke.net
由於幾乎所有答案都在同一件事上,即使這樣也行不通,我決定更深入地研究SDK示例,並意識到我需要第二次調用PrtRead(...)以獲取正確的答案。價值觀。
我最終使用:
[DllImport("HPRDH.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern UInt32 PrtRead(IntPtr hPrt, UInt32 dwTimeout, ref UInt32 pdwType, out UInt32 pdwParArray, ref UInt32 pdwArraySize, ref byte[] pbReadData, ref UInt32 pdwReadDataLen);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.