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 關注
- 170 瀏覽
添加回答
舉報