www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Any way to access a C++ DLL?

reply mike <vertex gmx.at> writes:
Hi!

Lot's of questions coming up ... but that's really important for me, if =
I  =

can't solve that I have to throw away over half a year of invested spare=
  =

time, so:

Is there any way to access a C++ DLL (precisely: a VST plugin - for thos=
e  =

who don't know: VST is a plugin API for virtual synthesizers, audio/midi=
  =

effects, etc.) from D?

I'm working on a VST host in D. I knew that VST plugins are written in  =

C++ but I somehow had in mind that the VST SDK just maps the C++ objects=
  =

to C functions ... now I found out that I was terribly wrong - a VST  =

plugin host obtains a pointer to a C++ object from the DLL's main and  =

calls that for processing. So ... is there a way to wrap that with a D  =

class?

Since I'm not really experienced with plugins and calling conventions an=
d  =

that ... my guess is that there's the vtbl somewhere stored in the DLL, =
 =

one can calculate entry points for every member of the class from that a=
nd  =

needs to possibly push a this ptr on the stack before calling the functi=
on  =

pointer. Is that correct and doable? With a little research I'm sure I c=
an  =

make it work, but I would like to ask the experts here if it's at all  =

possible or if I should rather think of something else.

-Mike

-- =

Erstellt mit Operas revolution=E4rem E-Mail-Modul: http://www.opera.com/=
mail/
Sep 06 2006
next sibling parent reply xs0 <xs0 xs0.com> writes:
mike wrote:
 Hi!
 
 Lot's of questions coming up ... but that's really important for me, if 
 I can't solve that I have to throw away over half a year of invested 
 spare time, so:
 
 Is there any way to access a C++ DLL (precisely: a VST plugin - for 
 those who don't know: VST is a plugin API for virtual synthesizers, 
 audio/midi effects, etc.) from D?
 
 I'm working on a VST host in D. I knew that VST plugins are written in 
 C++ but I somehow had in mind that the VST SDK just maps the C++ objects 
 to C functions ... now I found out that I was terribly wrong - a VST 
 plugin host obtains a pointer to a C++ object from the DLL's main and 
 calls that for processing. So ... is there a way to wrap that with a D 
 class?
 
 Since I'm not really experienced with plugins and calling conventions 
 and that ... my guess is that there's the vtbl somewhere stored in the 
 DLL, one can calculate entry points for every member of the class from 
 that and needs to possibly push a this ptr on the stack before calling 
 the function pointer. Is that correct and doable? With a little research 
 I'm sure I can make it work, but I would like to ask the experts here if 
 it's at all possible or if I should rather think of something else.
You can't call C++ code directly from D. However, you can call C code, meaning you can write a bunch of C functions that call C++ methods, and use that from D. something like C++: struct FooBoo { FooBoo() { ... } void boo(int a); } extern "C" { void* FooBoo_create() { return (void*) new FooBoo(); } void FooBoo_boo(void* obj, int a) { ((FooBoo*)obj)->boo(a); } void FooBoo_delete(void *obj) { delete ((FooBoo*)obj); } } D: extern(C) FooBoo_create(); extern(C) FooBoo_boo(void* obj, int a); extern(C) FooBoo_delete(void *obj); class FooBoo { void* obj; public this() { obj = FooBoo_create(); } public boo(int a) { FooBoo_boo(obj, a); } ~this() { FooBoo_delete(obj); obj = null; } } xs0
Sep 06 2006
parent mike <vertex gmx.at> writes:
Am 06.09.2006, 13:12 Uhr, schrieb xs0 <xs0 xs0.com>:

 You can't call C++ code directly from D. However, you can call C code,=
=
 meaning you can write a bunch of C functions that call C++ methods, an=
d =
 use that from D.

 something like

 C++:

 struct FooBoo
 {
      FooBoo() { ... }
      void boo(int a);
 }

 extern "C" {
 void* FooBoo_create()
 {
      return (void*) new FooBoo();
 }

 void FooBoo_boo(void* obj, int a)
 {
      ((FooBoo*)obj)->boo(a);
 }

 void FooBoo_delete(void *obj)
 {
      delete ((FooBoo*)obj);
 }
 }


 D:

 extern(C) FooBoo_create();
 extern(C) FooBoo_boo(void* obj, int a);
 extern(C) FooBoo_delete(void *obj);

 class FooBoo
 {
      void* obj;
      public this() {
          obj =3D FooBoo_create();
      }

      public boo(int a) {
          FooBoo_boo(obj, a);
      }

      ~this() {
          FooBoo_delete(obj); obj =3D null;
      }
 }


 xs0
