1 回答

TA贡献1827条经验 获得超4个赞
答案是:
第一部分GO 方面:
我们需要使函数可导出,因此名称应大写并变为
GetKey()
我们需要使用
cgo
以便我们可以创建共享库,cgo
这意味着我们需要:
2.1。利用import "C"
2.2. 将注释与函数一起使用//export GetKey
2.3. 使用C.type
接口,在本例中,代替string
使用C.char
and C.CString
,因为使用指针是更可取的方式,使用*C.char
因此,Go
问题中的函数应重写为:
// filename: lib.go
package main
import "C"
//export GetKey
func GetKey() *C.char {
theKey := "123-456-789"
return C.CString(theKey)
}
func main() {}
编译上述内容并将共享库创建为:
go build -buildmode=c-shared -o lib.a lib.go
第二部分Dart 方面:
创建pubspec.yaml并添加到它的依赖项中ffi: ^0.1.3,所以它是:
name: dart_app
description: A new Dart application.
# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
ffi: ^0.1.3
将生成的文件从 GO 复制lib.a到lib.hdart projetc 文件夹
创建 dart 文件来处理 FFI,您需要: 3.1. 导入ffi和utf8
3.2. 将 FFI 函数签名定义为typedef get_key_func = ffi.Pointer<Utf8> Function();
3.3. 将 Dart 函数签名定义为typedef GetKey = ffi.Pointer<Utf8> Function();
3.4. 将共享库加载为final dylib = ffi.DynamicLibrary.open('lib.a');
3.5. 将 FFI 和 Dart 函数签名映射为final GetKey getKey dylib.lookup<ffi.NativeFunction<get_key_func>>('GetKey').asFunction();
3.6. 定义一个函数来执行,并在这个函数内部执行以下操作:
3.6.1. 调用 Dart 函数并将输出分配给一个变量var addressOf = getKey();
3.6.2. 解码结果,即指针的地址,并从中获取字符串,如下所示:print(addressOf.ref.toString());
因此,Dart 代码将变为:
//file name fficheck.dart
import 'dart:ffi' as ffi; // For FFI
import 'package:ffi/ffi.dart';
import 'package:ffi/src/utf8.dart';
typedef get_key_func = ffi.Pointer<Utf8> Function(); // FFI fn signature
typedef GetKey = ffi.Pointer<Utf8> Function(); // Dart fn signature
final dylib = ffi.DynamicLibrary.open('lib.a');
final GetKey getKey =
dylib.lookup<ffi.NativeFunction<get_key_func>>('GetKey').asFunction();
void testffi() {
print("Hi from dart");
var addressOf = getKey();
print(addressOf.ref.toString());
}
创建主要的 Dart 文件,并导入处理 FFI 的文件,并调用所需的函数,如下所示:
// file name lib.dart
import 'fficheck.dart';
main() {
print("Hello, World!");
testffi();
}
执行 dart 文件为dart main.dart
快速注意,不要远离问题的范围,如果你返回一个字符串,那么如果你从代码中调用它,那么这个函数的返回值必须C
在 C 代码中显式释放,但是当你从垃圾中调用它时收集器环境,Java/Kotlin 你不想担心它。
如果释放分配的缓冲区不方便,通常填充调用者提供的缓冲区:
func GetKey(buff *C.char, n int) int
如果您可以分配内存但不想处理 C 字符串,则可以将缓冲区插入指针并返回大小。
func GetKey(buff **C.char) int
- 1 回答
- 0 关注
- 182 浏览
添加回答
举报