www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - thiscall calling convention

reply Max Samuha <maxter i.com.ua> writes:
I have a COM object which uses __thiscall linkage for its methods
(guys who created the object have perfect sense of humor). Would you
advice me of a good way to call those methods from D?
Oct 23 2006
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Max Samuha" <maxter i.com.ua> wrote in message 
news:o14pj2teu31k82a6rnqfc7jbk422lrm05l 4ax.com...
I have a COM object which uses __thiscall linkage for its methods
 (guys who created the object have perfect sense of humor). Would you
 advice me of a good way to call those methods from D?

To use any COM interface from D, you can just create an interface which derives from IUnknown. D will make the interface COM-compatible. import std.c.windows.com; interface SomeInterface : IUnknown { HRESULT method1(); } extern(Windows) export CreateSomeInterface(); ... SomeInterface i = CreateSomeInterface(); i.method1(); Of course, if the library you're using (what are you using anyway?) doesn't have a function which creates an instance of the COM object for you, you'll have to use QueryInterface from a base COM object, but..
Oct 23 2006
next sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message 
news:ehihsl$1p7p$1 digitaldaemon.com...

 extern(Windows) export CreateSomeInterface();

Oops, that'd be something like extern(Windows) export SomeInterface CreateSomeInterface();
Oct 23 2006
prev sibling parent reply Max Samuha <maxter i.com.ua> writes:
On Mon, 23 Oct 2006 09:59:56 -0400, "Jarrett Billingsley"
<kb3ctd2 yahoo.com> wrote:

"Max Samuha" <maxter i.com.ua> wrote in message 
news:o14pj2teu31k82a6rnqfc7jbk422lrm05l 4ax.com...
I have a COM object which uses __thiscall linkage for its methods
 (guys who created the object have perfect sense of humor). Would you
 advice me of a good way to call those methods from D?

To use any COM interface from D, you can just create an interface which derives from IUnknown. D will make the interface COM-compatible. import std.c.windows.com; interface SomeInterface : IUnknown { HRESULT method1(); } extern(Windows) export CreateSomeInterface(); ... SomeInterface i = CreateSomeInterface(); i.method1(); Of course, if the library you're using (what are you using anyway?) doesn't have a function which creates an instance of the COM object for you, you'll have to use QueryInterface from a base COM object, but..

