实战演练:一步一步的教你nodejs怎么引用c++写的动态链接库

环境:win10+vscode+vs2017+node10

1.新建c++动态链接库

定义一个非常简单的库(因为我不是专业的c++程序员,复杂的不会写~)

--------------sdk.h

#pragma once
#include<string>

class sdk
{
public:
	static __declspec(dllexport) void Test(char* string);
};


---------------sdk.cpp
#include "stdafx.h"
#include "sdk.h"

void  sdk::Test(char* string)
{
	strcpy_s(string, 100, "hello world");
}


2.新建c++扩展项目 myaddon

首先引用依赖项

npm i bindings --save

npm i node-addon-api --save

代码:

-----------------index.js
var addon = require("bindings")("sdkaddon");

console.log(addon.test());


-------------------package.json
{
  "name": "myaddon",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "bindings": "^1.3.1",
    "node-addon-api": "^1.6.2"
  }
}


-------------------------sdkaddon.cc
#include <napi.h>
#include "sdk.h"
#include <iostream>
#include <string>

Napi::String Method(const Napi::CallbackInfo &info)
{
    Napi::Env env = info.Env();
    char str[100];
    sdk::Test(str);
    return Napi::String::New(env, str);
}

Napi::Object Init(Napi::Env env, Napi::Object exports)
{
    exports.Set(Napi::String::New(env, "test"), Napi::Function::New(env, Method));
    return exports;
}

NODE_API_MODULE(sdkaddon, Init)



-------------------------binding.gyp  重要 本地编译必要文件
{
  "targets": [
    {
      "target_name": "sdkaddon",
      'conditions': [
        [ 'OS=="win"', {
            "cflags!": [ "-fno-exceptions" ],
            "cflags_cc!": [ "-fno-exceptions" ],
            "sources": [ "sdkaddon.cc" ],
            "include_dirs": [
              "<!@(node -p \"require('node-addon-api').include\")",
              'sdk/include'
            ],
            'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ],
            'link_settings': {
            'conditions': [
              ['target_arch=="ia32"', {
                'libraries': [
                  '<(PRODUCT_DIR)/../../sdk/lib/x86/sdk.lib',
                ],
                "copies": [
                  {
                    "destination": "build/Release",
                    "files": [
                      "sdk/lib/x86/sdk.dll"
                    ]
                  }
                ]
              },{
                'libraries': [
                  '<(PRODUCT_DIR)/../../sdk/lib/x64/sdk.lib',
                ],
                "copies": [
                  {
                    "destination": "build/Release",
                    "files": [
                      "sdk/lib/x64/sdk.dll"
                    ]
                  }
                ]
              }]
            ],
          },
        }]
      ],
    }
  ]
}

3.编译执行

npm install

node-gyp rebuild

node .\index.js;

输出:hello world。

完成。

对于js&c++大佬这个可能不是什么难事,但是我这个c#程序员还是挺难的,折腾了老几天。。。记录一下希望帮助遇到和我同样问题的人。

全部源码: https://github.com/DaZiYuan/nodejs-dynamiclink-example