![]() |
Re: D3D9 Hook bzw. als "proxy.dll"
Was heißt denn jetzt "funktioniert nicht"? Hast du das mal debuggt?
Christian, der Funktionsprototyp darf nicht verändert werden. Wenn man als Result ein Interface, dynamisches Array, String oder Variant verwendet, wird intern ein out-Parameter verwendet - man verändert also die Aufrufkonvention. |
Re: D3D9 Hook bzw. als "proxy.dll"
Um was geht es? COM Methoden oder Standardfunktionen?
Der Result ist hier ein Pointer, original ist ein Interface. |
Re: D3D9 Hook bzw. als "proxy.dll"
Naja, die C++-Deklaration sieht so aus:
Code:
Und wenn ich in Delphi schreibe
IDirect3D9 * Direct3DCreate9(
UINT SDKVersion );
Delphi-Quellcode:
dürfte das in C++ so heraus kommen:
function Direct3DCreate9(SDKVersion: Cardinal): IDirect3D9; stdcall;
Code:
Sofern ich mich nicht irre, werden Typen mit RefCount (d.h. finalisierungsbedürftige Typen) immer als out-Parameter zurückgegeben.
void Direct3DCreate9(UINT SDKVersion, IDirect3D9** result);
Nebenbei bemerkt scheint beim Threadersteller ein stdcall verloren gegangen zu sein. |
Re: D3D9 Hook bzw. als "proxy.dll"
Ich bezog mich garnicht auf die Übersetzung, sondern nur, dass man Interfaces als Result zurückgeben kann.
Aber stimmt schon, wenn man es übersetzt dann über einen Pointer. D.h. die Routine muss gekapselt werden und die neue Routine darf nur öffentlich sein. Allerdings, der Header definiert das stdcall garnicht. |
Re: D3D9 Hook bzw. als "proxy.dll"
Stimmt, das stdcall fehlt - sehr seltsam. Register ist es allerdings auf keinen Fall.
|
Re: D3D9 Hook bzw. als "proxy.dll"
I think this is a Delphi bug, I remember it because I had a problem with some other winapi call that returned an interface.
I quickly tested this (I used IUnknown because I don't have DirectX):
Delphi-Quellcode:
When I look in the CPU window we can see the problem:
function Direct3DCreate9(SDKVersion: Cardinal): IUnknown; stdcall; external 'd3d9.dll';
procedure TForm2.Button1Click(Sender: TObject); var Unknown: IUnknown; begin Unknown := Direct3DCreate9(32); end;
Delphi-Quellcode:
For some reason Delphi put's the result (which is in eax when using stdcall) on stack (push eax).
Unit2.pas.31: Unknown := Direct3DCreate9(32);
004A3B0F 6A20 push $20 004A3B11 8D45F8 lea eax,[ebp-$08] 004A3B14 50 push eax 004A3B15 E8CEFFFFFF call Direct3DCreate9 If I declare like this it looks ok:
Delphi-Quellcode:
The CPU window shows:
function Direct3DCreate9(SDKVersion: Cardinal): Pointer; stdcall; external 'd3d9.dll';
procedure TForm2.Button1Click(Sender: TObject); var Unknown: IUnknown; begin Pointer(Unknown) := Direct3DCreate9(32); end;
Delphi-Quellcode:
Unit2.pas.31: Pointer(Unknown) := Direct3DCreate9(32);
004A3B0F 6A20 push $20 004A3B11 E8D2FFFFFF call Direct3DCreate9 004A3B16 8945F8 mov [ebp-$08],eax |
Re: D3D9 Hook bzw. als "proxy.dll"
Delphi doesn't really put the result on stack - it uses an out Parameter. You see that the calling routine pushes the address ebp - 8 which is the address of the Unknown variable.
I think that the modified signature using an out-parameter instead of the usual result is reasonable from a design standpoint. Returning an interface in eax is always bad - and never happens in the usual COM context - because it poses a severe problem with respect to exception handling. If an exception occurs when the called routine returns, the interface cannot be released correctly because it is lost when the exception is thrown. Using the Delphi design, on the other hand, the caller retains a reference to the interface and will release it due to the auto-generated try-finally. To sum it up, the Delphi semantics is different to the C++ semantics and perhaps different from naive expectations, but it is the best way to do it in my opinion. The error is on the side of the Direct3D developers because they designed their function to break COM rules. |
Re: D3D9 Hook bzw. als "proxy.dll"
Well, the way I see it it's not a design discussion (although I agree that the Delphi (Safecall) solution is elegant) but what's happening here is that Delphi put's 2 pointers on stack while the dll expects only one. Another example where this happens is
![]() |
Re: D3D9 Hook bzw. als "proxy.dll"
Sure, as I said, you cannot naively translate from/to C++. But SHOpenRegStream2 poses the very same exception problem I described above - I regard this as a bug. By forcing you to think about untyped pointers and reference counting, Delphi doesn't hide this bug. Delphi's interfaces are made to be fail-safe with the automatic reference counting - but this safety simply cannot be provided in the case of SHOpenRegStream2 et al., and Delphi doesn't give any illusions about this.
|
Re: D3D9 Hook bzw. als "proxy.dll"
hat niemand die Deklaration
Delphi-Quellcode:
mal ausprobiert?
function(SDKVersion: LongWord): ^IDirect3D9; stdcall
[UPDATE] Ich meinte mit ^ |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:52 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz