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 |
方法返回: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中设置值