Open Frechdachs opened 2 years ago
Afaik that's a known problem. Use msvc or mingw-compiled libavisynth.dll (msvc-built plugins will not work).
Yes, this is a long-standing known issue, and AFAIK an unavoidable one. MSVC's and GCC's C++ ABIs are fundamentally not portable due to name mangling, exception handling, and the like (and the given excuse is that while you can probably get close enough to compatibility to fudge it on some level, AviSynth's C++ API was never written with that in mind, and changing it now would break existing C++ plugins...I don't know how true that is, but that's the claim). Unfortunately, because the C++ API came first (and GCC compatibility didn't exist until it was introduced into Plus in 2016), the vast majority of plugins out there use the C++ API and not the C API.
The C API was itself at least partially intended to overcome this (the other big reason was that it was actually intended to help ease the porting effort to Linux...which didn't actually happen for another like, 17 years after the C interface was created).
AviSynth+ can be built using MinGW-w64, though, and that build can run C++ plugins that were built with MinGW-w64. Additionally, because Windows has to be all kinds of irritating, the difference in calling convention between the Win32 and Win64 APIs means that while a 64-bit build of FFmpeg can use either an MSVC-built or GCC-built AviSynth+, a 32-bit build of FFmpeg can't, and requires a separate build just to support 32-bit GCC builds of AviSynth+ (the times I've put out test builds of FFmpeg or mpv, those builds are the ones with the -avsgcc suffix).
If you do have a build of AviSynth+GCC, it does recognize plugins_gcc
and plugins64_gcc
as the autoload paths for plugins, and ignores the regular plugins/plugins64 directories. MSVC builds are the opposite, and ignore the _gcc directories.
In terms of the theoretically possible, it's been floated before that it might be possible to write a filter that wraps C++ plugins and loads them through the C interface instead, but as of yet no one's tried or if they have, they either haven't succeeded or haven't made it public.
On practically every other operating system, GCC (or Clang using its default GCC compatibility) is so dominant that there's almost no chance of running into this problem. Other C++ compilers do exist, but like Clang either they defer to matching GCC's ABI, or they just don't have anywhere close to a notable install base to make any incompatibility a problem.
That's unfortunate. But thank you for this extensive and informative reply.
Loading plugins that are cross-compiled with mingw for Windows doesn't work. A manual
LoadPlugin
call executes without error, but the filters provided by the plugin won't be availableSteps to reproduce:
Consider the following simple plugin that includes a single filter that only passes through frames:
Compile it with
(I only tested 64-bit.) Then trying to load the plugin with
LoadPlugin("passthrough.dll")
will have no effect. Not even an error message.On the other hand, compiling it for Linux with the following command works just fine. On Linux, the plugin gets loaded and the filter is usable.
Cross-compilation was tested on Arch Linux with their official mingw packages. I have attached the cross-compiled .dll together with their dependencies (it depends on
libgcc_s_seh-1.dll
,libstdc++6.dll
andlibwinpthread-1.dll
). passthrough.zipI hope this helps to figure out what is going on.
BTW, the C API cross-compiles just fine.