www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Request assistance binding to Windows dsound.{lib, dll}

reply Andrew Edwards <edwards.ac gmail.com> writes:
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
next sibling parent reply Guillaume Piolat <first.last gmail.com> writes:
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 1
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)
May 27 2016
parent reply Andrew Edwards <edwards.ac gmail.com> writes:
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:
     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
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. 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-L248
May 27 2016
parent reply Kagamin <spam here.lot> writes:
On Friday, 27 May 2016 at 15:28:42 UTC, Andrew Edwards wrote:
 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.
If you declare extern function with wrong calling convention, calling it can result in stack corruption.
 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
parent reply Andrew Edwards <edwards.ac gmail.com> writes:
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:
 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.
If you declare extern function with wrong calling convention, calling it can result in stack corruption.
Okay, that makes sense. Will remain mindful of that.
 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
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 32
May 27 2016
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Friday, 27 May 2016 at 17:37:38 UTC, Andrew Edwards wrote:
     extern (C) class IDirectSound : IUnknown
That should just be `interface IDirectSound : IUnknown`
May 27 2016
parent reply Andrew Edwards <edwards.ac gmail.com> writes:
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:
     extern (C) class IDirectSound : IUnknown
That should just be `interface IDirectSound : IUnknown`
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 RtlSetCurrentTransaction
May 27 2016
parent reply John <johnch_atms hotmail.com> writes:
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
parent Andrew Edwards <edwards.ac gmail.com> writes:
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
prev sibling next sibling parent Kagamin <spam here.lot> writes:
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
prev sibling next sibling parent Kagamin <spam here.lot> writes:
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
prev sibling parent notna <notna.remove.this ist-einmalig.de> writes:
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