NodeJS中使用N-API(NODE-API)去调用已经存在的dll.

本文介绍如何使用NodeJS的N-API来调用已存在的DLL。首先,通过VS2017创建一个C++动态链接库工程,并实现接口。接着,撰写N-API AddOn模块,调用生成的DLL。最后,配置binding.gyp文件,并通过node-gyp重建项目。在NodeJS中,通过加载addon,即可调用DLL的功能。
摘要由CSDN通过智能技术生成

在之前的一篇文章中,介绍了编写NodeJS AddOn的三种方式,N-API已经是AddOn的未来,N-API摆脱了Node各个大版本引用的chrominum V8不一致导致的API修改的问题。在之前的文章中介绍了N-API是Node team自己维护的,N-API内部会做V8中api匹配的问题。下面用一个例子来学习写一个N-API来调用已经存在的dll.

1. 写一个dll

利用机器上安装的vs2017(各个版本都可以),创建一个c++的动态链接库工程。

在工程里创建一个接口文件InterfaceHeader.h

#pragma once
class InterfaceHeader
{
public:
	virtual ~InterfaceHeader() = default;
public:
	virtual void SetMessage(char const *&& pMsg) = 0;
	virtual char* PrintMessage() = 0;
};

 在动态链接库工程里面创建一个类(ExportHelloWorld)实现这个接口,例如如下声明:

#pragma once
#include "InterfaceHeader.h"
#ifdef EXPORT_API
#define EXPORT_CLASS __declspec(dllexport)
#else
#define EXPORT_CLASS __declspec(dllimport)
#endif
class ExportHelloWorld: public InterfaceHeader
{
public:
	ExportHelloWorld();
	ExportHelloWorld(const char* msg);
	virtual ~ExportHelloWorld();
private:
	char m_Msg[MAX_PATH];
public:
	void SetMessage( const char *&& pMsg) override;
	char* PrintMessage() override;
};

 创建输出API函数声明

extern "C" {
	EXPORT_CLASS InterfaceHeader* CreateHeader();
	EXPORT_CLASS void InvokeHeader();
}

在cpp文件里面实现API和相关的类(ExportHelloWorld),

#include "pch.h"
#include "ExportHelloWorld.h"
ExportHelloWorld::ExportHelloWorld(): m_Msg{0}
{
}

ExportHelloWorld::ExportHelloWorld(const char* msg)
{
	strcpy_s(m_Msg, msg);
}

ExportHelloWorld::~ExportHelloWorld()
{
	m_Msg[0] = 0;
}

void ExportHelloWorld::SetMessage(char const *&& pMsg)
{
	if (strlen(pMsg) > sizeof(m_Msg))
		memcpy(m_Msg, pMsg, sizeof(m_Msg) - 1);
	else
		strcpy_s(m_Msg, pMsg);
}

char* ExportHelloWorld::PrintMessage()
{
	return m_Msg;
}

InterfaceHeader* g_header = nullptr;

InterfaceHeader* CreateHeader()
{
	return new ExportHelloWorld();
}

void InvokeHeader()
{
	if (!!g_header)
		g_header->PrintMessage();
}

编译,生成动态链接库。

2.  撰写N-API add on module

2.1 写code调用刚才产生的dll.

#include "pch.h"
#include <node_api.h>
#include "Common.h"
#include <cstring>
#include <thread>
#include <Windows.h>
#include <WinBase.h>
#include <tchar.h>
#include "../Extention.dll/InterfaceHeader.h"  // we can remove the include_dirs information in binding.gyp
//#include "InterfaceHeader.h"   // we should add include_dirs information in binding.gyp
#
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Node.js是一个使用JavaScript编写的服务器端应用程序环境,它使用事件驱动、非阻塞I/O模型,使得它非常适合在高并发场景下运行。在一些场景下,我们需要将Node.js与一些C/C++语言开发的库进行交互,这时我们可以通过node-ffi或者node-ffi-napi这样的扩展来实现。这些扩展可以让我们在Node.js加载动态链接库(DLL),并且调用DLL的函数。 Node.js加载DLL的方式和C/C++一样,需要通过动态链接库的名称来加载对应的DLL文件。一般来说,我们可以在Node.js使用node-ffi模块来完成动态链接库的加载和函数的调用node-ffi提供了一个简单而直接地API,允许我们从JavaScript代码调用动态链接库函数。要使用node-ffi,我们需要做以下几步: 1. 安装node-ffi:在命令行运行npm install ffi --save命令。 2. 加载DLL文件:使用ffi.Library方法来加载DLL文件。 3. 定义函数类型:使用ffi.Function和ffi.Callback方法来定义函数类型。 4. 调用DLL函数:使用ffi.Library对象的函数名来调用DLL函数。 下面是一个使用node-ffi模块加载DLL文件并调用DLL函数的示例: ``` const ffi = require('ffi'); // 加载DLL文件 const win32 = ffi.Library('kernel32', { 'GetLastError': [ 'int32', [] ] }); // 调用DLL函数,返回错误码 console.log(win32.GetLastError()); ``` 在这个示例,我们使用ffi.Library方法加载了kernel32.dll文件,然后使用GetLastError函数名来调用DLL函数。注意:在不同的操作系统环境DLL文件名称和函数名可能有所不同。 总的来说,Node.js通过node-ffi和node-ffi-napi这些扩展提供了一种简单、快捷的方式来将JavaScript代码与C/C++语言开发的库进行交互。使用这些扩展,我们可以轻松地在Node.js加载DLL文件,调用DLL函数,实现更为复杂的应用程序。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值