我目前在开发一个通过Zenoh协议读取消息的Dart应用程序时遇到了一个具有挑战性的问题。下面是我的问题的分解:
1.我的Dart代码通过Dart:ffi执行原生C代码。(没有问题)
1.然后C代码用数据回调Dart代码(直接回调没有问题)
当我在C代码中引入Zenoh库时,问题就出现了,它创建了一个“订阅者”。每当收到消息时,这个订阅者就会产生线程。这些线程负责处理传入的消息,并将内容回调到我的Dart代码中。
然而,当我尝试从这些线程调用Dart回调函数时,我遇到了以下错误:error: Cannot invoke native callback outside an isolate.
为了解决这个问题,我决定使用Dart:isolate并利用send/ReceivePorts从C线程发送数据。
我不确定我是否正确地处理了这个问题,我也不完全确定我是否完全理解了它。我花了将近四天的时间来解决这个问题,我感到非常困惑和沮丧。
我将非常感谢任何关于如何克服这个障碍并成功地从Zenoh C线程调用Dart回调的见解,建议或指导。提前感谢您的帮助!
Dart Code:
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'dart:isolate';
// typedef Request Callback
typedef RequestCallbackC = Void Function(Int32 port);
typedef RequestCallbackDart = void Function(int port);
class CWrapperZenoh{
late final DynamicLibrary _zenohLib;
late final RequestCallbackDart _requestCallbackDart;
// for native c callback
late final ReceivePort _receivePort;
late final SendPort _sendPort;
CWrapperZenoh(){
_zenohLib = DynamicLibrary.open("bin/include/lib_c_lib.so");
_requestCallbackDart = _zenohLib.lookup<NativeFunction<RequestCallbackC>>
('request_callback').asFunction();
_receivePort = ReceivePort();
_sendPort = _receivePort.sendPort;
// listen
_receivePort.listen((message) {
print("listen message\n");
if (message is String) {
dartCallbackString(message);
} else if (message is int){
print(message);
}
});
}
// application calls this to initiate
callFunctions(){
print("sendport: ${_sendPort.nativePort}");
_requestCallbackDart(_sendPort.nativePort);
}
static void dartCallbackString(String s) {
print("Received string from C: $s\n");
}
字符串
}
C库:
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "zenoh.h"
#include "include/dart_api.h"
#include "include/dart_api_dl.h"
#include <pthread.h>
// define Dart callback function
typedef void (*DartFunction)(const char*);
z_owned_config_t* config_ptr;
z_owned_session_t* sessionPtr;
z_owned_subscriber_t* sub;
z_owned_closure_sample_t callback;
Dart_Port dart_port;
DartFunction dartFunction;
void callbackFuncToDart(const z_sample_t *sample, void *arg);
void request_callback(Dart_Port port){
dart_port = port;
// config
config_ptr = malloc(sizeof(z_owned_config_t));
if (config_ptr != NULL) {
*config_ptr = zc_config_from_file("bin/include/DEFAULT_CONFIG_CONNECT.json5");
}
printf("config created\n");
fflush(stdout);
// open session
sessionPtr = (z_owned_session_t*)malloc(sizeof(z_owned_session_t));
*sessionPtr = z_open(config_ptr);
// subscribing
z_owned_closure_sample_t callback = z_closure(callbackFuncToDart);
sub = malloc(sizeof(z_owned_subscriber_t));
*sub = z_declare_subscriber(z_loan(*sessionPtr), z_keyexpr("geometry_msgs/msg/actualSpeed"), z_move(callback), NULL);
}
// callback to Dart
void callbackFuncToDart(const z_sample_t *sample, void *arg) {
// Create a SendPort to communicate with Dart isolate
Dart_Handle sendPort = Dart_NewSendPort(dart_port);
// Check if creating the SendPort was successful
if (!Dart_IsError(sendPort)) {
Dart_CObject message;
message.type = Dart_CObject_kInt32;
message.value.as_int32 = 1;
// Send the message using the SendPort
if (Dart_PostCObject(dart_port, &message)){
printf("Message sent\n");
fflush(stdout);
} else {
printf("Failed to create SendPort\n");
fflush(stdout);
}
}
//--Removed old irelevant code. comment relevant for my first threaded callback attempt--
//dartFunction(str); // different thread id than Darts "Main isolate". therefore i get the following: "error: Cannot invoke native callback outside an isolate."
}
型
1条答案
按热度按时间7eumitmz1#
自从我发布这个问题以来发生了很多事情,我不知道是什么原因导致了这个确切的问题。
在我的C库中,
字符串
然后在我的Dart构造函数中调用它
型