对于Delphi中的局部变量,带GMEM_的globalalloc是可移动的吗?
我们的编程部门刚刚花了大约一个非虚构的人月来跟踪我们认为是第三方组件中的bug,以下是他们受版权保护的源代码:对于Delphi中的局部变量,带GMEM_的globalalloc是可移动的吗?,delphi,winapi,memory,gdi+,tms,Delphi,Winapi,Memory,Gdi+,Tms,我们的编程部门刚刚花了大约一个非虚构的人月来跟踪我们认为是第三方组件中的bug,以下是他们受版权保护的源代码: function TGDIPPicture.GetImageSizes: boolean; var multi: TGPImage; pstm: IStream; hGlobal: THandle; pcbWrite: Longint; begin result := false; if Empty then Exit; if FDataStr
function TGDIPPicture.GetImageSizes: boolean;
var
multi: TGPImage;
pstm: IStream;
hGlobal: THandle;
pcbWrite: Longint;
begin
result := false;
if Empty then
Exit;
if FDataStream.Size = 0 then
Exit;
hGlobal := GlobalAlloc(GMEM_MOVEABLE, FDataStream.Size);
if (hGlobal = 0) then
raise Exception.Create('Could not allocate memory for image');
try
pstm := nil;
// Create IStream* from global memory
CreateStreamOnHGlobal(hGlobal, TRUE, pstm);
pstm.Write(FDataStream.Memory, FDataStream.Size,@pcbWrite);
multi := TGPImage.Create(pstm);
FWidth := multi.GetWidth;
FHeight := multi.GetHeight;
Result := true;
multi.Free;
finally
GlobalFree(hGlobal);
end;
end;
我们发现问题出在TMS的AdvOfficeAbset上。如果我们添加了标签,它就会崩溃,如果我们不添加标签,它就不会崩溃。(崩溃是一个不可调试的应用程序挂起,在真正的问题出现10步后,它会击中你)
接下来,我用GPTR替换了GMEM_MOVEABLE,它似乎已经解决了这个问题
我想知道是否有人能告诉我上面的代码是否有使用GMEM_MOVEABLE的正当理由。好吧,它只用于剪贴板,应该始终与GlobalAlloc一起使用
当我输入这个时,另一个程序员使用我的代码在GlobalFree函数中出错。所以,显然这也不起作用。这里真的需要一些帮助 *CreateStreamOnHGlobal是一个Windows API函数。(显然)
*TGPImage是TMS实现GDI+库的一部分。Jonathan发现了一个明显的问题,那就是HGLOBAL的双自由度。但正如您所发现的,使用GMEM_MOVEABLE是正确的 坦率地说,代码似乎不必要地复杂。我建议您使用内置流适配器,避免使用任何GlobalAlloc。要获得IStream,您只需执行以下操作:
pstm := TStreamAdapter.Create(FDataStream);
就是这样。乔纳森已经发现了一个明显的问题,那就是双自由度。但正如您所发现的,使用GMEM_MOVEABLE是正确的 坦率地说,代码似乎不必要地复杂。我建议您使用内置流适配器,避免使用任何GlobalAlloc。要获得IStream,您只需执行以下操作:
pstm := TStreamAdapter.Create(FDataStream);
就是这样。乔纳森已经发现了一个明显的问题,那就是双自由度。但正如您所发现的,使用GMEM_MOVEABLE是正确的 坦率地说,代码似乎不必要地复杂。我建议您使用内置流适配器,避免使用任何GlobalAlloc。要获得IStream,您只需执行以下操作:
pstm := TStreamAdapter.Create(FDataStream);
就是这样。乔纳森已经发现了一个明显的问题,那就是双自由度。但正如您所发现的,使用GMEM_MOVEABLE是正确的 坦率地说,代码似乎不必要地复杂。我建议您使用内置流适配器,避免使用任何GlobalAlloc。要获得IStream,您只需执行以下操作:
pstm := TStreamAdapter.Create(FDataStream);
就是这样。您正在为
fDeleteOnRelease
参数传递TRUE
到CreateStreamOnHGlobal()
,这意味着流现在拥有内存句柄,您不应该自己调用GlobalFree()。您似乎也没有释放流(除非Delphi自动为您释放,或者可能是TGPImage.Create
does?如果是这样,您肯定会得到一个双空闲内存句柄)。我不知道这些东西是否导致了你的崩溃,但是在这种情况下使用GMEM\u MOVEABLE
没有固有的问题,所以我很确定这不是问题所在。这是真正的代码吗?它有很多问题。不指定结果值。缺少错误检查。等等我们如何确定GlobalAlloc是问题所在。谢谢,这是我们第三次尝试使用一个我们根本不想使用的函数时要尝试的!我试着在CreateStreamOnHGlobal中把真改假,遇到了不同的问题,一些真实的事情,希望你所说的是正确的和唯一的答案。@DavidHeffernan是的,它来自TMS,我会想象我通过发布这篇文章侵犯了一些版权,但它应该被修复,它不够新颖,不足以关心版权。如果可能的话,我宁愿不使用globals——这对我来说不会有太大的改变。很难相信TMS写的。这很复杂。您正在为fDeleteOnRelease
参数传递TRUE
到CreateStreamOnHGlobal()
,这意味着流现在拥有内存句柄,您不应该自己调用GlobalFree()。您似乎也没有释放流(除非Delphi自动为您释放,或者可能是TGPImage.Create
does?如果是这样,您肯定会得到一个双空闲内存句柄)。我不知道这些东西是否导致了你的崩溃,但是在这种情况下使用GMEM\u MOVEABLE
没有固有的问题,所以我很确定这不是问题所在。这是真正的代码吗?它有很多问题。不指定结果值。缺少错误检查。等等我们如何确定GlobalAlloc是问题所在。谢谢,这是我们第三次尝试使用一个我们根本不想使用的函数时要尝试的!我试着在CreateStreamOnHGlobal中把真改假,遇到了不同的问题,一些真实的事情,希望你所说的是正确的和唯一的答案。@DavidHeffernan是的,它来自TMS,我会想象我通过发布这篇文章侵犯了一些版权,但它应该被修复,它不够新颖,不足以关心版权。如果可能的话,我宁愿不使用globals——这对我来说不会有太大的改变。很难相信TMS写的。这很复杂。您正在为fDeleteOnRelease
参数传递TRUE
到CreateStreamOnHGlobal()
,这意味着流现在拥有内存句柄,您不应该自己调用GlobalFree()。您似乎也没有释放流(除非Delphi自动为您释放,或者可能是TGPImage.Create
does?如果是这样,您肯定会得到一个双空闲内存句柄)。我不知道这些东西是否导致了你的崩溃,但是在这种情况下使用GMEM\u MOVEABLE
没有固有的问题,所以我很确定这不是问题所在。这是真正的代码吗?它有很多问题。不指定结果值。缺少错误检查。等等我们如何确定GlobalAlloc是e