【问题标题】:Direct2D COM calls returning 64-bit structs and C++Builder 2010Direct2D COM 调用返回 64 位结构和 C++Builder 2010
【发布时间】:2020-01-02 11:17:56
【问题描述】:

我正在尝试获取 Direct2D 位图的大小并立即崩溃。

// props and target etc all set up beforehand.
CComPtr<ID2D1Bitmap> &b;
target->CreateBitmap(D2D1::SizeU(1024,1024), frame.p_data, 1024* 4, &props, &b));

D2D_SIZE_U sz = b->GetPixelSize();  // Crashes here.

使用位图的所有其他操作(包括绘制它)都可以正常工作。它只是返回似乎是问题的大小。

根据 Rudy V 这样的文章,我怀疑它与 C++Builder 2010 以及 COM 函数如何返回 64 位结构有些不兼容。 http://rvelthuis.de/articles/articles-convert.html

GetPixelSize 的 Delphi 声明如下所示:(来自 D2D1.pas)

// Returns the size of the bitmap in resolution dependent units, (pixels).
procedure GetPixelSize(out pixelSize: TD2D1SizeU); stdcall; 

...在 D2D1.h 中是

//
// Returns the size of the bitmap in resolution dependent units, (pixels).
//
STDMETHOD_(D2D1_SIZE_U, GetPixelSize)(
    ) CONST PURE;

我可以在不重写 D2D 标头的情况下解决此问题吗?

欢迎所有建议 - 除了从 C++Builder 2010 升级,这是一项比我目前准备好的任务更多的任务。

【问题讨论】:

  • 您可以在自己的代码中复制ID2D1Bitmap,然后重新声明其GetPixelSize(),通过输出引用参数返回D2D_SIZE_U,就像Delphi代码一样。跨度>
  • @RemyLebeau 谢谢。经过一些测试后,我意识到拥有“固定”d2d1.h 的本地副本可能是最简单的方法。 STDMETHOD_(void, GetPixelSize)( __out D2D1_SIZE_U* size ) CONST PURE;

标签: com direct2d c++builder-2010


【解决方案1】:

“getInfo”是从 Delphi 代码派生的函数,可以解决。

void getInfo(void* itfc, void* info, int vmtofs)
{
    asm {
        push info           // pass pointer to return result
        mov eax,itfc        // eax poionts to interface
        push eax            // pass pointer to interface
        mov eax,[eax]       // eax points to VMT
        add eax,vmtofs      // eax points rto address of virtual function
        call dword ptr [eax]    // call function
    }
}

反汇编CBuilder生成的代码,导致崩溃:

Graphics.cpp.162: size = bmp->GetSize();
00401C10 8B4508           mov eax,[ebp+$08]
00401C13 FF7004           push dword ptr [eax+$04]
00401C16 8D55DC           lea edx,[ebp-$24]
00401C19 52               push edx
00401C1A 8B4D08           mov ecx,[ebp+$08]
00401C1D 8B4104           mov eax,[ecx+$04]
00401C20 8B10             mov edx,[eax]
00401C22 FF5210           call dword ptr [edx+$10]
00401C25 8B4DDC           mov ecx,[ebp-$24]
00401C28 894DF8           mov [ebp-$08],ecx
00401C2B 8B4DE0           mov ecx,[ebp-$20]
00401C2E 894DFC           mov [ebp-$04],ecx

“bmp”被声明为

ID2D1Bitmap* bmp;

调用“getInfo”的代码:

D2D1_SIZE_F size;
getInfo(bmp,&pf,0x10);

你从反汇编行“call dword ptr [edx+$10]”得到 0x10 (vmtofs)

您可以通过调用“getInfo”来调用“GetPixelSize”、“GetPixelFormat”等

D2D1_SIZE_U ps;// = bmp->GetPixelSize();
getInfo(bmp,&ps,0x14);
D2D1_PIXEL_FORMAT pf;// = bmp->GetPixelFormat();
getInfo(bmp,&pf,0x18);

“getInfo”与“STDMETHOD_ ... CONST PURE;”方法一起使用,返回结果。

STDMETHOD_(D2D1_SIZE_F, GetSize)(
    ) CONST PURE;

对于这种方法,CBuilder 会生成故障代码。

万一

STDMETHOD_(void, GetDpi)(
    __out FLOAT *dpiX,
    __out FLOAT *dpiY 
    ) CONST PURE;

CBuilder 代码工作正常,“getDpi”结果无效。

【讨论】:

    猜你喜欢
    • 2013-03-22
    • 2013-07-01
    • 1970-01-01
    • 2021-03-06
    • 1970-01-01
    • 2017-07-04
    • 2017-08-20
    • 1970-01-01
    • 2011-01-27
    相关资源
    最近更新 更多