Skip to content

Update from master.#50

Merged
SineVector241 merged 7 commits intodevfrom
master
Apr 8, 2026
Merged

Update from master.#50
SineVector241 merged 7 commits intodevfrom
master

Conversation

@SineVector241
Copy link
Copy Markdown
Member

No description provided.

SineVector241 and others added 7 commits April 2, 2026 09:47
…calling convention

On ARM64 Apple Silicon (macOS and iOS), the C ABI passes variadic
arguments (those after `...`) on the stack, while fixed arguments are
passed in registers. The opus `_ctl` functions (opus_encoder_ctl,
opus_decoder_ctl, opus_multistream_encoder_ctl, etc.) are all variadic
C functions. When C# P/Invoke calls these functions, it marshals all
parameters as fixed arguments in registers. The native opus library
expects the variadic arguments on the stack, reads uninitialized memory
instead, and returns OPUS_BAD_ARG.

This issue only affects Apple ARM64 platforms. On x86-64, Linux ARM64,
and Android ARM64, the variadic and non-variadic calling conventions
are identical, so P/Invoke works correctly by coincidence.

The fix introduces a small C shim library (opus_shim.c) containing 20
non-variadic wrapper functions — one for each P/Invoke CTL overload.
Since the shim is compiled natively, the compiler correctly handles the
variadic forwarding to the underlying opus CTL functions. The shim is
compiled into the same native binary (opus.dylib, opus.dll, opus.so,
libopus.a) on all platforms, avoiding conditional compilation in C# and
ensuring consistent behavior everywhere.

Changes:
- Add OpusSharp.Natives/opus_shim.c with non-variadic wrappers for all
  opus_encoder_ctl, opus_decoder_ctl, opus_dred_decoder_ctl,
  opus_multistream_encoder_ctl, and opus_multistream_decoder_ctl
  overloads (20 functions total)
- Update NativeOpus.cs and StaticNativeOpus.cs to use EntryPoint
  attributes pointing to the shim function names (40 declarations each)
- Update OpusCompile.yml to build opus as a static library first, then
  compile the shim and link both into a single shared library for each
  platform (or add the shim object to the static archive for iOS/Wasm)

The C# method names and signatures are unchanged, so no calling code
in downstream projects requires modification.
fix: resolve OPUS_BAD_ARG on ARM64 Apple Silicon due to variadic CTL calling convention
- Windows: map CMake arch names (Win32, x64, ARM64) to vcvarsall
  equivalents (x86, amd64, amd64_arm64) for cross-compilation
- Linux x86: pass -m32 flag to gcc so the shim is compiled as 32-bit
  to match the i386 libopus.a static archive
Add explicit CRT libraries (ucrt.lib, vcruntime.lib, msvcrt.lib) to
the Windows link step. The x86 SEH handler symbol __except_handler4_common
lives in vcruntime.lib and isn't automatically pulled in when manually
invoking link.exe with a static opus.lib built by CMake with /MD.
fix: correct OpusCompile workflow for shim linking on Windows and Linux x86
@SineVector241 SineVector241 merged commit a67da25 into dev Apr 8, 2026
23 checks passed
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.

2 participants