digitalmars.D.learn - Request assistance binding to Windows dsound.{lib, dll}
- Andrew Edwards (34/34) May 27 2016 http://ftp.dlang.org/ctg/implib.html
- Guillaume Piolat (5/11) May 27 2016 Have you tried with extern(C) yet?
- Andrew Edwards (28/41) May 27 2016 The thought never crossed my mind. Tried it and it works like a
- Kagamin (5/14) May 27 2016 If you declare extern function with wrong calling convention,
- Andrew Edwards (145/160) May 27 2016 So if I'm understanding correctly, I should be able to take this:
- Adam D. Ruppe (2/3) May 27 2016 That should just be `interface IDirectSound : IUnknown`
- Andrew Edwards (28/31) May 27 2016 Thanks for the clarification. That actually compiles but results
- John (9/9) May 27 2016 Additionally, remove QueryInterface, AddRef and Release from the
- Andrew Edwards (9/18) May 27 2016 Awesome... that's the missing link. Thank you very. I really
- Kagamin (3/3) May 27 2016 https://forum.dlang.org/post/kcr2vn$21i6$1@digitalmars.com
- Kagamin (3/3) May 27 2016 Another possibility is to use -m32mscoff switch
- notna (5/9) May 27 2016 If you haven't done so, you need to copy your resulting LIB file
http://ftp.dlang.org/ctg/implib.html The above URL suggests that, on Windoze, I can create a D compatible lib from a dll file by issuing the command: implib /s dsound.lib dsound.dll The following file: sound.d ======= pragma(lib, "dsound") struct IDirectSound{}; alias LPDIRECTSOUND = IDirectSound*; extern(Windows) HRESULT DirectSoundCreate(LPGUID, LPDIRECTSOUND*, LPUNKNOWN); void main() { LPDIRECTSOUND directSound; DirectSoundCreate(null, &directSound, null); } compiled as such: dmd sound dsound.lib produces the output: OPTLINK (R) for Win32 Release 8.00.17 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html sound.obj(sound) Error 42: Symbol Undefined _DirectSoundCreate 12 --- errorlevel 1 Obviously I'm doing something incorrectly but I'm unable to see it. Please shed some light. The only thing I can see is that IDirectSound8 is improperly declared. It is struct generated form an interface which I have now idea of how to bind to from D: https://gist.github.com/AndrewEdwards/560601a62ea890842ecac90bb41896a8#file-dsound-h-L214 Thanks, Andrew
May 27 2016
On Friday, 27 May 2016 at 12:26:19 UTC, Andrew Edwards wrote:OPTLINK (R) for Win32 Release 8.00.17 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html sound.obj(sound) Error 42: Symbol Undefined _DirectSoundCreate 12 --- errorlevel 1Have you tried with extern(C) yet? extern(C) is for undecorated symbold extern(Windows) adds the _ and 12 decorations (would be __stdcall on C/C++ side)
May 27 2016
On Friday, 27 May 2016 at 12:30:50 UTC, Guillaume Piolat wrote:On Friday, 27 May 2016 at 12:26:19 UTC, Andrew Edwards wrote:The thought never crossed my mind. Tried it and it works like a charm. Thanks to everyone who responded. notna: It is not really necessary to put the lib in the libs folder since it's being passed on the command line and available in the build directory. I will place it there eventually though. On other issue remains that I could not sort out: Once DirectSoundCreate() returns successfully, I need to call one of the function pointers in the struct but am at a loss of how to define it based on the interface presented. According the code, SetCooperativeLevel() can be called one of two ways, either via a template[1] or directly through the second parameter provided to and modified by SetCooperativeLevel(). I tried the two approaches below both inside and outside the struct but neither worked. // first approach struct IDirectSound { extern(C) HRESULT SetCooperativeLevel(HWND, DWORD); } // second approach alias setCooperativeLevel = HRESULT function(HWND, DWORD); setCooperativeLevel SetCooperativeLevel; It seemed pointless trying to recreate the template since above attempts did not expose the function signature which is necessary to get the template working. Any ideas? [1] https://gist.github.com/AndrewEdwards/560601a62ea890842ecac90bb41896a8#file-dsound-h-L248OPTLINK (R) for Win32 Release 8.00.17 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html sound.obj(sound) Error 42: Symbol Undefined _DirectSoundCreate 12 --- errorlevel 1Have you tried with extern(C) yet? extern(C) is for undecorated symbold extern(Windows) adds the _ and 12 decorations (would be __stdcall on C/C++ side)
May 27 2016
On Friday, 27 May 2016 at 15:28:42 UTC, Andrew Edwards wrote:If you declare extern function with wrong calling convention, calling it can result in stack corruption.Have you tried with extern(C) yet? extern(C) is for undecorated symbold extern(Windows) adds the _ and 12 decorations (would be __stdcall on C/C++ side)The thought never crossed my mind. Tried it and it works like a charm. Thanks to everyone who responded.Once DirectSoundCreate() returns successfully, I need to call one of the function pointers in the struct but am at a loss of how to define it based on the interface presented.This struct is called COM interface, D has built-in support for them: https://dlang.org/spec/interface.html#com-interfaces
May 27 2016
On Friday, 27 May 2016 at 16:08:27 UTC, Kagamin wrote:On Friday, 27 May 2016 at 15:28:42 UTC, Andrew Edwards wrote:Okay, that makes sense. Will remain mindful of that.If you declare extern function with wrong calling convention, calling it can result in stack corruption.Have you tried with extern(C) yet? extern(C) is for undecorated symbold extern(Windows) adds the _ and 12 decorations (would be __stdcall on C/C++ side)The thought never crossed my mind. Tried it and it works like a charm. Thanks to everyone who responded.So if I'm understanding correctly, I should be able to take this: DECLARE_INTERFACE_(IDirectSound, IUnknown) { // IUnknown methods STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID FAR *) PURE; STDMETHOD_(ULONG,AddRef) (THIS) PURE; STDMETHOD_(ULONG,Release) (THIS) PURE; // IDirectSound methods STDMETHOD(CreateSoundBuffer) (THIS_ LPCDSBUFFERDESC, LPDIRECTSOUNDBUFFER *, LPUNKNOWN) PURE; STDMETHOD(GetCaps) (THIS_ LPDSCAPS) PURE; STDMETHOD(DuplicateSoundBuffer) (THIS_ LPDIRECTSOUNDBUFFER, LPDIRECTSOUNDBUFFER *) PURE; STDMETHOD(SetCooperativeLevel) (THIS_ HWND, DWORD) PURE; STDMETHOD(Compact) (THIS) PURE; STDMETHOD(GetSpeakerConfig) (THIS_ LPDWORD) PURE; STDMETHOD(SetSpeakerConfig) (THIS_ DWORD) PURE; STDMETHOD(Initialize) (THIS_ LPGUID) PURE; }; Convert it into this: extern (C) class IDirectSound : IUnknown { // IUnknown methods HRESULT QueryInterface(const(IID)*, void**); uint AddRef(); uint Release(); // IDirectSound methods HRESULT CreateSoundBuffer(LPCDSBUFFERDESC, LPDIRECTSOUNDBUFFER*, LPUNKNOWN); HRESULT GetCaps(LPDSCAPS); HRESULT DuplicateSoundBuffer(LPDIRECTSOUNDBUFFER, LPDIRECTSOUNDBUFFER*); HRESULT SetCooperativeLevel(HWND, DWORD); HRESULT Compact(); HRESULT GetSpeakerConfig(LPDWORD); HRESULT SetSpeakerConfig(DWORD); HRESULT Initialize(LPGUID); } Import the correct libraries: import core.sys.windows.windows; import core.sys.windows.com; And finally link to the lib file and I should be golden!!! Except I'm not :( C:\Users\edwarac\work\sound\code>build A subdirectory or file ..\..\build already exists. OPTLINK (R) for Win32 Release 8.00.17 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound17CreateÇàìBufferMWxPSÇï»DSBUFFERDESCPPCÇèÜ8Çî╔Çå╝C4core3sys7windows6unknwn8IU·ownZi 12 sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound16SetSpeakerConfigMWkZi 4 sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound16GetSpeakerConfigMWPkZi 4 sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound7CompactMWZi 0 sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound20DuplicateSoundBufferMWPC8sound18IDirectSoundBufferPPC8sound18IDirectSoundBufferZi 8 sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound19SetCooperativeLevelMWPvkZi 8 sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound10InitializeMWPS4core3sys7windows8basetyps4GUIDZi 4 sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound7GetCapsMWPS8sound6DSCAPSZi 4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer12GetFrequencyMWPkZi 4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer6SetPanMWiZi 4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer9GetFormatMWPS4core3sys7windows8mmsystem12WAVEFORMATEXkPkZi 12 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer7RestoreMWZi 0 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer6GetPanMWPiZi 4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer4StopMWZi 0 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer9GetStatusMWPkZi 4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer4LockMWkkPPvPkPPvPkkZi 28 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer7GetCapsMWPS8sound7DSBCAPSZi 4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer12SetFrequencyMWkZi 4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer9SetFormatMWPxS4core3sys7windows8mmsystem12WAVEFORMATEXZi 4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer9SetVolumeMWiZi 4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer18SetCurrentPositionMWkZi 4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer9GetVolumeMWPiZi 4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer18GetCurrentPositionMWPkPkZi 8 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer6UnlockMWPvkPvkZi 16 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer4PlayMWkkkZi 12 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer10InitializeMWPC8sound12IDirectSoundxPS8sound12DSBUFFERDESCZi 8 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer7ReleaseMWZk 0 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer6AddRefMWZk 0 sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound14QueryInterfaceMWPxS4core3sys7windows8basetyps4GUIDPPvZi 8 sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound7ReleaseMWZk 0 sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound6AddRefMWZk 0 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer14QueryInterfaceMWPxS4core3sys7windows8basetyps4GUIDPPvZi 8 --- errorlevel 32Once DirectSoundCreate() returns successfully, I need to call one of the function pointers in the struct but am at a loss of how to define it based on the interface presented.This struct is called COM interface, D has built-in support for them: https://dlang.org/spec/interface.html#com-interfaces
May 27 2016
On Friday, 27 May 2016 at 17:37:38 UTC, Andrew Edwards wrote:extern (C) class IDirectSound : IUnknownThat should just be `interface IDirectSound : IUnknown`
May 27 2016
On Friday, 27 May 2016 at 17:49:56 UTC, Adam D. Ruppe wrote:On Friday, 27 May 2016 at 17:37:38 UTC, Andrew Edwards wrote:Thanks for the clarification. That actually compiles but results in access violation at the call site which takes place after verifying that the call to DirectSoundCreate() succeeded: if (SUCCEEDED(sound.SetCooperativeLevel(window, DSSCL_PRIORITY))) { MessageBoxA(null, "Hott Damn!!", null, MB_ICONINFORMATION); } else { MessageBoxA(null, "Naaah Man! Dat cyaan wuk!", null, MB_ICONINFORMATION); } Output: object.Error (0): Access Violation -------------- 0x00402700 in void sound.initSound(void*) at C:\Users\edwarac\work\sound\code\sound.d(555) 0x004021A2 in int sound.myWinMain(void*, void*, char*, int) at C:\Users\edwasac\work\sound\code\sound.d(210) 0x00402050 in WinMain at C:\Users\edwasac\work\sound\code\sound.d(154) 0x00422B4A in WinMainCRTStartup 0x76DF3744 in BaseThreadInitTrunk 0x7721A064 in RtlSetCurrentTransaction 0x7721A02F in RtlSetCurrentTransactionextern (C) class IDirectSound : IUnknownThat should just be `interface IDirectSound : IUnknown`
May 27 2016
Additionally, remove QueryInterface, AddRef and Release from the definition of IDirectSound. Also, interfaces are already references, so the definition of LPDIRECTSOUND should be: alias LPDIRECTSOUND = IDirectSound; Note there should be no *. Regarding any linking errors, it's easier to either grab the .lib files from the Windows SDK and convert them with coffimplib, or use the m32mscoff switch so you can link with the SDK .lib files directly.
May 27 2016
On Friday, 27 May 2016 at 20:59:56 UTC, John wrote:Additionally, remove QueryInterface, AddRef and Release from the definition of IDirectSound. Also, interfaces are already references, so the definition of LPDIRECTSOUND should be: alias LPDIRECTSOUND = IDirectSound; Note there should be no *.Awesome... that's the missing link. Thank you very. I really appreciate the assistance of everyone who helped to clarify this matter.Regarding any linking errors, it's easier to either grab the .lib files from the Windows SDK and convert them with coffimplib, or use the m32mscoff switch so you can link with the SDK .lib files directly.Was already doing that (both approaches). As Adam pointed out, last bit of errors were occurring because it was a class vice an interface. Again, thank you all. Andrew
May 27 2016
https://forum.dlang.org/post/kcr2vn$21i6$1 digitalmars.com implib can work for extern(C), but is likely to fail even for them.
May 27 2016
Another possibility is to use -m32mscoff switch https://dlang.org/dmd-windows.html#switch-m32mscoff and use ms toolchain for linking with PSDK import libraries.
May 27 2016
On Friday, 27 May 2016 at 12:26:19 UTC, Andrew Edwards wrote:http://ftp.dlang.org/ctg/implib.html The above URL suggests that, on Windoze, I can create a D compatible lib from a dll file by issuing the command: [...]If you haven't done so, you need to copy your resulting LIB file to your standard LIBs folder, which under Windows_X86 should be: - C:\D\dmd2\windows\lib regards
May 27 2016