Board index » delphi » Re: Thiscall
Avatar Zondertau
![]() Delphi Developer |
Avatar Zondertau
![]() Delphi Developer |
Re: Thiscall2005-05-12 05:05:40 PM delphi171 Quotefunction Thiscall(ClassRef, ProcRef: Pointer; inline. |
Thaddy
![]() Delphi Developer |
2005-05-12 05:24:30 PM
Re: Thiscall
"Nicholas Sherlock" <XXXX@XXXXX.COM>writes news:4282f2be$XXXX@XXXXX.COM...
QuoteHey all, Now we work with Delphi and ASIO by a stub dll that translates it to stdcall. Is it possible to use such an interface from Delphi w.o. the necessity for the stub dll? I suspect we need some BASM tricks, that why I post it here. |
Florent Ouchet
![]() Delphi Developer |
2005-05-12 05:47:10 PM
Re: ThiscallQuoteGiven a COM interface written in MSVC++ without an explicit calling convention specified, can I assume it to have the ThisCall Calling convention? (The Steinberg Asio interfaces) This could be easily translated to delphi. //--------------------------------------------------------------------------- ASIOBool __fastcall init(IASIO* Driver, void* sysHandle) { ASIOBool Result; __asm { mov eax, sysHandle push eax mov ecx, Driver mov eax, [ecx] call [eax+12] mov Result, eax }; return Result; }; //--------------------------------------------------------------------------- void getDriverName(IASIO* Driver, char *name) { __asm { mov eax, name push eax mov ecx, Driver mov eax, [ecx] call [eax+16] }; }; //--------------------------------------------------------------------------- long getDriverVersion(IASIO* Driver) { long Result; __asm { mov ecx, Driver mov eax, [ecx] call [eax+20] mov Result, eax }; return Result; }; //--------------------------------------------------------------------------- void getErrorMessage(IASIO* Driver, char *string) { __asm { mov eax, string push eax mov ecx, Driver mov eax, [ecx] call [eax+24] }; }; //--------------------------------------------------------------------------- ASIOError start(IASIO* Driver) { ASIOError Result; __asm { mov ecx, Driver mov eax, [ecx] call [eax+28] mov Result, eax }; return Result; }; //--------------------------------------------------------------------------- ASIOError stop(IASIO* Driver) { ASIOError Result; __asm { mov ecx, Driver mov eax, [ecx] call [eax+32] mov Result, eax }; return Result; }; //--------------------------------------------------------------------------- ASIOError __fastcall getChannels(IASIO* Driver, long *numInputChannels, long *numOutputChannels) { ASIOError Result; __asm { mov eax, numOutputChannels push eax mov eax, numInputChannels push eax mov ecx, Driver mov eax, [ecx] call [eax+36] mov Result, eax }; return Result; }; //--------------------------------------------------------------------------- ASIOError getLatencies(IASIO* Driver, long *inputLatency, long *outputLatency) { ASIOError Result; __asm { mov eax, outputLatency push eax mov eax, inputLatency push eax mov ecx, Driver mov eax, [ecx] call [eax+40] mov Result, eax }; return Result; }; //--------------------------------------------------------------------------- ASIOError getBufferSize(IASIO* Driver, long *minSize, long *maxSize, long *preferredSize, long *granularity) { ASIOError Result; __asm { mov eax, granularity push eax mov eax, preferredSize push eax mov eax, maxSize push eax mov eax, minSize push eax mov ecx, Driver mov eax, [ecx] call [eax+44] mov Result, eax }; return Result; }; //--------------------------------------------------------------------------- ASIOError canSampleRate(IASIO* Driver, ASIOSampleRate sampleRate) { ASIOError Result; void *sampleRate_ (&sampleRate); __asm { mov eax, sampleRate_ push [eax+4] push [eax] mov ecx, Driver mov eax, [ecx] call [eax+48] mov Result, eax }; return Result; }; //--------------------------------------------------------------------------- ASIOError getSampleRate(IASIO* Driver, ASIOSampleRate *sampleRate) { ASIOError Result; __asm { mov eax, sampleRate push eax mov ecx, Driver mov eax, [ecx] call [eax+52] mov Result, eax }; return Result; }; //--------------------------------------------------------------------------- ASIOError setSampleRate(IASIO* Driver, ASIOSampleRate sampleRate) { ASIOError Result; void *sampleRate_ (&sampleRate); __asm { mov eax, sampleRate_ push [eax+4] push [eax] mov ecx, Driver mov eax, [ecx] call [eax+56] mov Result, eax }; return Result; }; //--------------------------------------------------------------------------- ASIOError getClockSources(IASIO* Driver, ASIOClockSource *clocks, long *numSources) { ASIOError Result; __asm { mov eax, numSources push eax mov eax, clocks push eax mov ecx, Driver mov eax, [ecx] call [eax+60] mov Result, eax }; return Result; }; //--------------------------------------------------------------------------- ASIOError setClockSource(IASIO* Driver, long reference) { ASIOError Result; __asm { mov eax, reference push eax mov ecx, Driver mov eax, [ecx] call [eax+64] mov Result, eax }; return Result; }; //--------------------------------------------------------------------------- ASIOError getSamplePosition(IASIO* Driver, ASIOSamples *sPos, ASIOTimeStamp *tStamp) { ASIOError Result; __asm { mov eax, tStamp push eax mov eax, sPos push eax mov ecx, Driver mov eax, [ecx] call [eax+68] mov Result, eax }; return Result; }; //--------------------------------------------------------------------------- ASIOError getChannelInfo(IASIO* Driver, ASIOChannelInfo *info) { ASIOError Result; __asm { mov eax, info push eax mov ecx, Driver mov eax, [ecx] call [eax+72] mov Result, eax }; return Result; }; //--------------------------------------------------------------------------- ASIOError createBuffers(IASIO* Driver, ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks) { ASIOError Result; __asm { mov eax, callbacks push eax mov eax, bufferSize push eax mov eax, numChannels push eax mov eax, bufferInfos push eax mov ecx, Driver mov eax, [ecx] call [eax+76] mov Result, eax }; return Result; }; //--------------------------------------------------------------------------- ASIOError disposeBuffers(IASIO* Driver) { ASIOError Result; __asm { mov ecx, Driver mov eax, [ecx] call [eax+80] mov Result, eax }; return Result; }; //--------------------------------------------------------------------------- ASIOError controlPanel(IASIO* Driver) { ASIOError Result; __asm { mov ecx, Driver mov eax, [ecx] call [eax+84] mov Result, eax }; return Result; }; //--------------------------------------------------------------------------- ASIOError future(IASIO* Driver, long selector,void *opt) { ASIOError Result; __asm { mov eax, opt push eax mov eax, selector push eax mov ecx, Driver mov eax, [ecx] call [eax+88] mov Result, eax }; return Result; }; //--------------------------------------------------------------------------- ASIOError outputReady(IASIO* Driver) { ASIOError Result; __asm { mov ecx, Driver mov eax, [ecx] call [eax+92] mov Result, eax }; return Result; }; |
Florent Ouchet
![]() Delphi Developer |
2005-05-12 06:21:41 PM
Re: Thiscall
//---------------------------------------------------------------------------
function init(Driver: IASIO; SysHandle: Pointer): ASIOBool; asm push SysHandle mov ecx, Driver mov eax, [ecx] call [eax+12] end; //--------------------------------------------------------------------------- procedure GetDriverName(Driver: IASIO; Name: PChar); asm push name mov ecx, Driver mov eax, [ecx] call [eax+16] end; //--------------------------------------------------------------------------- function GetDriverVersion(Driver: IASIO): Integer; asm mov ecx, Driver mov eax, [ecx] call [eax+20] end; //--------------------------------------------------------------------------- procedure GetErrorMessage(Driver: IASIO; Error: PChar); asm push Error mov ecx, Driver mov eax, [ecx] call [eax+24] end; //--------------------------------------------------------------------------- function Start(Driver: IASIO): ASIOError; asm mov ecx, Driver mov eax, [ecx] call [eax+28] end; //--------------------------------------------------------------------------- function Stop(Driver: IASIO): ASIOError; asm mov ecx, Driver mov eax, [ecx] call [eax+32] end; //--------------------------------------------------------------------------- function GetChannels(Driver: IASIO; NumInputChannels, NumOutputChannels: PInteger): ASIOError; asm push NumOutputChannels push NumInputChannels mov ecx, Driver mov eax, [ecx] call [eax+36] end; //--------------------------------------------------------------------------- function GetLatencies(Driver: IASIO; InputLatency, OutputLatency: PInteger): ASIOError; asm push OutputLatency push InputLatency mov ecx, Driver mov eax, [ecx] call [eax+40] end; //--------------------------------------------------------------------------- function GetBufferSize(Driver: IASIO; MinSize, MaxSize, PreferredSize, Granularity: PInteger): ASIOError; asm push Granularity push PreferredSize push MaxSize push MinSize mov ecx, Driver mov eax, [ecx] call [eax+44] end; //--------------------------------------------------------------------------- function CanSampleRate(Driver: IASIO; SampleRate: ASIOSampleRate): ASIOError; asm push DWORD PTR [SampleRate+4] push DWORD PTR [SampleRate] mov ecx, Driver mov eax, [ecx] call [eax+48] end; //--------------------------------------------------------------------------- function GetSampleRate(Driver: IASIO; SampleRate: PASIOSampleRate): ASIOError; asm push SampleRate mov ecx, Driver mov eax, [ecx] call [eax+52] end; //--------------------------------------------------------------------------- function SetSampleRate(Driver: IASIO; SampleRate: ASIOSampleRate): ASIOError; asm push DWORD PTR [SampleRate+4] push DWORD PTR [SampleRate] mov ecx, Driver mov eax, [ecx] call [eax+56] end; //--------------------------------------------------------------------------- function GetClockSources(Driver: IASIO; Clocks: PASIOClockSource; NumSources: PInteger): ASIOError; asm push NumSources push Clocks mov ecx, Driver mov eax, [ecx] call [eax+60] end; //--------------------------------------------------------------------------- function SetClockSource(Driver: IASIO; Reference: Integer): ASIOError; asm push Reference mov ecx, Driver mov eax, [ecx] call [eax+64] end; //--------------------------------------------------------------------------- function GetSamplePosition(Driver: IASIO; sPos: PASIOSamples; TimeStamp: PASIOTimeStamp): ASIOError; asm push TimeStamp push sPos mov ecx, Driver mov eax, [ecx] call [eax+68] end; //--------------------------------------------------------------------------- function GetChannelInfo(Driver: IASIO; Info: PASIOChannelInfo): ASIOError; asm push Info mov ecx, Driver mov eax, [ecx] call [eax+72] end; //--------------------------------------------------------------------------- function CreateBuffers(Driver: IASIO; BufferInfos: PASIOBufferInfo; NumChannels, BufferSize: Integer; CallBacks: PASIOCallBacks): ASIOError; asm push Callbacks push BufferSize push NumChannels push BufferInfos mov ecx, Driver mov eax, [ecx] call [eax+76] end; //--------------------------------------------------------------------------- function DisposeBuffers(Driver: IASIO): ASIOError; asm mov ecx, Driver mov eax, [ecx] call [eax+80] end; //--------------------------------------------------------------------------- function ControlPanel(Driver: IASIO): ASIOError; asm mov ecx, Driver mov eax, [ecx] call [eax+84] end; //--------------------------------------------------------------------------- function Future(Driver: IASIO; Selector: Integer; Option: Pointer): ASIOError; asm push Option push Selector mov ecx, Driver mov eax, [ecx] call [eax+88] end; //--------------------------------------------------------------------------- function OutputReady(Driver: IASIO): ASIOError; asm mov ecx, Driver mov eax, [ecx] call [eax+92] end; |
Nicholas Sherlock
![]() Delphi Developer |
2005-05-13 12:32:36 PM
Re: Thiscall
Avatar Zondertau writes:
QuoteIndeed it looks like the function is not perofrming a check for that Gives: exception message : Access violation at address 004F492B in module '<module name...>'. Write of address 00003D8C. While the code I have written as a test performs fine: asm mov ecx, classref mov edx, procref mov eax, 200 push eax mov eax, 200 push eax call edx end; Cheers, Nicholas Sherlock |
Avatar Zondertau
![]() Delphi Developer |
2005-05-13 01:10:02 PM
Re: ThiscallQuoteStill having problems. Calling your routine with: Params: array of Longword): LongWord; asm PUSH EBX MOV EBX, [EBP+8] TEST EBX, EBX JS @@ParamsDone LEA ECX, [ECX+EBX*4] @@ParamLoop: PUSH DWORD PTR [ECX] LEA ECX, [ECX-4] DEC EBX JNS @@ParamLoop @@ParamsDone: MOV ECX, EAX CALL EDX POP EBX end; |
Nicholas Sherlock
![]() Delphi Developer |
2005-05-13 01:31:01 PM
Re: Thiscall
Avatar Zondertau writes:
QuoteAnd like this? Nicholas Sherlock |
Avatar Zondertau
![]() Delphi Developer |
2005-05-13 02:33:51 PM
Re: ThiscallQuote>And like this? be returned, but i forgot to change the line that loads the class pointer as well, so the class pointer was invalid. |