Stupid me! Never thought about that (why do it the easy way when you can= = do it the hard way ... hehe). Thanks a lot! -Mike -- = Erstellt mit Operas revolution=E4rem E-Mail-Modul: http://www.opera.com/= mail/
Sep 06 2006
prev sibling parent reply Steve Horne <stephenwantshornenospam100 aol.com> writes:
On Wed, 06 Sep 2006 13:03:40 +0200, mike <vertex gmx.at> wrote:

Is there any way to access a C++ DLL (precisely: a VST plugin - for those  
who don't know: VST is a plugin API for virtual synthesizers, audio/midi  
effects, etc.) from D?
I'm a newb, but I can still say yes - in principle. Worst case, you write an adaptor lib in C++ which provides a C level API. D can easily call that. On the C level, you see functions that take 'handles' as parameters. It's a lot like the Windows APIs - those window and device context handles are actually object pointers and, very likely, those C-like function calls use an underlying C++-style virtual function call in order to resolve what kind of window/device context/whatever they are dealing with. I haven't dealt with VST plugins, but for the main plugin mechanism I have used, there is a single exported function in the DLL. This is normally accessed through GetProcAddress, and when called it provides an object which is used as a kind of 'factory' for API objects. Mapping all of that to a C-compatible adaptor lib would be a pain, but not difficult as such. Just hassle. You could, of course, use SWIG. AFAIK it can't generate D wrappers yet, but it can generate an XML description of a C++ API which you could then translate to a D wrapper using XSLT. Of course this might take some time and fiddling around. Far better case - perhaps VST uses COM? After all, there aren't any big overheads to using COM, providing the interfaces are provided by a local DLL. All basic COM does is allow an executable or DLL to call create objects and call interfaces defined in another DLL. The calls are just C++-style virtual function calls through an interface object pointer. I believe D has built-in support for COM, making it easier to program COM in D than in C++, though I haven't used it. -- Remove 'wants' and 'nospam' from e-mail.
Sep 06 2006
parent mike <vertex gmx.at> writes:
Thanks!

I'll go the wrapper route (no COM for VST). I need to translate a lot of=
  =

enums by hand, should mostly be copy/paste anyway.

-Mike

Am 06.09.2006, 13:28 Uhr, schrieb Steve Horne  =

<stephenwantshornenospam100 aol.com>:

 On Wed, 06 Sep 2006 13:03:40 +0200, mike <vertex gmx.at> wrote:

 Is there any way to access a C++ DLL (precisely: a VST plugin - for  =
 those
 who don't know: VST is a plugin API for virtual synthesizers, audio/m=
idi
 effects, etc.) from D?
I'm a newb, but I can still say yes - in principle. Worst case, you write an adaptor lib in C++ which provides a C level API. D can easily call that. On the C level, you see functions that take 'handles' as parameters. It's a lot like the Windows APIs - those window and device context handles are actually object pointers and, very likely, those C-like function calls use an underlying C++-style virtual function call in order to resolve what kind of window/device context/whatever they are dealing with. I haven't dealt with VST plugins, but for the main plugin mechanism I have used, there is a single exported function in the DLL. This is normally accessed through GetProcAddress, and when called it provides an object which is used as a kind of 'factory' for API objects. Mapping all of that to a C-compatible adaptor lib would be a pain, but=
 not difficult as such. Just hassle.

 You could, of course, use SWIG. AFAIK it can't generate D wrappers
 yet, but it can generate an XML description of a C++ API which you
 could then translate to a D wrapper using XSLT. Of course this might
 take some time and fiddling around.


 Far better case - perhaps VST uses COM? After all, there aren't any
 big overheads to using COM, providing the interfaces are provided by a=
 local DLL. All basic COM does is allow an executable or DLL to call
 create objects and call interfaces defined in another DLL. The calls
 are just C++-style virtual function calls through an interface object
 pointer.

 I believe D has built-in support for COM, making it easier to program
 COM in D than in C++, though I haven't used it.
-- = Erstellt mit Operas revolution=E4rem E-Mail-Modul: http://www.opera.com/= mail/
Sep 06 2006