[NodeJs] 调用Go dll文件

GO

  • 安装 Gcc tdm-gcc (jmeubank.github.io)

win64位下载地址:https://github.com/jmeubank/tdm-gcc/releases/download/v10.3.0-tdm64-2/tdm64-gcc-10.3.0-2.exe

  • 步骤

  1. 设置编译环境为64位 GOARCH=amd64 ,如果想设置为32位 GOARCH=386
  2. 需要生成动态库的文件必须要符合以下条件
    a. import "C"
    b. main函数
    c.导出的函数首字母必须大写
    d.函数前必须要放//export (函数名)
  3. 生成 dll 或者 os 文件

import "C" : 如果在Go代码中出现了import "C"语句则表示使用了CGO特性,紧跟在这行语句前面的注释是一种特殊语法,里面包含的是正常的C语言代码。

  • 编写 dll

package main

/*
#include 
*/
import "C"
import "unsafe"

func main() {

}

var result *C.char

//export Create
func Create(p *C.char) *C.char {
    v := C.GoString(p)
    result = C.CString(v)
    return result
}

//export Free
func Free()  {
    C.free(unsafe.Pointer(result))
}

Create :方法体,其中参数为 *C.char 类型,接收NodeJs传递过来的 string 类型参数,返回也是 *C.char 类型,返回为 string 类型返回值。
其中
C.GoString() (转换C字符串为go字符串),
C.CString() (转换go的字符串为C字符串,C中的字符串是使用malloc分配的,所以需要调用C.free来释放内存)

✨这里有一点要说明下,Create 返回类型为 *C.char ,nodejs 那边才能拿到对应字符串类型数据,但是因为需要 通过 C.CString() 转换成C对应的字符串才能返回,但是使用了 C.CString() 就需要面临 C.free 释放内存,我通过 defer C.free(unsafe.Pointer()) 去释放,释放后返回值就出现了问题,但是不释放我测试了下 10W 次调用 Create 方法,内存就一直递增,没办法我只有写一个专用的方法来释放内存...

Free : 方法体,释放 C.CString() 分配的内存,原因上面说明,我不晓得有啥其他解决方法,懂C 和 Go 的大大们,有啥解决方法帮我留个言,我确实不晓得咋个搞了....
C.free()是存在 stdlib.h 库中的,所以需要在 import "C"上注释增加:

/*
#include 
*/

注释与 import "C" 之间不能有换行、空格。

Go中写C代码,可以了解下 CGO入门了解传送门
  • 编译 动态库

// test.dll 是windows 动态库
go build -o test.dll -buildmode=c-shared main.go

// test.so 是mac 动态库
go build -o test.so -buildmode=c-shared main.go

NodeJs

  • 准备工作

  • 安装 cnpm 淘宝 NPM 镜像 (npmmirror.com)

npm install -g cnpm --registry=https://registry.npmmirror.com

  • 安装 Python 2.7 Python 2.7.0 Release | Python.org

win64位下载地址:https://www.python.org/ftp/python/2.7/python-2.7.amd64.msi

  • 全局安装 windows-build-tools 工具包

cnpm install --global --production windows-build-tools

  • 安装 windows-build-tools 卡住时可参考 安装 windows-build-tools 卡在 Python 2.7 - (jianshu.com)
  • 安装 node-ffi-napi

cnpm install ffi-napi

  • 使用方式

const ffi = require("ffi-napi")
const path = require("path")

const Dll = ffi.Library(path.resolve("dll/t.dll"), {
    Create: ["string", ["string"]],
    Free: ["void", []]
})
Dll.Create("哈哈哈哈!!!!!!!!!!")
Dll.Free();

使用 ffi.Library 加载 dll 文件,其中 CreateFree 为 dll 暴露的方法名,[] 中第一个参数为返回值类型, 第二个参数也是 [] 数组,为方法体的参数类型,多个以逗号分隔。

然后直接通过 Dll 调用对应声明的方法体就行了!!! Over!!!

然后,各位大大们,帮我看下上面提到的 Go 里面如何释放 C.CString , 然后我也能返回 string 类型值 ♂️,感谢!!!

你可能感兴趣的:([NodeJs] 调用Go dll文件)