Skip to content

[ffigen] Struct Member Renamed Due to Top-Level Function Collision #2850

Description

@HosseinYousefi

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.

Activity

  1. vikramsingh920 commented on Oct 1, 2026

    @vikramsingh920
    Contributor

    "Hi @dcharkes @liamappelbe, is this issue still open to take? I'm looking into ffigen issues. I would like to investigate this member renaming collision and submit a PR with unit tests. Could you please assign this to me?"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions