Skip to content

[ffigen] C++ functions outside extern "C" are bound to their unmangled name #3666

Open

Description

@jakobkordez

When parsing in C++ mode, ffigen binds a free function declared outside any
extern "C" block to its plain spelling, but the exported symbol is mangled.
Func uses originalName as the lookup symbol (func.dart), and
originalName is the cursor spelling, so C++ linkage is never accounted for.

Example from the existing test suite: int outside(double d) in
test/native_cpp_test/cpp_extern_c_test.h generates a lookup of 'outside',
while the real symbol is ?outside@@YAHN@Z (MSVC) / _Z7outsided (GCC/Clang).
Calling it at runtime fails with a symbol-not-found error. The test only checks
isA<int Function(double)>() and never calls the function, so this goes
unnoticed.

The same applies to Global (global.dart) for variables declared outside
extern "C".

Possible fixes, both with trade-offs:

  • Emit an extern "C" shim via the existing toCppBindingString mechanism
    used by CppClass methods. ABI-portable, but requires compiling the
    generated .cpp, and globals become accessor functions.
  • Bind clang_Cursor_getMangling and look up the mangled symbol. Simpler, but
    the result is ABI-specific to the host that generated the bindings.

At minimum, the test should call outside so the failure is visible, or
ffigen should warn when a C++-linkage function is bound by its unmangled name.

Activity

  1. liamappelbe commented on Sep 21, 2026

    @liamappelbe
    Contributor
    • Emit an extern "C" shim via

    Definitely go with this option. That's the exact approach we're already using for C++ interop.

  2. removed
    needs-triageNeeds triage from the team. Remove this label once triaged.
    on Sep 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions