ldc-developers/ldc

__InterfaceZ is not exported on Windows

rikkimax opened this issue · 4 comments

Filing on behalf of Hipreme, it appears that __InterfaceZ symbols are not exported.

ldc 1.29 works. In newer compilers:

match3.obj : error LNK2019: unresolved external symbol __imp__D3hip3api5audio9audioclip13IHipAudioClip11__InterfaceZ referenced in function _D3hip3api6assets14assets_binding__T3getTCQBoQBn5audio9audioclip13IHipAudioClipZQBsFAyaZQBv
match3.obj : error LNK2019: unresolved external symbol __imp__D3hip3api4data7commons15IHipPreloadable11__InterfaceZ referenced in function ldc.dllimport_relocation
match3.obj : error LNK2019: unresolved external symbol __imp__D3hip3api4view5scene6AScene7__ClassZ referenced in function ldc.dllimport_relocation
match3.obj : error LNK2019: unresolved external symbol __imp__D3hip3api4view5scene6IScene11__InterfaceZ referenced in function ldc.dllimport_relocation

Basically, interface in static lib, is used in a templated function initialized in an executable, both come from the library code that was compiled to create the static lib (minus the template instantiation).

_D3hip3api6assets14assets_binding__T3getTCQBoQBn5audio9audioclip13IHipAudioClipZQBsFAyaZQBv:
T get(T)(string name){return cast(T)getAsset(name); }

interface IHipAudioClip
{
    bool loadFromMemory(in ubyte[] data, HipAudioEncoding encoding, HipAudioType type,
    void delegate(in ubyte[]) onSuccess, void delegate() onFailure);

    uint loadStreamed(in ubyte[] data, HipAudioEncoding encoding);
    uint getSampleRate();
    uint updateStream();
    void onUpdateStream(ubyte[] data, uint decodedSize);

    /** 
     * This function is reserved for HipAudio for being able to take the buffer out of an
     *  audio asset.
     */
    HipAudioBufferAPI* _getBufferAPI(ubyte[] data, uint size); 
    ///Reserved for internal engine methods.
    IHipAudioClip getAudioClipBackend();
    T getAudioClipBackend(T)(){return cast(T)getAudioClipBackend;}
    ubyte[] getClipData();
    size_t getClipSize();
    float getDuration();
    float getDecodedDuration();
    void unload();
    immutable(HipAudioClipHint)* getHint();
}

Public visibility and dllimport=all throughout all packages.

kinke commented

This sounds like it might be the problem of the .obj from the static lib containing the __InterfaceZ definition and export linker directive not being pulled in during linking - the 5th paragraph of #3931. In that case, linking the static lib via /WHOLEARCHIVE might work.

Okay looks like I got it wrong, its static lib going into dll, it does produce one due to build commands how ever.

With /WHOLEARCHIVE it got worse:

oldnames.lib(serrlist.obi) : error LNK2001: unresolved external symbol __imp__sys_errlist

I went ahead and tried the method I have to use with dmd by specifying exports manually:

hipreme_api_exports.def : error LNK2001: unresolved external symbol __imp__D3hip3api4view5scene6AScene7__ClassZ
hipreme_api_exports.def : error LNK2001: unresolved external symbol __imp__D3hip3api4view5scene6IScene11__InterfaceZ
hipreme_api_exports.def : error LNK2001: unresolved external symbol __imp__D3hip3api5audio9audioclip13IHipAudioClip11__InterfaceZ
hipreme_api_exports.def : error LNK2001: unresolved external symbol __imp__D3hip3api7systems5timer13IHipTimerList11__InterfaceZ
hipreme_api_exports.def : error LNK2001: unresolved external symbol __imp__D3hip3api7systems5timer14IHipFiniteTask11__InterfaceZ
hipreme_api_exports.def : error LNK2001: unresolved external symbol __imp__D3hip3api7systems5timer9IHipTimer11__InterfaceZ

I tried the linker script in both the static library and the DLL. From what I'm seeing, they just don't exist when it comes time to make the static library.

I've included a copy of the object files and the static library from the build directory.
script-debug-windows-x86_64-ldc_v1.31.0-46A3EAF8AD5F0FD0B3E71BE6557FE86485C00FA7C0BE05AE0528DD2E77E69FD1.zip

I exported the wrong symbols sigh

LIBRARY

EXPORTS
_D3hip3api5audio9audioclip13IHipAudioClip11__InterfaceZ
_D3hip3api4view5scene6AScene7__ClassZ
_D3hip3api4view5scene6IScene11__InterfaceZ
_D3hip3api7systems5timer9IHipTimer11__InterfaceZ
_D3hip3api7systems5timer14IHipFiniteTask11__InterfaceZ
_D3hip3api7systems5timer13IHipTimerList11__InterfaceZ

yeah that worked.

Cheers, we got a workaround at least.

In the mean time, can we get ldc to generate a linker script with the exports (perhaps by flag)? It'll at least make this automatable in dub.

EDIT: Only one .def file can be specified to LINK. guess the linker script idea won't work

Turns out /WHOLEARCHIVE does work when you pass in the D library module name. /WHOLEARCHIVE:hipengine_api.

We can totally do this in dub and have it "just work". Since dub knows its D code, it can add it automatically.