连接到动态库
注意: 下面的示例主要针对的是使用Golang生成的动态库
生成动态库
使用C语言字符串参数
// 你需要导入C
import "C"
// 在需要导出的动态库上添加export注解,注意export前面没有空格,函数名开头大写
//export Connect
func Connect(s1 *C.char, s2 *C.char) *C.char {
gs1 := C.GoString(s1)
gs2 := C.GoString(s2)
return C.CString(gs1 + " " + gs2)
}
导出动态库
通过下面的命令导出动态库
# macOS & iOS
go build -o lib.dylib -buildmode=c-shared main.go
# Windows
go build -o lib.dll -buildmode=c-shared main.go
将动态库打包到App内部
可以参考官方文档
连接到动态库
将动态库存储为Dart函数
import 'dart:ffi';
// 定义类型,一个为动态库函数,一个为Dart函数,注意这两个类型完全不同
// 如果是返回字符串(指针)的函数则可以不区分
typedef Add = int Function(int, int);
typedef AddFunc = Int Function(Int, Int);
// 如果是字符串可以这样只保留一个typedef
typedef CharSet=Pointer<Utf8> Function(Pointer<Utf8>);
// 绑定动态库
final dynamicLib=DynamicLibrary.open(Platform.isMacOS ? 'lib.dylib' : 'lib.dll');
// 绑定函数
final Add add=dynamicLib
.lookup<NativeFunction<AddFunc>>('Add')
.asFunction();
// 如果是返回字符串的函数
final CharSet charSet=dynamicLib
.lookup<NativeFunction<CharSet>>('CharSet')
.asFunction();
运行函数
短时间调用
// 如果不含字符串可以直接调用
final newNum=add(1, 2);
// 如果含有字符串
// 注意传递的参数和返回值都需要转换
final String data=charSet("Hello World!!!".toNativeUtf8()).toDartString();
持续调用
可以使用await异步运行
static void isolateFunction(List params){
final dynamicLib=DynamicLibrary.open(Platform.isMacOS ? 'lib.dylib' : 'lib.dll');
final Add add=dynamicLib
.lookup<NativeFunction<AddFunc>>('Add')
.asFunction();
add(params[0], params[1]);
}
await compute(isolateFunction, [param1, param2]);
持续运行
防止执行过程中程序卡死
static void isolateFunction(List params){
final dynamicLib=DynamicLibrary.open(Platform.isMacOS ? 'lib.dylib' : 'lib.dll');
final Add add=dynamicLib
.lookup<NativeFunction<AddFunc>>('Add')
.asFunction();
add(params[0], params[1]);
}
// 注意这里如果使用compute会导致一直等待isolateFunction结束运行
await Isolate.spawn(isolateFunction, [param1, param2]);