亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用 FFI 從 Dart 調用 Go lib

如何使用 FFI 從 Dart 調用 Go lib

Go
函數式編程 2022-06-27 15:57:29
我需要在 中編寫一個函數GO,將其編譯為共享庫,然后從Dart. 例如,要返回一個鍵,如下面的代碼所示:package mainfunc getKey() string {    theKey := "123-456-789"    return theKey}func main() {}
查看完整描述

1 回答

?
GCT1015

TA貢獻1827條經驗 獲得超4個贊

答案是:

第一部分GO 方面:

  1. 我們需要使函數可導出,因此名稱應大寫并變為GetKey()

  2. 我們需要使用cgo以便我們可以創建共享庫,cgo這意味著我們需要:

2.1。利用import "C"

2.2. 將注釋與函數一起使用//export GetKey

2.3. 使用C.type接口,在本例中,代替string使用C.charand 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

http://img1.sycdn.imooc.com//62b9631400010cda12580551.jpg

快速注意,不要遠離問題的范圍,如果你返回一個字符串,那么如果你從代碼中調用它,那么這個函數的返回值必須C在 C 代碼中顯式釋放,但是當你從垃圾中調用它時收集器環境,Java/Kotlin 你不想擔心它。

如果釋放分配的緩沖區不方便,通常填充調用者提供的緩沖區:

func GetKey(buff *C.char, n int) int

如果您可以分配內存但不想處理 C 字符串,則可以將緩沖區插入指針并返回大小。

func GetKey(buff **C.char) int


查看完整回答
反對 回復 2022-06-27
  • 1 回答
  • 0 關注
  • 170 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號