evilrat666 / directx-d

[DISCONTINUED] DirectX bindings for D
MIT License
20 stars 16 forks source link

Undefined symbol `_D2D1CreateDevice@12` #7

Closed marler8997 closed 5 years ago

marler8997 commented 5 years ago

I've create a repo to show how to reproduce the bug: https://github.com/marler8997/directx-d-bug

It seems the issue is that when compiling with debug symbols (-g) and when including the directx.d2d1_1 module in your compilation, you'll end up with an undefined symbol error during link:

OPTLINK (R) for Win32  Release 8.00.17
Copyright (C) Digital Mars 1989-2013  All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
main.obj(main)
 Error 42: Symbol Undefined _D2D1CreateDevice@12
main.obj(main)
 Error 42: Symbol Undefined _D2D1CreateDeviceContext@12
Error: linker exited with status 2

I believe it is because of these 2 functions defined in src/directx/d2d1_1.d around line 2233 (https://github.com/evilrat666/directx-d/blob/master/src/directx/d2d1_1.d#L2233)

HRESULT 
D2D1CreateDevice(
    IDXGIDevice dxgiDevice,
    const D2D1_CREATION_PROPERTIES creationProperties,
    out ID2D1Device d2dDevice
    ) 
{

    return
        D2D1CreateDevice(
            dxgiDevice,
            &creationProperties,
            &d2dDevice);
} 

HRESULT 
D2D1CreateDeviceContext(
    IDXGISurface dxgiSurface,
    const D2D1_CREATION_PROPERTIES creationProperties,
    out ID2D1DeviceContext d2dDeviceContext
    ) 
{
    return
        D2D1CreateDeviceContext(
            dxgiSurface,
            &creationProperties,
            &d2dDeviceContext);
}

I'm not super familair with where these functions are supposed to be defined, but they're not defined in the d2d1 library I have. Are they supposed to be in that library?

evilrat666 commented 5 years ago

Works fine with COFF, even with some code using that functions. Looks like OMF conversion issue, or maybe converted lib file is from old SDK. Anyway why not just use -m32mscoff or -m64 for DMD?

marler8997 commented 5 years ago

Thanks for the reply. It looks like the bug also occurs with COFF. I updated my bug repo (https://github.com/marler8997/directx-d-bug) to reproduce the bug with COFF or OMF. Use buildomf.bat to reproduce with OMF and buildcoff.bat to reproduce with coff.

Do you know if this D2D1CreateDeviceContext function is supposed to be exported in the d2d1.lib file? If not then the 2 functions I listed above need to be removed or templatized or something so they don't try to link to those symbols at compile time.

evilrat666 commented 5 years ago

Yes it is supposed to be exported from d2d1.lib from DX/Windows SDK libs.

Again, when I do this

dmd -g -i -I=directx-d\src main.d -m32mscoff d2d1.lib

instead this from example

dmd -g -i -I=directx-d\src main.d -m32mscoff d2d1.coff.lib

it successfully links...

dumpbin shows this d2d1.coff.lib has less exports than that from SDK (below)

C:\...\directx-d-bug>dumpbin /EXPORTS d2d1.coff.lib
Microsoft (R) COFF/PE Dumper Version 14.16.27027.1
Copyright (C) Microsoft Corporation.  All rights reserved.

Dump of file d2d1.coff.lib

File Type: LIBRARY

     Exports

       ordinal    name

                  _D2D1CreateFactory@16
                  _D2D1InvertMatrix@4
                  _D2D1IsMatrixInvertible@4
                  _D2D1MakeRotateMatrix@16
                  _D2D1MakeSkewMatrix@20
...
C:\...>dumpbin /EXPORTS d2d1.lib
Microsoft (R) COFF/PE Dumper Version 14.16.27027.1
Copyright (C) Microsoft Corporation.  All rights reserved.

Dump of file C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\um\x64\d2d1.lib

File Type: LIBRARY

     Exports

       ordinal    name

            12    D2D1ComputeMaximumScaleFactor
             6    D2D1ConvertColorSpace
             7    D2D1CreateDevice
             8    D2D1CreateDeviceContext
             1    D2D1CreateFactory
            13    D2D1GetGradientMeshInteriorPointsFromCoonsPatch
             5    D2D1InvertMatrix
             4    D2D1IsMatrixInvertible
             2    D2D1MakeRotateMatrix
             3    D2D1MakeSkewMatrix
             9    D2D1SinCos
            10    D2D1Tan
            11    D2D1Vec3Length
...
evilrat666 commented 5 years ago

Looked again and here what I see: This happens because you added -i flag to include it all in compilation, these bindings is just "headers" and there is no code so that shouldn't be a problem... except these very few helper functions* like that at the end of d2d1_1.d

So the real solution will be to add ability to choose whether users need such helpers or not using either mixin/version mechanisms. This will help in such situations where compiler includes the code and that forces you to link unresolved symbols from relevant libs even if YOU don't really uses them in your code.

*(These helpers probably comes from the new style helpers that comes with Windows 10)

marler8997 commented 5 years ago

Yeah that's what I understood as well. That's why I said you could templatize them so they wouldn't need to link against those symbols unless they were used. I just didn't know whether or not those functions were suppose to be defined in d2d1.lib.

I still have yet to find a new d2d1.lib file though. Will update when I do.

evilrat666 commented 5 years ago

Another issue showed up, these functions and helpers are indistinguishable to the compiler, that's defeats their purpose. I was unable to make it work. Now that looks like they are totally useless, and harmful.

I will try to hack up a solution, or if all fails I will consider to remove them.

evilrat666 commented 5 years ago

Now it should work, try it out and re-open the issue if it still broken. I also made a new release for dub users convenience (I hope that doesn't bite me later)

marler8997 commented 5 years ago

Lol...the fix seems hacky but if it works it works :) Did you try just having an empty template parameter list?

Instead of

//...
HRESULT 
D2D1CreateDeviceContext(T=void)(
    IDXGISurface dxgiSurface,
    const D2D1_CREATION_PROPERTIES creationProperties,
//...

Did you try this?

//...
HRESULT 
D2D1CreateDeviceContext()(
    IDXGISurface dxgiSurface,
    const D2D1_CREATION_PROPERTIES creationProperties,
//...
marler8997 commented 5 years ago

Here's a PR for my suggestion if you agree with it: https://github.com/evilrat666/directx-d/pull/9