如何在Electron中调用Dll客户端的一些硬件接口需要调试,连接到电脑上的一些硬件设备,比如打印机,扫描仪,或者串口通讯。光靠JS是做不到的。我们决定将这些功能用C++或者C#封装成Dll,然后在Electron客户端通过Node调用Dll来实现需要的功能。Dll类型先简单说一下什么是Dll。dll是动态链接库文件,也是代码库的一种形式。相对于静态链接库,每次程序运行时都会调用,静态链接库指令会被打包到最终的exe文件中,所以如果功能有变化,需要重新生成exe,并且动态链接库不需要这样做。生成Dll可以通过VS来完成。您可以选择使用C#或C++进行开发。C#开发界面更方便。如果你的功能需要弹出一些界面,需要用C#写相应的Dll。不过这里要注意,用C#语言编写生成的Dll和用C++语言编写生成的Dll是不一样的。C#生成的Dll需要.net开发环境,而C++生成的Dll没有限制。Node如何调用Dll在Electron中调用Dll其实就是node调用Dll。刚才说了,生成的Dll不一样,所以调用方式也不一样。我使用了ffi和edge这两个模块,使用ffi调用C++生成的Dll,使用edge调用C#生成的Dll。ffi调用Dll。比如我这里有一个ffiTest.dll文件。有一个名为joinStr的导出函数,它是一个暴露的方法。给定两个字符串,返回这两个参数的拼接结果。注意C++生成的Dll要使用C风格的extern"C",否则可能找不到对应的方法名。varffi=require('ffi');varpath=require('path');vardllPath=path.resolve('ffiTest.dll');varlib=ffi.Library(dllPath,{'joinStr':['string',['string','string']],})varresult=lib.joinStr('hello','world');控制台日志(结果);//printhelloworld更详细的例子可以参考它的教程。ffi.Library中的第二个参数是一个Json结构,key代表方法名,value代表一个数组。数组的第一个参数是返回值类型,第二个参数是方法列表。如果返回值为空,则数组的第一个参数应为void。如果返回值或参数类型未知,写void*。用ffi中的类型来表示C/C++语言中的类型,对照表如下基本类型int8Signed8-bitIntegeruint8Unsigned8-bitIntegerint16Signed16-bitIntegeruint16Unsigned16-bitIntegerint32Signed32-bitIntegeruint32Unsigned32-bitIntegerint64Signed64-bitIntegeruint64Unsigned64-bitIntegerfloat单精度浮点数(float)double双精度浮点数(double)pointerPointerTypestringNull-TerminatedString(char*)常见的C语言类型byteunsignedcharcharcharucharunsignedshortushortunsignedshortintintuintunsignedintlonglongulongunsignedlonglonglonglongulonglongunsignedlonglongsize_t平台相关,通常是指针大小如果是指针类型,可以使用ref模块来表示。varref=require('ref');varrefArray=require('ref-array');varintPtr=ref.refType('int');//int*typevarcharPtr='hello';//char*可以用string表示//如果是字符数组varrefArray=require('ref-array');varcharPtrPtr=refArray(ref.types.char,50);//50个大小的数组如果参数或者返回值是结构体,那么就需要用ref-struct模块来表示varref=require('ref');varFFI=require('ffi');varStruct=require('ref-struct');varTimeVal=Struct({'tv_sec':'long','tv_usec':'long'});varTimeValPtr=ref.refType(TimeVal);varlib=newFFI。库(null,{'gettimeofday':['int',[TimeValPtr,'pointer']]});vartv=newTimeVal();lib.gettimeofday(tv.ref(),null);console.log("自纪元以来的秒数:"+tv.tv_sec);edgecallsDlledge这个模块非常强大,不仅可以在node中编写C#代码还可以在C#中调用node代码,需要.net4.5以上版本环境C#写的Dll被node调用前必须先async修改,大致是这样classStartUp{publicasyncTask
