Dart 使用动态链接库¶
您可以访问 WordPress 版本以获得不一样的体验。
本文使用 ffigen
包为 Dart 生成动态链接库的绑定。
前置知识¶
- Dart 开发基础
- Go 开发基础
- 动态链接库概念
本文默认读者已经了解以上知识。若未了解,请读者自行查阅资料。
示例¶
以下是一个使用 Go 语言生成动态链接库并使用 Dart 调用其导出的函数的示例。
环境¶
- 系统
- 版本:Windows 10 专业工作站版
- 操作系统内部版本:19045.3803
- 开发环境
- Go :
go1.23.2 windows/amd64
- Dart :
3.6.1 (stable) (Tue Jan 7 09:50:00 2025 -0800) on "windows_x64"
ffi: ^2.1.3
ffigen: ^15.0.0
- LLVM:
19.1.7
- 安装路径:
D:\App\Runtime\LLVM
- 安装路径:
完整流程¶
Go 部分 - 生成动态链接库¶
新建一个名为 go-test 的文件夹。
在 go-test 下运行指令:
go mod init go-test
新建文件 main.go
,内容如下:
package main
import "C"
//export Add
func Add(a, b int) int {
return a + b
}
func main() {}
保存后 main.go
后运行指令:
go build -o add.dll -buildmode=c-shared main.go
此时 go-test 下的结构如下:
.
├── add.dll
├── add.h
├── go.mod
├── main.go
0 directories, 4 files
至此,Go 部分即动态链接库的生成已经完成,接下来就是 Dart 部分即动态链接库的调用。
Dart 部分 - 调用动态链接库¶
新建一个名为 ffi_test 的文件夹。
在 ffi_test 下运行指令:
dart create . --force
使用以下指令将 ffigen 添加至 dev_dependencies:
dart pub add -d ffigen
将前面生成的 add.h
复制到 lib/lib_headers
下。
新建文件 ffigen.yaml
,内容如下:
name: GoAddLibAutoGen
output: 'lib/goaddlib_bindings.dart'
headers:
entry-points:
- 'lib/lib_headers/add.h'
llvm-path: ['D:\\App\\Runtime\\LLVM']
保存 ffigen.yaml
后运行指令:
dart run ffigen --config ffigen.yaml
此时 ffi_test 下的结构如下:
.
├── CHANGELOG.md
├── README.md
├── analysis_options.yaml
├── bin
│ └── ffi_test.dart
├── ffigen.yaml
├── lib
│ ├── ffi_test.dart
│ ├── goaddlib_bindings.dart
│ └── lib_headers
│ └── add.h
├── pubspec.lock
├── pubspec.yaml
└── test
└── ffi_test_test.dart
4 directories, 11 files
新建文件 lib/ff.dart
,内容如下:
import 'dart:ffi';
import 'dart:io';
import 'package:ffi_test/goaddlib_bindings.dart' as goaddlib_bindings;
List<DynamicLibrary> _libs4 = [
DynamicLibrary.open(Platform.isWindows ? "add.dll" : "add.so"),
];
Pointer<T> _looup<T extends NativeType>(String symbolName) {
for (final i in _libs4) {
if (i.providesSymbol(symbolName)) {
return i.lookup(symbolName);
}
}
throw Exception("can not find the symbol $symbolName from library");
}
final ff = goaddlib_bindings.GoAddLibAutoGen.fromLookup(_looup);
保存 lib/ff.dart
后修改 bin/ffi_test.dart
,内容如下:
import 'package:ffi_test/ffi_test.dart' as ffi_test;
import 'package:ffi_test/ff.dart';
void main(List<String> arguments) {
print('Hello world: ${ffi_test.calculate()}!');
print('ff.Add(1, 2): ${ff.Add(1, 2)}');
}
保存 bin/ffi_test.dart
后新建文件夹 compile/exe
并运行指令:
dart compile exe .\bin\ffi_test.dart -o .\compile\exe\ffi_test.exe
将前面生成的 add.dll
复制到 compile/exe
下后,运行指令:
.\compile\exe\ffi_test.exe
此时命令行中便会输出:
Hello world: 42!
ff.Add(1, 2): 3