@@ -16,6 +16,8 @@ Rust. For more details, see https://dart.dev/guides/libraries/c-interop.
1616FFIgen also has experimental support for calling ObjC and Swift code;
1717for details see https://dart.dev/guides/libraries/objective-c-interop .
1818
19+ More FFIgen documentation can be found [ here] ( doc/README.md ) .
20+
1921## Getting Started
2022
2123This guide demonstrates how to call a custom C API from a standalone Dart
@@ -955,305 +957,3 @@ include-transitive-objc-categories: false
955957 </tr>
956958</tbody>
957959</table>
958-
959- # # FAQ
960-
961- # ## Can FFIgen be used for removing underscores or renaming declarations?
962-
963- FFIgen supports **regexp-based renaming**. The regexp must be a full match.
964- For renaming you can use regexp groups (`$1` means group 1).
965-
966- To renaming `clang_dispose_string` to `string_dispose` we can match it using
967- ` clang_(.*)_(.*)` and rename with `$2_$1`.
968-
969- Here's an example of how to remove prefix underscores from any struct and its
970- members.
971-
972- ` ` ` yaml
973- structs:
974- ...
975- rename:
976- '_(.*)': '$1' # Removes prefix underscores from all structures.
977- member-rename:
978- '.*': # Matches any struct.
979- '_(.*)': '$1' # Removes prefix underscores from members.
980- ` ` `
981- # ## How to generate declarations only from particular headers?
982-
983- The default behavior is to include everything directly/transitively under
984- each of the `entry-points` specified.
985-
986- If you only want to have declarations directly particular header you can do so
987- using `include-directives`. You can use **glob matching** to match header paths.
988-
989- ` ` ` yaml
990- headers:
991- entry-points:
992- - 'path/to/my_header.h'
993- include-directives:
994- - '**my_header.h' # This glob pattern matches the header path.
995- ` ` `
996- # ## Can FFIgen filter declarations by name?
997-
998- FFIgen supports including/excluding declarations using full regexp matching.
999-
1000- Here's an example to filter functions using names :
1001-
1002- ` ` ` yaml
1003- functions:
1004- include:
1005- - 'clang.*' # Include all functions starting with clang.
1006- exclude:
1007- - '.*dispose': # Exclude all functions ending with dispose.
1008- ` ` `
1009-
1010- This will include `clang_help`. But will exclude `clang_dispose`.
1011-
1012- Note : exclude overrides include.
1013-
1014- # ## How does FFIgen handle C Strings?
1015-
1016- FFIgen treats `char*` just as any other pointer (`Pointer<Int8>`).
1017- To convert these to/from `String`, you can use [package:ffi](https://pub.dev/packages/ffi).
1018- Use `ptr.cast<Utf8>().toDartString()` to convert `char*` to dart `string` and
1019- ` "str".toNativeUtf8()` to convert `string` to `char*`.
1020-
1021- # ## How are unnamed enums handled?
1022-
1023- Unnamed enums are handled separately, under the key `unnamed-enums`, and are
1024- generated as top level constants.
1025-
1026- Here's an example that shows how to include/exclude/rename unnamed enums :
1027-
1028- ` ` ` yaml
1029- unnamed-enums:
1030- include:
1031- - 'CX_.*'
1032- exclude:
1033- - '.*Flag'
1034- rename:
1035- 'CXType_(.*)': '$1'
1036- ` ` `
1037-
1038- # ## How can I handle unexpected enum values?
1039-
1040- Native enums are, by default, generated into Dart enums with `int get value` and
1041- ` fromValue(int)` . This works well in the case that your enums values are known
1042- in advance and not going to change, and in return, you get the full benefits of
1043- Dart enums like exhaustiveness checking.
1044-
1045- However, if a native library adds another possible enum value after you generate
1046- your bindings, and this new value is passed to your Dart code, this will result
1047- in an `ArgumentError` at runtime. To fix this, you can regenerate the bindings
1048- on the new header file, but if you wish to avoid this issue entirely, you can
1049- tell FFIgen to generate plain Dart integers for your enum instead. To do this,
1050- simply list your enum's name in the `as-int` section of your FFIgen config :
1051-
1052- ` ` ` yaml
1053- enums:
1054- as-int:
1055- include:
1056- - MyIntegerEnum
1057- - '*IntegerEnum'
1058- exclude:
1059- - FakeIntegerEnum
1060- ` ` `
1061-
1062- Functions that accept or return these enums will now accept or return integers
1063- instead, and it will be up to your code to map integer values to behavior and
1064- handle invalid values. But your code will be future-proof against new additions
1065- to the enums.
1066-
1067- # ## Why are some struct/union declarations generated even after excluded them in config?
1068-
1069- This happens when an excluded struct/union is a dependency to some included
1070- declaration. (A dependency means a struct is being passed/returned by a function
1071- or is member of another struct in some way.)
1072-
1073- Note : If you supply `structs.dependency-only` as `opaque` FFIgen will generate
1074- these struct dependencies as `Opaque` if they were only passed by reference
1075- (pointer).
1076-
1077- ` ` ` yaml
1078- structs:
1079- dependency-only: opaque
1080- unions:
1081- dependency-only: opaque
1082- ` ` `
1083-
1084- # ## How to expose the native pointers?
1085-
1086- By default, the native pointers are private, but you can use the
1087- ` symbol-address` subkey for functions/globals and make them public by matching
1088- with its name. The pointers are then accessible via `nativeLibrary.addresses`.
1089-
1090- Example :
1091-
1092- ` ` ` yaml
1093- functions:
1094- symbol-address:
1095- include:
1096- - 'myFunc' # Match function name.
1097- - '.*' # Do this to expose all function pointers.
1098- exclude: # If you only use exclude, then everything not excluded is generated.
1099- - 'dispose'
1100- ` ` `
1101-
1102- # ## How to get typedefs to Native and Dart type of a function?
1103-
1104- By default, these types are inline. But you can use the `expose-typedef` subkey
1105- for functions to generate them. This will expose the Native and Dart type.
1106- E.g. for a function named `hello` the generated typedefs are named as
1107- ` NativeHello` and `DartHello`.
1108-
1109- Example :
1110-
1111- ` ` ` yaml
1112- functions:
1113- expose-typedefs:
1114- include:
1115- - 'myFunc' # Match function name.
1116- - '.*' # Do this to expose types for all functions.
1117- exclude: # If you only use exclude, then everything not excluded is generated.
1118- - 'dispose'
1119- ` ` `
1120-
1121- # ## How are Structs/Unions/Enums that are referred to via typedefs handled?
1122-
1123- Named declarations use their own names even when inside another typedef.
1124- However, unnamed declarations inside typedefs take the name of the _first_
1125- typedef that refers to them.
1126-
1127- # ## Why are some typedefs not generated?
1128-
1129- The following typedefs are not generated :
1130- - They are not referred to anywhere in the included declarations.
1131- - They refer to a struct/union having the same name as itself.
1132- - They refer to a boolean, enum, inline array, Handle or any unsupported type.
1133-
1134- # ## How are macros handled?
1135-
1136- FFIgen uses `clang`'s own compiler frontend to parse and traverse the `C`
1137- header files. FFIgen expands the macros using `clang`'s macro expansion and
1138- then traverses the expanded code. To do this, FFIgen generates temporary files
1139- in a system tmp directory.
1140-
1141- A custom temporary directory can be specified by setting the `TEST_TMPDIR`
1142- environment variable.
1143-
1144- # ## What are these logs generated by FFIgen and how to fix them?
1145-
1146- FFIgen can sometimes generate a lot of logs, especially when it's parsing a lot
1147- of code.
1148- - ` SEVERE` logs are something you *definitely need to address*. They can be
1149- caused due to syntax errors, or more generally missing header files
1150- (which need to be specified using `compiler-opts` in config).
1151- - ` WARNING` logs are something *you can ignore*, but should probably look into.
1152- These are mostly indications of declarations FFIgen couldn't generate due
1153- to limitations of `dart:ffi`, private declarations (which can be resolved
1154- by renaming them via FFIgen's config) or other minor issues in the config
1155- file itself.
1156- - Everything else can be safely ignored. Its purpose is to simply let you know
1157- what FFIgen is doing.
1158- - The verbosity of the logs can be changed by adding a flag with
1159- the log level, e.g. `dart run ffigen --verbose <level>`.
1160- Level options are `[all, fine, info (default), warning, severe]`.
1161- The `all` and `fine` will print a ton of logs are meant for debugging
1162- purposes only.
1163-
1164- # ## How can type definitions be shared?
1165-
1166- FFIgen can share type definitions using symbol files.
1167- - A package can generate a symbol file using the `output.symbol-file` config.
1168- - And another package can then import this, using `import.symbol-files` config.
1169- - Doing so will reuse all the types such as Struct/Unions, and will automatically
1170- exclude generating other types (E.g. functions, enums, macros).
1171-
1172- Checkout `examples/shared_bindings` for details.
1173-
1174- For manually reusing definitions from another package, the `library-imports`
1175- and `type-map` config can be used.
1176-
1177- # ## How does ObjC method filtering work?
1178-
1179- Methods and properties on ObjC interfaces and protocols can be filtered using
1180- the `member-filter` option under `objc-interfaces` and `objc-protocols`. For
1181- simplicity we'll focus on interface methods, but the same rules apply to
1182- properties and protocols. There are two parts to the filtering process : matching
1183- the interface, and then filtering the method.
1184-
1185- The syntax of `member-filter` is a YAML map from a pattern to some
1186- ` include` /`exclude` rules, and `include` and `exclude` are each a list of
1187- patterns.
1188-
1189- ` ` ` yaml
1190- objc-interfaces:
1191- member-filter:
1192- MyInterface: # Matches an interface.
1193- include:
1194- - "someMethod:withArg:" # Matches a method.
1195- exclude:
1196- - someOtherMethod # Matches a method.
1197- ` ` `
1198-
1199- The interface matching logic is the same as the matching logic for the
1200- `member-rename` option :
1201-
1202- - The pattern is compared against the original name of the interface (before any
1203- renaming is applied).
1204- - The pattern may be a string or a regexp, but in either case they must match
1205- the entire interface name.
1206- - If the pattern contains only alphanumeric characters, or `_`, it is treated as
1207- a string rather than a regex.
1208- - String patterns take precedence over regexps. That is, if an interface matches
1209- both a regexp pattern, and a string pattern, it uses the string pattern's
1210- ` include` /`exclude` rules.
1211-
1212- The method filtering logic uses the same `include`/`exclude` rules as the rest
1213- of the config :
1214-
1215- - ` include` and `exclude` are a list of patterns.
1216- - The patterns are compared against the original name of the method, before
1217- renaming.
1218- - The patterns can be strings or regexps, but must match the entire method name.
1219- - The method name is in ObjC selector syntax, which means that the method name
1220- and all the external parameter names are concatenated together with `:`
1221- characters. This is the same name you'll see in ObjC's API documentation.
1222- - **NOTE:** Since the pattern must match the entire method name, and most ObjC
1223- method names end with a `:`, it's a good idea to surround the pattern with
1224- quotes, `"`. Otherwise, YAML will think you're defining a map key.
1225- - If no `include` or `exclude` rules are defined, all methods are included,
1226- regardless of the top level `exclude-all-by-default` rule.
1227- - If only `include` rules are `defined`, all non-matching methods are excluded.
1228- - If only `exclude` rules are `defined`, all non-matching methods are included.
1229- - If both `include` and `exclude` rules are defined, the `exclude` rules take
1230- precedence. That is, if a method name matches both an `include` rule and an
1231- ` exclude` rule, the method is excluded. All non-matching methods are also
1232- excluded.
1233-
1234- The property filtering rules live in the same `objc-interfaces.member-filter`
1235- option as the methods. There is no distinction between methods and properties in
1236- the filters. The protocol filtering rules live in
1237- ` objc-protocols.member-filter` .
1238-
1239- # ## How do I generate bindings for Apple APIs?
1240-
1241- It can be tricky to locate header files containing Apple's ObjC frameworks, and
1242- the paths can vary between computers depending on which version of Xcode you are
1243- using and where it is installed. So FFIgen provides the following variable
1244- substitutions that can be used in the `headers.entry-points` list :
1245-
1246- - `$XCODE` : Replaced with the result of `xcode-select -p`, which is the
1247- directory where Xcode's APIs are installed.
1248- - `$IOS_SDK` : Replaced with `xcrun --show-sdk-path --sdk iphoneos`, which is the
1249- directory within `$XCODE` where the iOS SDK is installed.
1250- - `$MACOS_SDK` : Replaced with `xcrun --show-sdk-path --sdk macosx`, which is the
1251- directory within `$XCODE` where the macOS SDK is installed.
1252-
1253- For example :
1254-
1255- ` ` ` Yaml
1256- headers:
1257- entry-points:
1258- - '$MACOS_SDK/System/Library/Frameworks/Foundation.framework/Headers/NSDate.h'
1259- ` ` `
0 commit comments