实战演练:一步一步的教你 nodejs 怎么引用 c++写的动态链接库 环境:win10+vscode+vs2017+node10


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

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
--------------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

代码:

1
2
3
4
-----------------index.js;
var addon = require("bindings")("sdkaddon");

console.log(addon.test());
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
-------------------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)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
-------------------------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. 编译执行

1
2
3
4
npm install
node-gyp rebuild
node .\index.js;
输出:hello world。

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

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