ffigen renames struct members with a $1 suffix if they share a name with a top-level function in the generated bindings, even if the struct member is scoped within a class and shouldn't conflict.
Minimal Reproducible Example
C Header (example.h)
typedef struct {
void (*FindClass)(void);
} JniEnv;
void FindClass(void);
2. Reproduction Script (repro.dart)
import 'package:ffigen/ffigen.dart';
import 'dart:io';
void main() {
final generator = FfiGenerator(
output: Output(dartFile: Uri.file('bindings.dart')),
headers: Headers(entryPoints: [Platform.script.resolve('example.h')]),
structs: Structs.includeAll,
functions: Functions.includeAll,
);
generator.generate();
}
3. Generated Dart (bindings.dart)
// ...
@ffi.Native<ffi.Void Function()>()
external void FindClass();
final class JniEnv extends ffi.Struct {
external ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> FindClass$1;
}
Expected Behavior
The struct member FindClass should retain its name, as it is a member of the JniEnv class/struct and does not conflict with the top-level FindClass function in Dart.
Actual Behavior
The struct member is renamed to FindClass$1.
ffigenrenames struct members with a$1suffix if they share a name with a top-level function in the generated bindings, even if the struct member is scoped within a class and shouldn't conflict.Minimal Reproducible Example
C Header (
example.h)2. Reproduction Script (
repro.dart)3. Generated Dart (
bindings.dart)Expected Behavior
The struct member
FindClassshould retain its name, as it is a member of theJniEnvclass/struct and does not conflict with the top-levelFindClassfunction in Dart.Actual Behavior
The struct member is renamed to
FindClass$1.