How to return a struct from a Go function to Dart?
Is it possible to send back a struct from the Go function to Dart?
Could you add an example to send a struct from Go to Dart and how to handle the received struct in the Dart side?
The simplest way to send a struct over is to allocate it with C.malloc and then send the pointer to it as an int64 to Dart. On the Dart side you can use Pointer<...>.fromAddress to create a pointer object and then work with the struct.
Hey, thanks for the quick reply.
Like you said, I tried to allocate struct to malloc and then send the pointer as int64 to Dart.
But Dart is picking the message from Go as the int 5 which basically (pWork->a=5;)
dart_api_dl.go:
// // Go does not allow calling C function pointers directly. So we are
// // forced to provide a trampoline.
// bool GoDart_PostCObject(Dart_Port_DL port, Dart_CObject* obj) {
// return Dart_PostCObject_DL(port, obj);
// }
//
// typedef struct Work{
// int64_t a;
// int64_t b;
// }Work;
//
// void GetWork(void **ppWork) {
// Work *pWork= (Work *)malloc(sizeof(Work));
// pWork->a=5;
// pWork->b=6;
// *ppWork = pWork;
// }
import "C"
func Init(api unsafe.Pointer) C.long {
return C.Dart_InitializeApiDL(api)
}
type Work struct {
a int64
b int64
}
func SendToPort(port int64, msg int64) {
var obj C.Dart_CObject
obj._type = C.Dart_CObject_kInt64
var pwork unsafe.Pointer
C.GetWork(&pwork)
work := *(*Work)(pwork)
unsafePtr := (*int64)(unsafe.Pointer(&work))
*(*C.int64_t)(unsafe.Pointer(&obj.value[0])) = C.int64_t(*unsafePtr)
C.GoDart_PostCObject(C.int64_t(port), &obj)
}
Dart side:
Future<void> run() async {
_squashArchiverLib.InitializeDartApi(NativeApi.initializeApiDLData);
final interactiveCppRequests = ReceivePort();
final interactiveCppSub = interactiveCppRequests.listen((data) {
print(data); // <---------outputs 5---------->
/*final work = Pointer<Work>.fromAddress(data as int);
print(work.ref.a);
print(work.ref.b);*/
});
final nativePort = interactiveCppRequests.sendPort.nativePort;
_squashArchiverLib.StartWork(nativePort);
}
Git repo: https://github.com/ganeshrvel/squash_archiver/blob/feature/go-archiver-example/packages/archiver_ffi/native/archiver_lib/dart_api_dl/dart_api_dl.go
I am not able to return the pointer address of the struct back to Dart, always the value of the struct is returned. Am I doing it right? Any suggestions will be appreciated.
I got it working.
If anyone else is looking for an answer here, this is what i did. I first did a cast of the struct ptr using uint64_t in the GetWork and returned the value back.
// int64_t GetWork(void **ppWork) {
// Work *pWork= (Work *)malloc(sizeof(Work));
// pWork->a=16;
// pWork->b=15;
// *ppWork = pWork;
//
// int64_t ptr = (int64_t)pWork;
//
// return ptr;
// }
func SendToPort(port int64, msg int64) {
var obj C.Dart_CObject
obj._type = C.Dart_CObject_kInt64
var pwork unsafe.Pointer
ptrAddr := C.GetWork(&pwork)
*(*C.int64_t)(unsafe.Pointer(&obj.value[0])) = ptrAddr
C.GoDart_PostCObject(C.int64_t(port), &obj)
defer C.free(pwork)
}
Dart side:
final interactiveCppSub = interactiveCppRequests.listen((data) {
final work = Pointer<Work>.fromAddress(data as int);
print(work.ref.a);
print(work.ref.b);
});
Thanks a lot for the suggestions. You had been a great help!