docs/ffigen.md
2024-10-18 10:20:13 +08:00

120 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ffigen
源文件代码如下
```c
#ifndef HELLO_H
#define HELLO_H
#include "ppp.h" // 为了使用struct Point
#include <stdio.h> // 标准库文件
void hello();
void say_hello(const char* name);
void say_hello2(struct Point* p);
#endif
```
只想生成当前文件下的函数声明,而不生成有关标准库里面的内容
```yaml
# pubsspey.yaml
headers:
entry-points:
- "clibrary/hello.h"
include-directives:
- "**hello.h" # 使用相对路径不管用
```
生成出来的dart代码没有标准库中的符号。
但是自动生成ppp.h中有关struct Point 结构体的相关内容say_hello2函数参数用到了
```dart
class Point extends ffi.Struct {
@ffi.Int32()
external int TID;
@ffi.Int32()
external int type;
@ffi.Int32()
......
}
```
如果不关心结构体具体内容
```yaml
# pubsspey.yaml
structs:
dependency-only: opaque
```
生成的代码如下
```dart
class Point extends ffi.Opaque {} // error 需要手动修改
// 修改后
final class Point extends ffi.Opaque {}
```
ffi生成的class 有错误 需要手动更改
```dart
final class Point extends ffi.Struct {
@ffi.Int32()
external int x;
} // 正确
class Point extends ffi.Struct {
@ffi.Int32()
external int x;
}// 错误缺少final ffigen自动生成的
```
未避免每次生成都需要手动更改
解决方案第一次通过ffi生成后将class复制到另外一个文件中 bindings.dart。但是生成的dart代码中找不到Point类型需要引入bindings.dart这个文件。于是需要进行配置
使生成的代码自动引入class所在的dart文件
```yaml
library-imports:
point: 'bindings.dart' # @1 point需要引入dart文件也可以引入其他package bindings存放了class Point
type-map:
'structs': # Point是结构体.
'Point': # 依赖的C语言中的结构体名称
'lib': 'point' # @1 名字自定义
'c-type': 'Point' # import 'bindings.dart' as point ffi.Pointer<point.Point> // point文件中具体要使用的类型
'dart-type': 'point'
```
```dart
import 'bindings.dart' as point // @1;
......
void say_hello2(
ffi.Pointer<point.Point> p,
) {
return _say_hello2(
p,
);
}
late final _say_hello2Ptr =
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<point.Point>)>>(
'say_hello2');
late final _say_hello2 =
_say_hello2Ptr.asFunction<void Function(ffi.Pointer<point.Point>)>();
```
生成的代码中既没有错误的class Point 也不需要手动引入正确的dart Point类