如何使用 FFI 从 Dart 调用 Go lib

我需要在 中编写一个函数GO,将其编译为共享库,然后从Dart. 例如,要返回一个键,如下面的代码所示:


package main


func getKey() string {

    theKey := "123-456-789"

    return theKey

}


func main() {}


函数式编程
浏览 183回答 1
1回答

GCT1015

答案是:第一部分GO 方面:我们需要使函数可导出,因此名称应大写并变为GetKey()我们需要使用cgo以便我们可以创建共享库,cgo这意味着我们需要:2.1。利用import "C"2.2.&nbsp;将注释与函数一起使用//export GetKey2.3.&nbsp;使用C.type接口,在本例中,代替string使用C.charand&nbsp;C.CString,因为使用指针是更可取的方式,使用*C.char因此,Go问题中的函数应重写为:// filename: lib.gopackage mainimport "C"//export GetKeyfunc GetKey() *C.char {&nbsp; &nbsp; theKey := "123-456-789"&nbsp; &nbsp; return C.CString(theKey)}func main() {}&nbsp;&nbsp;编译上述内容并将共享库创建为:go build -buildmode=c-shared -o lib.a lib.go第二部分Dart 方面:创建pubspec.yaml并添加到它的依赖项中ffi: ^0.1.3,所以它是:name: dart_appdescription: 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.devversion: 1.0.0+1environment:&nbsp; sdk: ">=2.7.0 <3.0.0"dependencies:&nbsp; ffi: ^0.1.3将生成的文件从 GO 复制lib.a到lib.hdart projetc 文件夹创建 dart 文件来处理 FFI,您需要: 3.1. 导入ffi和utf83.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.dartimport 'dart:ffi' as ffi; // For FFIimport 'package:ffi/ffi.dart';import 'package:ffi/src/utf8.dart';typedef get_key_func = ffi.Pointer<Utf8> Function(); // FFI fn signaturetypedef GetKey = ffi.Pointer<Utf8> Function(); // Dart fn signaturefinal dylib = ffi.DynamicLibrary.open('lib.a');final GetKey getKey =&nbsp; &nbsp; dylib.lookup<ffi.NativeFunction<get_key_func>>('GetKey').asFunction();void testffi() {&nbsp; print("Hi from dart");&nbsp; var addressOf = getKey();&nbsp; print(addressOf.ref.toString());}创建主要的 Dart 文件,并导入处理 FFI 的文件,并调用所需的函数,如下所示:// file name lib.dartimport 'fficheck.dart';main() {&nbsp; print("Hello, World!");&nbsp; testffi();}执行 dart 文件为dart main.dart快速注意,不要远离问题的范围,如果你返回一个字符串,那么如果你从代码中调用它,那么这个函数的返回值必须C在 C 代码中显式释放,但是当你从垃圾中调用它时收集器环境,Java/Kotlin 你不想担心它。如果释放分配的缓冲区不方便,通常填充调用者提供的缓冲区:func&nbsp;GetKey(buff&nbsp;*C.char,&nbsp;n&nbsp;int)&nbsp;int如果您可以分配内存但不想处理 C 字符串,则可以将缓冲区插入指针并返回大小。func&nbsp;GetKey(buff&nbsp;**C.char)&nbsp;int
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go