Thank you for the reply. It's not that i can't obtain the COM interface. I just can't call methods on that interface because the COM object implementation uses thiscall (not stdcall or cdecl) calling convention. This is an ASIO driver. The interface declaration does not specify the calling convention explicitly in their SDK (in C++): interface IASIO : public IUnknown { virtual ASIOBool init(void *sysHandle) = 0; virtual void getDriverName(char *name) = 0; virtual long getDriverVersion() = 0; ... } So MSVC++ which is used de facto to compile ASIO drivers for windows defaults to thiscall, effectively making the drivers crash when they are called by clients compiled in languages that don't support thiscall. I think, Walter has intended to add extern(C++): "C++ is reserved for future use". Will it be added? A wrapper could be used to fix that (http://www.martinfay.com/openasio.htm) but someone may have a better idea?
Oct 24 2006
next sibling parent Don Clugston <dac nospam.com.au> writes:
Max Samuha wrote:
 On Mon, 23 Oct 2006 09:59:56 -0400, "Jarrett Billingsley"
 <kb3ctd2 yahoo.com> wrote:
 
 "Max Samuha" <maxter i.com.ua> wrote in message 
 news:o14pj2teu31k82a6rnqfc7jbk422lrm05l 4ax.com...
 I have a COM object which uses __thiscall linkage for its methods
 (guys who created the object have perfect sense of humor). Would you
 advice me of a good way to call those methods from D?

derives from IUnknown. D will make the interface COM-compatible. import std.c.windows.com; interface SomeInterface : IUnknown { HRESULT method1(); } extern(Windows) export CreateSomeInterface(); ... SomeInterface i = CreateSomeInterface(); i.method1(); Of course, if the library you're using (what are you using anyway?) doesn't have a function which creates an instance of the COM object for you, you'll have to use QueryInterface from a base COM object, but..

Thank you for the reply. It's not that i can't obtain the COM interface. I just can't call methods on that interface because the COM object implementation uses thiscall (not stdcall or cdecl) calling convention. This is an ASIO driver. The interface declaration does not specify the calling convention explicitly in their SDK (in C++): interface IASIO : public IUnknown { virtual ASIOBool init(void *sysHandle) = 0; virtual void getDriverName(char *name) = 0; virtual long getDriverVersion() = 0; ... } So MSVC++ which is used de facto to compile ASIO drivers for windows defaults to thiscall, effectively making the drivers crash when they are called by clients compiled in languages that don't support thiscall.

thiscall isn't standard in C++. It's an MSVC-only thing (but see below).
 I think, Walter has intended to add extern(C++): "C++ is reserved for
 future use". Will it be added?

If it is, it still won't solve the problem. There's no standard for extern(C++). Borland, MSVC, GCC, Watcom, DMC, all use different calling conventions. Failing to standardise the ABI was one of the appallingly bad C++ mistakes. HOWEVER... *** IUnknown is treated specially by DMD *** It is magical, and it makes all of the member functions use the MSVC 'thiscall' calling convention. (There's no other way to specify 'thiscall'). It should just work. Have you actually tried it?
 A wrapper could be used to fix that
 (http://www.martinfay.com/openasio.htm) but someone may have a better
 idea?

Oct 24 2006
prev sibling parent reply mike <vertex gmx.at> writes:
Hi!

Maybe you could try to google for "iasiothiscallresolver.h".

I used this in a C++ project (before I converted to D and trashed the  =

code) to do all the ASIO stuff. I had used MinGW and couldn't link to th=
e  =

ASIO interface either (does only work from Visual C++), using this heade=
r  =

file it worked. Maybe you can rewrite it and use it, don't know if it  =

works in D, though.

-Mike

Am 24.10.2006, 11:32 Uhr, schrieb Max Samuha <maxter i.com.ua>:

 On Mon, 23 Oct 2006 09:59:56 -0400, "Jarrett Billingsley"
 <kb3ctd2 yahoo.com> wrote:

 "Max Samuha" <maxter i.com.ua> wrote in message
 news:o14pj2teu31k82a6rnqfc7jbk422lrm05l 4ax.com..
 I have a COM object which uses __thiscall linkage for its methods
 (guys who created the object have perfect sense of humor). Would you=



 advice me of a good way to call those methods from D?

To use any COM interface from D, you can just create an interface whi=


 derives from IUnknown.  D will make the interface COM-compatible.


 import std.c.windows.com;

 interface SomeInterface : IUnknown
 {
    HRESULT method1();
 }

 extern(Windows) export CreateSomeInterface();

 ...

 SomeInterface i =3D CreateSomeInterface();
 i.method1();


 Of course, if the library you're using (what are you using anyway?)  =


 doesn't
 have a function which creates an instance of the COM object for you, =


 you'll
 have to use QueryInterface from a base COM object, but..

Thank you for the reply. It's not that i can't obtain the COM interface. I just can't call methods on that interface because the COM=

 object implementation uses thiscall (not stdcall or cdecl) calling
 convention. This is an ASIO driver. The interface declaration does not=

 specify the calling convention explicitly in their SDK (in C++):

 interface IASIO : public IUnknown
 {
 	virtual ASIOBool init(void *sysHandle) =3D 0;
 	virtual void getDriverName(char *name) =3D 0;	=

 	virtual long getDriverVersion() =3D 0;
 	...
 }

 So MSVC++ which is used de facto to compile ASIO drivers for windows
 defaults to thiscall, effectively making the drivers crash when they
 are called by clients compiled in languages that don't support
 thiscall.

 I think, Walter has intended to add extern(C++): "C++ is reserved for
 future use". Will it be added?

 A wrapper could be used to fix that
 (http://www.martinfay.com/openasio.htm) but someone may have a better
 idea?

-- = Erstellt mit Operas revolution=E4rem E-Mail-Modul: http://www.opera.com/= mail/
Oct 24 2006
parent Max Samuha <maxter i.com.ua> writes:
Thank you

HOWEVER... *** IUnknown is treated specially by DMD ***
It is magical, and it makes all of the member functions use the MSVC 
'thiscall' calling convention. (There's no other way to specify 'thiscall').

It should just work. Have you actually tried it?

Yes, I tried it. Doesn't work. I'm not sure, but apparently the COM interface member functions in D use stdcall by default, not thiscall. At least, IUnknown members are correctly declared in com.d as using stdcall. IMO, the docs should be clearer on that issue. btw, MSVC++ 2005 allows to set __thiscall explicitly.
Hi!

Maybe you could try to google for "iasiothiscallresolver.h".

I used this in a C++ project (before I converted to D and trashed the  
code) to do all the ASIO stuff. I had used MinGW and couldn't link to the  
ASIO interface either (does only work from Visual C++), using this header  
file it worked. Maybe you can rewrite it and use it, don't know if it  
works in D, though.

-Mike

Yes, i saw this header. Thanks.
Oct 24 2006