この記事を書く主な動機は、cgo と Dart FFI を使用して Dart 言語から Go コードを呼び出すことに関する情報が (特にロシア語を話すコミュニティで) 大幅に不足しているという事実です。
Dart 言語は、その人気が高まっているにもかかわらず、現時点では Go 言語と同じ大きなコミュニティを持っていません。Dart は他のタスクの実行を対象としているため、Go がすでに備えている実装や機能が含まれていない場合があります。
go コードの Dart へのエクスポート (たとえば、既製のライブラリのエクスポート) を回避できる場合は、cgo を使用せず、この機会を利用することをお勧めします。ただし、go を dart コードに絞り込むことが最適なソリューションである場合もあります (たとえば、Go と Dart に既に慣れていて、C でコードを記述したくない場合など、cgo の使用を検討するのが理にかなっていますおよびダート FFI)。
この記事では、簡単な例を使用して、Dart 言語から Go コードを呼び出す方法を示します (たとえば、Flutter アプリケーションで)。
インストールする必要があるもの:
行く
ダーツ
テキスト エディター / IDE (VSCode を使用します。これは Dart および Go コミュニティの中で最も人気のある環境であるため、Go および Flutter 言語をサポートするための特別なプラグインもインストールされます)
ステップ 1 - 空の Dart コンソール アプリケーションを作成する
Command Palette F1 Dart, Console Application ( , cgo Flutter Dart).
, cgo_dartffi_helloworld, . ( Dart, ffi pubspec.yaml ).
.
2 - ffi yaml
ffi yaml go dart.
name: cgo_dartffi_helloworld
description: A sample command-line application.
version: 1.0.0
environment:
sdk: '>=2.12.0 <3.0.0'
dependencies:
path: ^1.8.0
ffi: ^0.1.3
dev_dependencies:
pedantic: ^1.10.0
test: ^1.16.0
3 - .go
go, ( , lib.go) Dart. - HelloFromGo().
// filename: lib.go
package main
import "C"
//export HelloFromGo
func HelloFromGo() *C.char {
message := "Hello to dart lang from go"
return C.CString(message)
}
func main() {}
cgo , . cgo (, ), ( export). cgo https://golang.org/cmd/cgo/, .
4 - go
:
go build -buildmode=c-shared -o lib.a lib.go
lib.a ( c ). ( , go, go, cgo).
5 -
:
:
pubspec.yaml
lib.h, lib.a lib.go
bin dart ( )
6 - cgo Dart
( ) . ( ), .
6.1 - bin/cgo_dartffi_helloworld.dart
6.2 - ( ffi utf8 )
import 'dart:ffi' as ffi;
import 'package:ffi/src/utf8.dart';
6.3 -
final dylib = ffi.DynamicLibrary.open('lib.a');
6.4 - dart
typedef HelloFromGo = ffi.Pointer<Utf8> Function();
typedef HelloFromGoFunc = ffi.Pointer<Utf8> Function();
final HelloFromGo _finalFunction = dylib
.lookup<ffi.NativeFunction<HelloFromGoFunc>>('HelloFromGo')
.asFunction();
6.5 - ( , .toDartString C Dart):
void main() {
print(_finalFunction().toDartString());
}
go, string Dart.
さらに、関数を作成するときは、Go、C、および Dart 言語のデータ形式が異なる可能性があることを考慮に入れる必要があります (多くの場合、これが発生します)。詳細については、次のリンクを参照してください。
完全な Dart コード:
import 'dart:ffi' as ffi;
import 'package:ffi/src/utf8.dart';
final dylib = ffi.DynamicLibrary.open('lib.a');
typedef HelloFromGo = ffi.Pointer<Utf8> Function();
typedef HelloFromGoFunc = ffi.Pointer<Utf8> Function();
final HelloFromGo _finalFunction = dylib
.lookup<ffi.NativeFunction<HelloFromGoFunc>>('HelloFromGo')
.asFunction();
void main() {
print(_finalFunction().toDartString());
}
呼び出された関数にパラメーターを渡す必要がある場合は、ポインターを使用して、呼び出された関数でそれらを宣言できます。次に例を示します。
typedef GetHash = Pointer<Utf8> Function(Pointer<Utf8> str);
typedef GetHashFunc = Pointer<Utf8> Function(Pointer<Utf8> str);
final GetHash _getHashGoFunction =
_lib.lookup<NativeFunction<GetHashFunc>>('GetHash').asFunction();
覚えておくべき主なことは、送信されたデータの形式を確認する必要があることです。