执行dart run ffigen出现如下错误:
Unhandled exception:\nInvalid argument(s): Failed to load dynamic library '/Users/bruce/homebrew/opt/llvm/lib/libclang.dylib': dlopen(/Users/bruce/homebrew/opt/llvm/lib/libclang.dylib, 0x0001): tried: '/Users/bruce/homebrew/opt/llvm/lib/libclang.dylib' (mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64')), '/Users/bruce/homebrew/Cellar/llvm/13.0.1_1/lib/libclang.dylib' (mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64'))\n#0 _open (dart:ffi-patch/ffi_dynamic_library_patch.dart:12:43)\n#1 new DynamicLibrary.open (dart:ffi-patch/ffi_dynamic_library_patch.dart:23:12)\n#2 initializeGlobals (package:ffigen/src/header_parser/data.dart:41:33)\n#3 initParser (package:ffigen/src/header_parser/parser.dart:48:3)\n#4 parse (package:ffigen/src/header_parser/parser.dart:22:3)\n#5 main (package:ffigen/src/executables/ffigen.dart:54:19)\n#6 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:295:32)\n#7 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)\nRun Code Online (Sandbox Code Playgroud)\n我检查了我的 Flutter 环境:
\n\xe2\x9d\xaf file /Users/bruce/dev_tools/flutter/bin/cache/dart-sdk/bin/dart\n/Users/bruce/dev_tools/flutter/bin/cache/dart-sdk/bin/dart: Mach-O 64-bit executable x86_64\nRun Code Online (Sandbox Code Playgroud)\n当我运行brew install llvm安装 llvm 时,我得到的是 …
/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/ffi-0.1.3/lib/src/utf8.dart:63:33: 错误:getter 'addressOf' 未定义对于“Utf8”类。
报告前请仔细阅读。
我的 flutter web 项目运行得很好。几个小时后,它开始抱怨 'dart:ffi: 我什至没有导入。我看到了类似的问题,但没有一个是我的情况。我尝试了所有能找到的东西,但没有任何效果。以下是错误:
/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/drift-1.7.1/lib/src/sqlite3/database_tracker.dart:1:8: Error: Not found: 'dart:ffi'
import 'dart:ffi';
^
/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/sqlite3-1.8.0/lib/src/ffi/api/database.dart:1:8: Error: Not found: 'dart:ffi'
import 'dart:ffi';
^
/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/sqlite3-1.8.0/lib/src/ffi/api/statement.dart:1:8: Error: Not found: 'dart:ffi'
import 'dart:ffi';
^
/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/sqlite3-1.8.0/lib/open.dart:5:8: Error: Not found: 'dart:ffi'
import 'dart:ffi';
^
...
Failed to compile application.
Exited (sigterm)
Run Code Online (Sandbox Code Playgroud)
我无法包含整个调试控制台的输出,但这些是顶线和底线。请帮忙,谢谢。
您好,我正在使用 dart:ffi 与我的本机 c/c++ 库构建一个接口。我需要一种方法来获取从 c 到 dart 的回调,例如在 sqlite 中:
int sqlite3_exec(
sqlite3*, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
void *, /* 1st argument to callback */
char **errmsg /* Error msg written here */
);
Run Code Online (Sandbox Code Playgroud)
in 的第三个参数sqlite3_exec是指向回调的函数指针。所以如果我在 dart 中使用调用这个函数,ffi我需要传递一个函数指针:在dart:ffi Pointer类中有一个名为fromFunctionwitch的函数接受一个 dart 静态函数和一个exceptionalReturn; 但是仅仅通过调用这个函数来获取一个 dart 托管函数的函数指针:a(sigterm)被引发并且 dart 代码不再在这个过程中工作。
所以我的问题:有没有办法在 dart 中获得本机回调,如在 Python、c#、..
额外:有什么方法可以包含 …
我有一个 Flutter 应用程序,用于Dart ffi连接到我的自定义 C++ 音频后端。在那里我为我的音频缓冲区分配了大约 10MB 的总内存。每个缓冲区有 10MB / 84 的内存。我使用 84 音频播放器。这是 ffi 流程:
C++ 桥:
extern "C" __attribute__((visibility("default"))) __attribute__((used))
void *
loadMedia(char *filePath, int8_t *mediaLoadPointer, int64_t *currentPositionPtr, int8_t *mediaID) {
LOGD("loadMedia %s", filePath);
if (soundEngine == nullptr) {
soundEngine = new SoundEngine();
}
return soundEngine->loadMedia(filePath, mediaLoadPointer, currentPositionPtr, mediaID);
}
Run Code Online (Sandbox Code Playgroud)
在我的声音引擎中,我启动了一个 C++ 线程:
void loadMedia(){
std::thread{startDecoderWorker,
buffer,
}.detach();
}
void startDecoderWorker(float*buffer){
buffer = new float[30000]; // 30000 might be wrong here, I entered a huge value …Run Code Online (Sandbox Code Playgroud) 我现在正在学习 Dart,并且正在研究 Dart 与 C 的互操作性。我能够使用带有两个 int 参数的 C 方法。代码如下:
你好.dart
import 'dart:ffi' as ffi;
typedef sum_func = ffi.Int32 Function(ffi.Int32 a, ffi.Int32 b);
typedef Sum = int Function(int a, int b);
...
final dylib = ffi.DynamicLibrary.open(path);
final sumPointer = dylib.lookup<ffi.NativeFunction<sum_func>>('sum');
final sum = sumPointer.asFunction<Sum>();
print('3 + 5 = ${sum(3, 5)}');
Run Code Online (Sandbox Code Playgroud)
你好ç
int sum(int a, int b){
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
你好.h
int add(int x, int y)
Run Code Online (Sandbox Code Playgroud)
你好.def
LIBRARY hello
EXPORTS
sum
Run Code Online (Sandbox Code Playgroud)
这一切都运行得很好,但我还想要一个maxC 方法,它将 int 数组作为输入并返回最大的数字。我怎样才能做到这一点?我已经用 C 实现了所有必需的代码,但我不确定如何将其与 …
我正在致力于为 Dart 公开一个音频库(C 库)。要触发音频引擎,需要一些初始化步骤(对于 UI 来说是非阻塞的),然后使用执行函数触发音频处理,该函数是阻塞的(音频处理是一项繁重的任务)。这就是我开始阅读有关 Dart 分离株的原因。
我的第一个想法是我只需要调用isolate中的性能方法,但这似乎不可能,因为perform函数将引擎状态作为第一个参数 - 这个引擎状态是一个不透明的指针(dart中的指针:ffi )。当尝试使用计算函数将引擎状态传递给新的隔离时,Dart VM 返回错误 - 它无法将 C 指针传递给隔离。
我找不到一种方法将此数据传递给隔离区,我认为这是由于主隔离区和我正在创建的隔离区的内存不同所致。
因此,我可能应该在隔离中管理整个引擎状态,这意味着:
我找不到任何有关如何在隔离中执行此操作的示例,而是从主线程/隔离触发。也没有讨论如何管理隔离内存(保持引擎状态并使用它)。我当然可以
这是我想要做的一个非孤立的例子:
Pointer<Void> engineState = createEngineState();
initEngine(engineState, parametersString);
startEngine(engineState);
perform(engineState);
Run Code Online (Sandbox Code Playgroud)
在运行时,由 UI 操作触发(例如滑块值更改或单击按钮):
setEngineControl(engineState, valueToSet);
double controleValue = getEngineControl(engineState);
Run Code Online (Sandbox Code Playgroud)
引擎状态可以封装在一个类中,我认为这在这里并不重要。无论是类还是不透明的数据类型,我都找不到如何管理和保持这种状态,并从主线程执行触发器(在隔离中处理)。任何想法 ?
提前谢谢。
PS:我注意到,在写作时,我的问题/解释可能不准确,我不得不说我在这里有点迷失,因为我从未使用过 Dart Isolates。如果缺少某些信息,请告诉我。
4 月 24 日编辑:它似乎正在创建和管理 Isolate 内的对象状态。但主要问题还没有解决。因为执行方法在未完成时实际上是阻塞的,所以无法在隔离中仍然接收消息。我首先想到的一个选项是使用 PerformBlock 方法,该方法仅执行音频样本块。像这样 :
while(performBlock(engineState)) {
// listen messages, and do something
}
Run Code Online (Sandbox Code Playgroud)
但这似乎不起作用,进程仍然被阻塞,直到音频表演结束。即使在隔离中的异步方法中调用此循环,它也会阻塞,并且不会读取任何消息。
我现在考虑将Pointer<Void>主隔离中的托管传递给另一个的可能性,这将是工作人员(仅适用于执行方法),然后能够从主隔离中触发一些控制方法。
isolate Dart包提供了一个注册表子库来管理一些共享内存。但在isolates之间传递void指针仍然是不可能的。
[错误:flutter/lib/ui/ui_dart_state.cc(157)] 未处理的异常:无效参数:本机对象(来自 dart:ffi),例如指针和结构不能在隔离之间传递。
有人遇到过这种情况吗?
我一直在尝试在我的 Flutter 应用程序中使用 Android NDK 的AssetManager类(它与Google Oboe配合使用)来访问音频文件。按照Oboe 存储库中的这个示例,我了解到他们是AssetManager这样从 Java 获取的:
JNIEXPORT void JNICALL
Java_com_google_oboe_sample_rhythmgame_MainActivity_native_1onStart(JNIEnv *env, jobject instance,
jobject jAssetManager) {
AAssetManager *assetManager = AAssetManager_fromJava(env, jAssetManager);
if (assetManager == nullptr) {
LOGE("Could not obtain the AAssetManager");
return;
}
game = std::make_unique<Game>(*assetManager);
game->start();
}
Run Code Online (Sandbox Code Playgroud)
基本上,它们通过 JNI 接口将参数jAssetManager从 Java 传递到 C++ 函数。现在我不使用 JNI,因为我使用 Flutter 和 Dart,Dart 中与 C++ 函数通信的方式是通过dart:ffi,但由于我可以创建的唯一方法AssetManager是 with AAssetManager_fromJava(env, jAssetManager),所以我需要这两个参数我找不到用 Flutter 和 Dart 替代的方法。
我做了一些研究,当我创建 Flutter FFI …
我试图让我的代码在为 ffi 分配内存时更加健壮。
我写了以下函数:
void withMemory<T extends NativeType>(
int size, void Function(Pointer<T> memory) action) {
final memory = calloc<Int8>(size);
try {
action(memory.cast());
} finally {
calloc.free(memory);
}
}
Run Code Online (Sandbox Code Playgroud)
为了调用上面的函数,我使用:
withMemory<Uint32>(sizeOf<Uint32>(), (phToken) {
// use the memory allocated to phToken
});
Run Code Online (Sandbox Code Playgroud)
这是可行的,但正如你所看到的,我需要传递 Uint32 两次以及sizeOf.
我真正想写的是:
withMemory<Uint32>((phToken) {
// use the memory allocated to phToken
});
Run Code Online (Sandbox Code Playgroud)
问题是您无法将泛型类型传递给以下calloc任何一个sizeOf错误:
[...] 的类型参数必须是编译时常量,但类型参数不是常量。尝试将类型参数更改为常量类型。
有什么办法可以解决这个问题吗?