打电话给 C++ C# 应用程序中的 DLL 方法
我正在尝试在 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)] out ulong[] pdwParArray
结果:
pdwParArray[0] = null;
pdwParArray[1] = null;
定义:
[MarshalAs(UnmanagedType.LPArray)] ulong pdwParArray
结果:
无法封送“参数 #4”:无效的托管/非托管类型组合(Int64/UInt64 必须与 I8 或 U8 配对)。
定义:
[MarshalAs(UnmaDefinition:ngedType.LPArray)] out ulong pdwParArray
结果:
无法封送“参数 #4”:无效的托管/非托管类型组合(Int64/UInt64 必须与 I8 或 U8 配对)。
I'm trying to use a method from a C++ DLL in a C# project, but I'm, having problems calling it correctly.
The method is this:
As said in the SDK manual
DWORD WINAPI PrtRead (HANDLE hPrt, DWORD dwTimeout, DWORD *pdwType, LPDWORD pdwParArray, LPDWORD pdwArraySize, LPBYTE pbReadData, LPDWORD pdwReadDataLen)
As really defined on code
extern "C" __declspec(dllimport) DWORD PrtRead (HANDLE hPRT, DWORD dwTimeout, DWORD *pdwType, LPDWORD pdwParArray, LPDWORD pdwArraySize,LPBYTE pbReadData, LPDWORD pdwReadDataLen);
and in the SDK C++ sample they call it like this:
DWORD dwPar[2];
pdwParArray = &dwPar[0];
dwPar[0] = 0;
dwPar[1] = 0;
DWORD dwRet = PrtRead(hPrinter, dwCurrentTimeout, &dwType, pdwParArray, &dwArraySize, NULL, &dwReadDataLen);
My problem is getting the value LPDWORD pdwParArray.
The DLL always returns one of the following values in position [0]: 1, 2 or 20 and in postion [1]: 1, 2 or 4, but I'm unbale to make it do this.
I've tryed defining the import like this:
[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);
and varied XXXXXXXXX like this
Method definition:
out ulong[] pdwParArray
Variable Initialization:
ulong[] pdwParArray;
Method returns:
pdwParArray = null
Method definition:
ref ulong[] pdwParArray
Variable Initialization:
ulong[] pdwParArray = new ulong[2];
pdwParArray[0] = 0;
pdwParArray[1] = 0;
Method returns:
pdwParArray[0] = 0;
pdwParArray[1] = Out of bounds array index;
Method definition:
out ulong pdwParArray
Variable Initialization:
ulong[] pdwParArray = new ulong[2];
Method returns:
pdwParArray[0] = 0;
pdwParArray[1] = 0;
Method definition:
ref ulong pdwParArray
Variable Initialization:
ulong[] pdwParArray = new ulong[2];
Method returns:
pdwParArray[0] = 0;
pdwParArray[1] = 0;
How should I define the LPDWORD pdwParArray in my C# import, how to initialize it and call it?
Thanks in advance
_
_
_
_
EDIT:
@TheMathemagician
Tried the following with these results:
Definition:
[MarshalAs(UnManagedType.LPArray)] ulong[] pdwParArray
Result:
pdwParArray[0] = 0;
pdwParArray[1] = 0;
Definition:
[MarshalAs(UnmanagedType.LPArray)] out ulong[] pdwParArray
Result:
pdwParArray[0] = null;
pdwParArray[1] = null;
Definition:
[MarshalAs(UnmanagedType.LPArray)] ulong pdwParArray
Result:
Cannot marshal 'parameter #4': Invalid managed/unmanaged type combination (Int64/UInt64 must be paired with I8 or U8).
Definition:
[MarshalAs(UnmaDefinition:nagedType.LPArray)] out ulong pdwParArray
Result:
Cannot marshal 'parameter #4': Invalid managed/unmanaged type combination (Int64/UInt64 must be paired with I8 or U8).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
你说的方法是WINAPI调用,而不是cdecl
在您的 C# 应用程序中,您将其声明为 cdecl
you said the method is a WINAPI call,not a cdecl
in your c# application you declared it as cdecl
由于几乎所有答案都涉及同一件事,即使如此它也不起作用,我决定更深入地研究 SDK 示例,并意识到我需要再次调用 PrtRead(...) 才能获得正确的结果价值观。
我最终使用:
As almost all the answers where about the same thing, and even so It wasn't working, I decided to look even deeper into the SDK sample, and realized I needed to call PrtRead(...) a second time to get the correct values.
I ended up by using:
我注意到的一件事是您为导入的函数指定了错误的 CallingConvention。
在 C++ 中,WINAPI 被定义为
所以你的 C# 导入应该是
One thing I notice is that you specify the wrong CallingConvention for the imported function.
In C++ WINAPI is defined as
So your C# import should be
使用此处的表进行转换并更正调用约定:
Pinvoke.net
Use the table from here for your conversions and also correct the calling convention:
Pinvoke.net
尝试将其声明为 [MarshalAs(UnManagedType.LPArray)] ulong[] pdwParArray
OK ulong 在 C# 中是一个 64 位整数(在 Windows 7 上),我发现如果我将所有 ulong 更改为 Int32,它适用于我构建的 DLL 函数具有相同的签名。
所以我有:
[DllImport("SPLibNet.dll", CallingConvention=CallingConvention.StdCall)]
公共静态 extern Int32 PrtRead(IntPtr hPtr, Int32 dwTimeout, ref Int32 pdwType,
[MarshalAs(UnmanagedType.LPArray)] Int32[] pdwParArray, ...
我的 DLL 能够在 pdwParArray 中设置值
Try declaring it as [MarshalAs(UnManagedType.LPArray)] ulong[] pdwParArray
OK ulong in C# is a 64-bit integer (on Windows 7) and I found if I changed all the ulong's to Int32's it worked for a DLL function I constructed with the same signature.
So I have:
[DllImport("SPLibNet.dll", CallingConvention=CallingConvention.StdCall)]
public static extern Int32 PrtRead(IntPtr hPtr, Int32 dwTimeout, ref Int32 pdwType,
[MarshalAs(UnmanagedType.LPArray)] Int32[] pdwParArray, ...
And my DLL is able to set values in pdwParArray