打电话给 C++ C# 应用程序中的 DLL 方法

发布于 2024-12-29 22:04:28 字数 2743 浏览 0 评论 0原文

我正在尝试在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

无需解释 2025-01-05 22:04:28

你说的方法是WINAPI调用,而不是cdecl
在您的 C# 应用程序中,您将其声明为 cdecl

you said the method is a WINAPI call,not a cdecl
in your c# application you declared it as cdecl

放飞的风筝 2025-01-05 22:04:28

由于几乎所有答案都涉及同一件事,即使如此它也不起作用,我决定更深入地研究 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);

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:

[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);
背叛残局 2025-01-05 22:04:28

我注意到的一件事是您为导入的函数指定了错误的 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);

One thing I notice is that you specify the wrong CallingConvention for the imported function.

In C++ WINAPI is defined as

#define WINAPI __stdcall

So your C# import should be

[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);
桜花祭 2025-01-05 22:04:28

使用此处的表进行转换并更正调用约定:
Pinvoke.net

Use the table from here for your conversions and also correct the calling convention:
Pinvoke.net

梦幻之岛 2025-01-05 22:04:28

尝试将其声明为 [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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文