@@ -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