感觉好窝囊,被一个自认为简单的小问题绊了一整天
发布于 5 年前 作者 misland 4480 次浏览 来自 问答

是这样的,我在研究一个技术可行性,就是通过Nodejs调用C++的dll,目前通过ffi这个插件实现的,我对C++并不熟悉,前面自己写了个测试的C++的dll调用成功了,证明可行,于是继续研究调用一个视频采集卡的dll,本以为很简单,结果第一个方法就被挡住了。 C++头文件中方法声明如下: QCAP_CREATE( CHAR * pszDevName /*IN*/, UINT iDevNum /*IN*/, HWND hAttachedWindow /*IN*/, PVOID * ppDevice /*OUT*/, BOOL bThumbDraw = FALSE /*IN*/, BOOL bMaintainAspectRatio = FALSE /*IN*/ ); 这个方法的第三个参数要求传递一个窗口的句柄,用于显示采集卡的影像,当然也可以不传,传一个空指针也行,由于要跨语言,类型转换是个大问题,为了稳妥起见,我先在我熟悉的C#里试了一下,调用具体代码如下:

[DllImport(@"D:\01work\01code\video\code\VideoDemo\CPlusPlus\obj\Debug\QCAP.X64.DLL", EntryPoint = "QCAP_CREATE")]
public static extern ulong QCAP_CREATE(string deviceName, UInt32 iDevNum, IntPtr hAttachedWindow, out IntPtr ppDevice, bool bThumbDraw, bool bMaintainAspectRatio);
//引入后调用
var result = QCAP_CREATE("CY3014 USB", 0, IntPtr.Zero, out ppDevice, true, false);

第三个参数通过IntPtr.Zero传递一个空的指针,很顺利就成功了,以为很简单,于是继续在Node中试验,对于类型我使用了ref这个工具包来向dll传递参数,具体代码如下:

 const ffi = require('ffi');
const ref = require('ref');
const path = require('path');
let dllPath = path.join(__dirname, '/QCAP.X64');
let intPtr = ref.refType('int');
let QCAP = ffi.Library(dllPath, {
  'QCAP_CREATE': [ref.types.ulong, [ref.types.CString, ref.types.uint, intPtr, intPtr, ref.types.bool, ref.types.bool]]
});
  let ppdevice = ref.alloc('int');
  let NULL = ref.NULL;
  //初始化采集卡
 let initResult = QCAP.QCAP_CREATE('CY3014 USB', 0, NULL, ppdevice, true, false);

我看了ref的源码,ref.NULL的解释如下: **A Buffer that references the C NULL pointer. ** 于是上面最后一行代码第三个参数我试图通过ref.NULL传递一个空指针,结果方法始终提示第三个参数错误,各种google和百度,折腾了一天还是无果,感觉好沮丧,来社区请教一下社区的老师们,有没有哪位老师能指点一下呢,任何帮助都很感谢

11 回复

ref.NULL_POINTER

@justjavac 我也试了传递NULL_POINTER,依然提示相同的问题

实在不行就用wine运行你的C#程序去调用,wine不是虚拟机,比真win系统慢也是因为要实时解释。

没用过ffi,你看下能不能初始化个int类型的空指针或者void类型的指针。还有Null和empty有一定区别,这点要注意。

想问一下最后有结果了吗? 我也被这个卡了好久

@remenwang 大兄弟你是怎么翻出来的,我们该不会是同一个问题吧.

传个空 Buffer 过去试试

 let initResult = QCAP.QCAP_CREATE('CY3014 USB', 0, new Buffer([]), ppdevice, true, false);

是这样吗?

回到顶部