[NodeJs] 调用Go dll文件

2021-03-17  本文已影响0人  卓灬不凡

GO

  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语言代码。

package main

/*
#include <stdlib.h>
*/
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 <stdlib.h>
*/

注释与 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

npm 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 类型值 🤷♂️,感谢!!!
上一篇 下一篇

猜你喜欢

热点阅读