Thread overview
Any way to access a C++ DLL?
Sep 06, 2006
mike
Sep 06, 2006
xs0
Sep 06, 2006
mike
Sep 06, 2006
Steve Horne
Sep 06, 2006
mike
September 06, 2006
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.

-Mike

-- 
Erstellt mit Operas revolutionärem E-Mail-Modul: http://www.opera.com/mail/
September 06, 2006
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
September 06, 2006
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.
September 06, 2006
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, 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

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ärem E-Mail-Modul: http://www.opera.com/mail/
September 06, 2006
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/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.
>



-- 
Erstellt mit Operas revolutionärem E-Mail-Modul: http://www.opera.com/mail/