Thread overview
thiscall calling convention
Oct 23, 2006
Max Samuha
Oct 24, 2006
Max Samuha
Oct 24, 2006
Don Clugston
Oct 24, 2006
mike
Oct 24, 2006
Max Samuha
October 23, 2006
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?
October 23, 2006
"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..


October 23, 2006
"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();


October 24, 2006
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?
October 24, 2006
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?
>> 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.

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?
October 24, 2006
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

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 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?



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