Einzelnen Beitrag anzeigen

Kas Ob.

Registriert seit: 3. Sep 2023
439 Beiträge
 
#10

AW: Direct2D Anwendung

  Alt Heute, 09:02
Be careful it is full of miss ordered functions with overload
Bitte genauer, und mit Dokumentation:
COM Interfaces in Pascal brauchen (um was zu verhindern?)
eine andere deklarierte Reihenfolge der Methoden als im MS SDK header (.h)?
Well, the thing is there is no documentation for this very thing, i searched for these declaration many times, i didn't search for Delphi/Pascal headers, but for different languages and didn't find anything except in Rust, and to be clear, Rust has the most elegant translation for Windows SDK and DDK, also i always look for Rust libraries for specific codes values when it is hard to extract it from SDK and DDK headers,

So let me show and point to one or more example about this very problem, and remember one thing the declaration header and methods order is SDK is exactly as the documentation in Microsoft site,
1) IDWriteGdiInterop1 from https://learn.microsoft.com/en-us/wi...itegdiinterop1 has four methods
Zitat:
IDWriteGdiInterop1::CreateFontFromLOGFONT
Creates a font object that matches the properties specified by the LOGFONT structure. (IDWriteGdiInterop1.CreateFontFromLOGFONT)

IDWriteGdiInterop1::GetFontSignature
Reads the font signature from the given font. (overload 2/2)

IDWriteGdiInterop1::GetFontSignature
Reads the font signature from the given font. (overload 1/2)

IDWriteGdiInterop1::GetMatchingFontsByLOGFONT
Gets a list of matching fonts based on the specified LOGFONT values. Only fonts of that family name will be returned.
Do you see the (2/2) then (1/2), well it must means something, if you click on them then you will have them like this
Zitat:
HRESULT GetFontSignature(
IDWriteFont *font,
FONTSIGNATURE *fontSignature
);

HRESULT GetFontSignature(
IDWriteFontFace *fontFace,
FONTSIGNATURE *fontSignature
);
So the first take font and the second will take fontFace , let see how Rust declare them from https://docs.rs/winapi/latest/winapi...iInterop1.html
Code:
Source
impl IDWriteGdiInterop1
Source
pub unsafe fn CreateFontFromLOGFONT(
    &self,
    logFont: *const LOGFONTW,
    fontCollection: *mut IDWriteFontCollection,
    font: *mut *mut IDWriteFont,
) -> HRESULT
Source
pub unsafe fn GetFontSignature_2(
    &self,
    fontFace: *mut IDWriteFontFace,
    fontSignature: *mut FONTSIGNATURE,
) -> HRESULT
Source
pub unsafe fn GetFontSignature_1(
    &self,
    font: *mut IDWriteFont,
    fontSignature: *mut FONTSIGNATURE,
) -> HRESULT
Source
pub unsafe fn GetMatchingFontsByLOGFONT(
    &self,
    logFont: *const LOGFONTW,
    fontSet: *mut IDWriteFontSet,
    filteredSet: *mut *mut IDWriteFontSet,
) -> HRESULT
Now we see the fontFace then font also the added number which goes right with (2/2) and (1/2) in reversed order, how Delphi do it ? well i put it up in earlier post https://github.com/FactoryXCode/MfPa...#L1439C3-L1485

2) IDWriteFontFace4 from https://learn.microsoft.com/en-us/wi...writefontface4 has the same as (1), watch the parameters
https://github.com/FactoryXCode/MfPa...#L1709C3-L1756
now compare with Rust declaration
https://docs.rs/winapi/latest/winapi...FontFace4.html
The only difference now we only have one with number of order (1/2) for the second one in the SDK

3) This case is peculiar and interesting as it is fixed and swapped !
IDWriteFactory3 https://learn.microsoft.com/en-us/wi...dwritefactory3
has these overloaded in this order, also notice they don't have numbers (?/?)
Zitat:
HRESULT CreateFontFaceReference(
IDWriteFontFile *fontFile,
UINT32 faceIndex,
DWRITE_FONT_SIMULATIONS fontSimulations,
IDWriteFontFaceReference **fontFaceReference
);

HRESULT CreateFontFaceReference(
WCHAR const *filePath,
FILETIME const *lastWriteTime,
UINT32 faceIndex,
DWRITE_FONT_SIMULATIONS fontSimulations,
IDWriteFontFaceReference **fontFaceReference
);
the order here is method take first parameter as fontFile then filePath
in Pascal translation the order is right !
https://github.com/FactoryXCode/MfPa....pas#L553-L584
Delphi-Quellcode:
    function CreateFontFaceReference(filePath: PWideChar;
                                     lastWriteTime: FILETIME;
                                     faceIndex: UINT32;
                                     fontSimulations: DWRITE_FONT_SIMULATIONS;
                                     out fontFaceReference: IDWriteFontFaceReference): HResult; overload; stdcall;


    function CreateFontFaceReference(fontFile: IDWriteFontFile;
                                     faceIndex: UINT32;
                                     fontSimulations: DWRITE_FONT_SIMULATIONS;
                                     out fontFaceReference: IDWriteFontFaceReference): HResult; overload; stdcall;
And in Rust https://docs.rs/winapi/latest/winapi...eFactory3.html
Code:
pub unsafe fn CreateFontFaceReference_2(
    &self,
    fontFile: *mut IDWriteFontFile,
    faceIndex: UINT32,
    fontSimulations: DWRITE_FONT_SIMULATIONS,
    fontFaceReference: *mut *mut IDWriteFontFaceReference,
) -> HRESULT
Source
pub unsafe fn CreateFontFaceReference_1(
    &self,
    filePath: *const WCHAR,
    lastWriteTime: *const FILETIME,
    faceIndex: UINT32,
    fontSimulations: DWRITE_FONT_SIMULATIONS,
    fontFaceReference: *mut *mut IDWriteFontFaceReference,
) -> HRESULT
Rust order without the _1 and _2 is wrong !, yet the numbers here will save you as Rust has extra layer and will use the right order based on the suffixes _1 and _2
So this one was fixed in Pascal/Delphi and i think the reason is someone tried to use it and found the right order to make it work, unlike many others !
Also notice how they are declared in the SDK header file
https://github.com/apitrace/dxsdk/bl..._3.h#L436-L461 and this is identical to the SDK documentation.

Why this happen ?
1) While Delphi is rightfully very strict in building the VTable, Visual Studio and every other compiler is also rightfully can change the order.
2) While VT is something belongs to the compiler to decide when and where, Delphi is right, Visual Studio on other hand rearrange them as see fit, and here i am not talking about interfaces, just VT in general, VS compiler optimize the table.
3) The problem in my opinion is from very old introduced bug and when Windows SDK introduced interface, ATL and COM they failed to foresee the incompatibility with compilers form different languages, so they can't change their own SDK and they can't break compiler it self for libs that already being built, hence they left it like that undocumented and don't want to talk about it and don't to document it !

@pcoder, i added examples here and hope they are clear or clearer to see and fact checking if there is questions then please explain it in details.

Hope that helps.
Kas
  Mit Zitat antworten Zitat