Skip to content

Declare the Prime string functions in CFFIPrime.h included after CFFI.h - #426

Open
Tutez64 wants to merge 1 commit into
openfl:mainfrom
Tutez64:fix/cffi-prime-after-cffi
Open

Tutez64 wants to merge 1 commit into
openfl:mainfrom
Tutez64:fix/cffi-prime-after-cffi

Conversation

@Tutez64

@Tutez64 Tutez64 commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Since 1e6417d (#323), a native extension that includes hx/CFFI.h before hx/CFFIPrime.h no longer compiles:

include/hx/CFFIPrime.h:497:8: error: 'hxs_encoding' was not declared in this scope
include/hx/CFFIPrime.h:499:38: error: 'hxs_utf16' was not declared in this scope
include/hx/CFFIPrime.h:531:8: error: 'hxs_encoding' was not declared in this scope
include/hx/CFFIPrime.h:536:11: error: 'alloc_hxs_utf8' was not declared in this scope

SteamWrap is one of them:

#define IMPLEMENT_API
#include <hx/CFFI.h>
#include <hx/CFFIPrime.h>

CFFIAPI.h declares the Prime string functions only under HXCPP_PRIME, which CFFIPrime.h defines before it includes CFFI.h. Included first, CFFI.h declares the API without them, and the inclusion from CFFIPrime.h then does nothing. The ordinary wrapper of a DEFINE_PRIME function now uses three of them. The tests only include CFFIPrime.h, so CI did not see it.

CFFIAPI.h now defines HX_CFFI_PRIME_DECLARED when it declares them, and declares only them under HX_CFFI_PRIME_ONLY. When they are missing, CFFIPrime.h includes it that way, so the wrapper keeps Unicode strings whatever the include order. An ndll resolves each function the first time it is called, so declaring them later changes nothing else. Under neko, with CFFI.h first, CFFILoader.h has no defaults for alloc_hxs_utf8 and hxs_utf16, but hxs_encoding's default answers UTF-8, so neither is called.

Tests: test/regression/CffiPrimeAfterCffi builds an ndll that includes CFFI.h before CFFIPrime.h and passes strings that are not ASCII through the wrapper, both ways. Before, its ndll failed to compile. It is skipped on Emscripten, as CffiPrimeUnicodeFallback is. The other Cffi* cases pass, and both include orders compile with IMPLEMENT_API, with STATIC_LINK and with neither.

CFFIAPI.h declares hxs_encoding, hxs_utf16, alloc_hxs_utf8 and the other
Prime string functions only under HXCPP_PRIME, which CFFIPrime.h defines
before it includes CFFI.h. An extension that includes CFFI.h first, as
SteamWrap does, gets the API without them, and CFFIPrime.h's own
inclusion of CFFI.h then does nothing. Since 1e6417d, the ordinary
wrapper of a DEFINE_PRIME function uses three of them, so such an
extension no longer compiled.

CFFIAPI.h now marks that it declared them, and with HX_CFFI_PRIME_ONLY
declares them alone. CFFIPrime.h includes it that way when they are
missing, so the wrapper keeps Unicode strings whatever the order. An ndll
resolves each function the first time it is called, so declaring them
later changes nothing else. Under neko, CFFI.h included first leaves out
the defaults of alloc_hxs_utf8 and hxs_utf16, but hxs_encoding's default
answers UTF-8, so neither is called.

Tests: test/regression/CffiPrimeAfterCffi builds an ndll that includes
CFFI.h before CFFIPrime.h and passes strings that are not ASCII through
the wrapper. Before, the ndll failed to compile. The other Cffi* cases
pass, and both include orders compile with IMPLEMENT_API, STATIC_LINK
and neither.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant