ocaml / flexdll

a dlopen-like API for Windows
Other
97 stars 30 forks source link

[Question] How does Flexdll handling name mangling #76

Closed ManasJayanth closed 4 years ago

ManasJayanth commented 5 years ago

As a follow up to #75, I'm using MSVC toolchain all through out, to compile Skia bindings.

  1. skia.lib is compiled with MSVC as described in the official docs
  2. Skia APIs are written in C++ and dont have extern C. So the stubs are written in C++ by hand (no ctypes) contain the extern C prefixes.
  3. I'm using fdopen's opam in cygwin with MSVC switch. OCaml 4.07.1

Flexlink complains of unresolved symbols from Skia. Looks like a name mangling issue.

** Cannot resolve symbols for src\libskia_stubs.lib(skia.obj):
 ?setStrokeJoin@SkPaint@@QEAAXW4Join@1@@Z
 ?setStrokeMiter@SkPaint@@QEAAXM@Z
 ?setStrokeWidth@SkPaint@@QEAAXM@Z
 ?setStyle@SkPaint@@QEAAXW4Style@1@@Z
 ?setSubpixel@SkFont@@QEAAX_N@Z
 ?sk_abort_no_print@@YAXXZ
 ?toSkColor@?$SkRGBA4f@$02@@QEBAIXZ
File "caml_startup", line 1:
Error: Error during linking

(truncated for brevity)

stubs.cpp (the bindings) is linked against skia.lib

@lib.exe /out:bindings.lib bindings.obj %esy_skia_install%/out/Release/skia.lib

And this library file is passed to ocamlmklib

ocamlmklib -o skia_stubs bindings.lib

Tiny visual aid

 libskia_stubs <- bindings.lib (contain extern C) <- skia.lib (no extern C)

Can flexlink handling name mangling correctly in this case? Alternatively, how we use flexlink to link to C++ APIs that don't ship with extern "C"

ManasJayanth commented 5 years ago

In case it helps, here is the dumpbin output of the library file created by Flexdll (filtered by one of the missing symbols SkFILEWStream for brevity)

$ dumpbin /symbols _build/default/src/libskia_stubs.lib | grep SkFILEWStream
2A0 00000000 SECT1E notype ()    External     | ??0SkFILEWStream@@QEAA@QEBD@Z (public: __cdecl SkFILEWStream::SkFILEWStream(char const * const))
2A1 00000000 SECT2E notype ()    External     | ??1SkFILEWStream@@UEAA@XZ (public: virtual __cdecl SkFILEWStream::~SkFILEWStream(void))
2A2 00000000 SECTFE notype ()    External     | ?write@SkFILEWStream@@UEAA_NPEBX_K@Z (public: virtual bool __cdecl SkFILEWStream::write(void const *,unsigned __int64))
2A3 00000000 SECT80 notype ()    External     | ?flush@SkFILEWStream@@UEAAXXZ (public: virtual void __cdecl SkFILEWStream::flush(void))
2A4 00000000 SECT84 notype ()    External     | ?fsync@SkFILEWStream@@QEAAXXZ (public: void __cdecl SkFILEWStream::fsync(void))
2A5 00000000 SECT74 notype ()    External     | ?bytesWritten@SkFILEWStream@@UEBA_KXZ (public: virtual unsigned __int64 __cdecl SkFILEWStream::bytesWritten(void)const )
2A6 00000000 SECT44 notype ()    External     | ??_GSkFILEWStream@@UEAAPEAXI@Z (public: virtual void * __cdecl SkFILEWStream::`scalar deleting destructor'(unsigned int))
2A7 00000000 UNDEF  notype ()    WeakExternal | ??_ESkFILEWStream@@UEAAPEAXI@Z (public: virtual void * __cdecl SkFILEWStream::`vector deleting destructor'(unsigned int))
4BB 00000000 SECT18E notype       Static      | $unwind$??0SkFILEWStream@@QEAA@QEBD@Z
4BE 00000000 SECT18F notype       Static      | $pdata$??0SkFILEWStream@@QEAA@QEBD@Z
4C1 00000000 SECT190 notype       Static      | $unwind$??1SkFILEWStream@@UEAA@XZ
4C4 00000000 SECT191 notype       Static      | $pdata$??1SkFILEWStream@@UEAA@XZ
4C7 00000000 SECT192 notype       Static      | $unwind$?write@SkFILEWStream@@UEAA_NPEBX_K@Z
4CA 00000000 SECT193 notype       Static      | $pdata$?write@SkFILEWStream@@UEAA_NPEBX_K@Z
4CD 00000000 SECT194 notype       Static      | $unwind$?fsync@SkFILEWStream@@QEAAXXZ
4D0 00000000 SECT195 notype       Static      | $pdata$?fsync@SkFILEWStream@@QEAAXXZ
4D3 00000000 SECT196 notype       Static      | $unwind$??_GSkFILEWStream@@UEAAPEAXI@Z
4D6 00000000 SECT197 notype       Static      | $pdata$??_GSkFILEWStream@@UEAAPEAXI@Z
6A2 00000000 SECT230 notype       External    | ??_7SkFILEWStream@@6B@ (const SkFILEWStream::`vftable')
2DC 00000000 UNDEF  notype ()    External     | ??0SkFILEWStream@@QEAA@QEBD@Z (public: __cdecl SkFILEWStream::SkFILEWStream(char const * const))
376 00004410 SECT5  notype ()    External     | caml_SkFILEWStream_make
377 00004560 SECT5  notype ()    External     | caml_SkFILEWStream_write
989 0000023C SECTFA notype       Static       | $unwind$caml_SkFILEWStream_make
98A 000002F4 SECTFB notype       Static       | $pdata$caml_SkFILEWStream_make
98B 00000244 SECTFA notype       Static       | $unwind$caml_SkFILEWStream_write
98C 00000300 SECTFB notype       Static       | $pdata$caml_SkFILEWStream_write
ManasJayanth commented 4 years ago

Closing this as it isn't related to name mangling (a similar issue was seen in the C API of the library too). Will re-open with more correct info