从C#应用程序调用C ++ DLL方法

Call a C++ DLL method from a C# application

我试图从C++的DLL中使用一个C语言项目中的方法,但是我在调用它时遇到了问题。方法如下:

如SDK手册所述

<罢工>dword winapi prtread(句柄hprt、dword dwtimeout、dword*pdwtype、lpdword pdwpararray、lpdword pdwarraySize、lpbyte pbreaddata、lpdword pdwaredatalen)< /打击>

如代码中的定义

1
extern"C" __declspec(dllimport) DWORD PrtRead (HANDLE hPRT, DWORD dwTimeout, DWORD *pdwType, LPDWORD pdwParArray, LPDWORD pdwArraySize,LPBYTE  pbReadData, LPDWORD pdwReadDataLen);

在SDK C++样本中,他们这样称呼:

1
2
3
4
5
6
DWORD       dwPar[2];
pdwParArray = &dwPar[0];
dwPar[0] = 0;
dwPar[1] = 0;

DWORD dwRet = PrtRead(hPrinter, dwCurrentTimeout, &dwType, pdwParArray, &dwArraySize, NULL, &dwReadDataLen);

我的问题是获取值lpdword pdwparary。

dll总是在位置[0]中返回以下值之一:1、2或20,并在位置[1]中返回:1、2或4,但我要取消缩放才能执行此操作。

我试着这样定义导入:

1
2
[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);

像这样改变了

方法定义:

1
out ulong[] pdwParArray

变量初始化:

1
ulong[] pdwParArray;

方法返回:

1
pdwParArray = null

方法定义:

1
ref ulong[] pdwParArray

变量初始化:

1
2
3
ulong[] pdwParArray = new ulong[2];
pdwParArray[0] = 0;
pdwParArray[1] = 0;

方法返回:pdwpararray[0]=0;pdwpararray[1]=越界数组索引;

方法定义:Out Ulong Pdwpararray公司

变量初始化:ulong[]pdwpararray=新ulong[2];

方法返回:pdwpararray[0]=0;pdwpararray[1]=0;

方法定义:参考文件:乌隆·普德帕拉里

变量初始化:ulong[]pdwpararray=新ulong[2];

方法返回:pdwpararray[0]=0;pdwpararray[1]=0;

我应该如何在C导入中定义lpdword pdwparary,如何初始化它并调用它?

提前谢谢

1
2
3
4
_
_
_
_

编辑:@专题病理学家

使用这些结果尝试了以下操作:

定义:

[marshalas(unmanagedType.lparray)]ulong[]pdwpararray

结果:

pdwpararray[0]=0;

pdwpararray[1]=0;

定义:

[marshalas(unmanagedType.lparray)]out ulong[]pdwpararray

结果:

pdwpararray[0]=空;

pdwpararray[1]=空;

定义:

[marshalas(unmanagedType.lparray)]ulong pdwpararray

结果:

无法封送"参数4":无效的托管/非托管类型组合(Int64/UInt64必须与I8或U8成对出现)。

定义:

[marshalas(unmadefinition:nagedtype.lparray)]out ulong pdwpararray

结果:

无法封送"参数4":无效的托管/非托管类型组合(Int64/UInt64必须与I8或U8成对出现)。


你说这个方法是winapi调用,不是cdecl在您的C申请中,您将其声明为CDECL。


由于几乎所有关于同一件事情的答案都是一样的,即使它不起作用,我决定更深入地研究sdk示例,并意识到我需要第二次调用prtread(…)来获得正确的值。

最后我用了:

1
2
[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);


使用此处的表进行转换,并更正调用约定:小精灵


我注意到的一件事是您为导入的函数指定了错误的调用约定。

在C++中,WiLAPI被定义为

1
#define WINAPI __stdcall

所以你的C进口应该是

1
2
[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);


尝试将其声明为[marshalas(unmanagedType.lparray)]ulong[]pdwpararray

好的,c_中的ulong是一个64位整数(在Windows7上),我发现如果我把所有的ulong都改成int32,它就可以用于我用相同签名构造的dll函数。

所以我有:[dllimport("splibnet.dll",callingConvention=callingConvention.stdcall)]公共静态外部Int32 prtread(Intptr hptr,Int32 dwTimeout,Ref Int32 pdwType,[marshalas(unmanagedtype.lparray)]int32[]pdwpararray,…

我的dll可以在pdwparary中设置值