www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Some asm help for the 'thiscall' calling convention?

reply Andrej Mitrovic <none none.none> writes:
I'm in the same situation as the person who posted about this 5 years ago:
http://www.digitalmars.com/d/archives/digitalmars/D/learn/thiscall_calling_convention_4943.html

This isn't so much relevant to COM as it is to this ASIO implementation. The
issue is that only Microsoft compilers can use the 'thiscall' calling
convention which is used with ASIO, while for other compilers your best options
are to either use inline assembly when calling functions, or to compile a DLL
wrapper using a Microsoft compiler (there's OpenAsio which does exactly that).

I could use the OpenAsio DLL wrapper, but I'd like to see if this could be done
with inline asm instead.

Here's what one call looks like for a C++ Borland compiler (see the
Resolver::init wrapper function):
http://codepad.org/rArgvPZC

In D, I can call a function like IASIO.init() without issues, and some other
functions such as "getDriverVersion" which take no parameters will work. But
trying to use functions which take parameters will fail with an access
violation, probably because D uses stdcall for COM methods, while these ASIO
COM methods need to be called with 'thiscall' convention.

I've attempted to translate this to D's inline asm but I get back access
violations. Here's my attempt:
http://codepad.org/gFLJ9RJd

I admit I barely know much asm but I thought I'd give it a shot. Calling
"IASIO.init()" works for me, of course. But calling any IASIO methods which
take parameters will fail since parameters are passed differently in the
'thiscall' convention.

Anyone know how to translate that asm block to D so it's valid?
Apr 23 2011
next sibling parent reply Simon <s.d.hammett gmail.com> writes:
On 24/04/2011 02:23, Andrej Mitrovic wrote:
 I'm in the same situation as the person who posted about this 5 years ago:
http://www.digitalmars.com/d/archives/digitalmars/D/learn/thiscall_calling_convention_4943.html

 This isn't so much relevant to COM as it is to this ASIO implementation. The
issue is that only Microsoft compilers can use the 'thiscall' calling
convention which is used with ASIO, while for other compilers your best options
are to either use inline assembly when calling functions, or to compile a DLL
wrapper using a Microsoft compiler (there's OpenAsio which does exactly that).

 I could use the OpenAsio DLL wrapper, but I'd like to see if this could be
done with inline asm instead.

 Here's what one call looks like for a C++ Borland compiler (see the
Resolver::init wrapper function):
 http://codepad.org/rArgvPZC

 In D, I can call a function like IASIO.init() without issues, and some other
functions such as "getDriverVersion" which take no parameters will work. But
trying to use functions which take parameters will fail with an access
violation, probably because D uses stdcall for COM methods, while these ASIO
COM methods need to be called with 'thiscall' convention.

 I've attempted to translate this to D's inline asm but I get back access
violations. Here's my attempt:
 http://codepad.org/gFLJ9RJd

 I admit I barely know much asm but I thought I'd give it a shot. Calling
"IASIO.init()" works for me, of course. But calling any IASIO methods which
take parameters will fail since parameters are passed differently in the
'thiscall' convention.

 Anyone know how to translate that asm block to D so it's valid?

IASIO is an abstract data type; it's a COM interface. you can't declare it as a member of your class as you have done: Your code: class Resolver { IASIO that_; Borland code: class Resolver { IASIO* that_; Notice the * In your code the struct will be 4 bytes long, while the real struct will be a lot bigger. You can never declare any COM interface as a real structure in your code. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Apr 23 2011
parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
And by calling IASIO.controlPanel(), I mean calling it on the instance.

E.g.:
class Foo
{
    IASIO bar; // can call bar.controlPanel();
}
Apr 23 2011
parent Simon <s.d.hammett gmail.com> writes:
On 24/04/2011 03:25, Andrej Mitrovic wrote:
 And by calling IASIO.controlPanel(), I mean calling it on the instance.

 E.g.:
 class Foo
 {
      IASIO bar; // can call bar.controlPanel();
 }

Not sure how D handles interfaces. If bar is implicitly a pointer then the bit where you do: void *this_ = &that_; means you are loading a pointer to a pointer. Try losing the & -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Apr 24 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Then how come I can create an instance with CoCreateInstance without
the call failing and returning "S_OK" which means the call succeeded,
and I can also call void functions like IASIO.controlPanel() and get
back this:
http://imgur.com/v4Uct
Apr 23 2011
prev sibling next sibling parent Kagamin <spam here.lot> writes:
Andrej Mitrovic Wrote:

 But trying to use functions which take parameters will fail with an access
violation, probably because D uses stdcall for COM methods, while these ASIO
COM methods need to be called with 'thiscall' convention.

COM uses stdcall convention. Everything else is not COM.
Apr 24 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Nevermind guys I'll just use OpenAsio.
Apr 24 2011