如何从Delphi 10.1 Berlin中的类助手访问私有字段?

时间:2016-05-20 16:11:03

标签: delphi class-helpers delphi-10.1-berlin

我想使用Gabriel Corneanu的jpegex,jpeg.TJPEGImage的类助手。 阅读thisthis我已经了解到除了Delphi Seattle之外你不能像jpegex那样访问私有字段了(下例中的FData)。和David Heffernan提出的VMT一样,远远超出我的范围。有没有更简单的方法来完成这项工作?

 <!DOCTYPE html>
 <html lang ="en">
<head>
    <meta charset="utf-8"/>
    <title>File Transfer</title>
    <link rel="stylesheet" href= "/static/styles.css">
</head>
<body>
    <h1>Upload file</h1>
    <form action="{0}" method="POST" enctype="multipart/form-data">
        <table id="uploadFile">
            <tr id="upldF">
                <td id="upldF"><input type="file" name="FileToUpload" id="FileToUpload"></td>
            </tr>
            <tr id="upldF">
                <td id="upldF"><input type="submit" value="Upload File" name="submit"></td>
            </tr>
        </table>
    </form>

    <h1>Download file</h1>
    <form action="/download" method="post">
        <table id="downloadFile" width="100%">
            <tr>
                <td>
                    <table id="downloadFileDetails">
                        <tr id="dld">
                            <td id="dld" width="2%"></td>
                            <td id="dld" width="80%">File Name</td>
                            <td id="dld" width="10%">Upload Date</td>
                            <td id="dld" width="8%">Format</td>
                        </tr>
                        {% for file in file_query %}
                        <tr>
                            <td id="dld" style="vertical-align: middle; text-align: center "><input type="checkbox" name="checkFile" >&nbsp </td>
                            <td id="dld">{{file.file1}}</td>
                            <td id="dld">{{file.create1}}</td>
                            <td id="dld">{{file.type1}}</td>
                        </tr>
                        {% endfor %}
                    </table>
                </td>
            </tr>
            <tr>
                <td><input type="submit" value="Download File" name="submit"></td>
            </tr>
        </table>
    </form>
</body>

3 个答案:

答案 0 :(得分:19)

今天我使用with语句找到了解决这个bug的巧妙方法。

function TValueHelper.GetAsInteger: Integer;
begin
  with Self do begin
    Result := FData.FAsSLong;
  end;
end;

除此之外,Embarcadero在建造墙壁以保护私人部分方面做得很好,这也许就是为什么他们将它命名为10.1柏林。

答案 1 :(得分:14)

小心!这是一个讨厌的黑客攻击,并且当被黑客攻击的类的内部字段结构发生变化时可能会失败。

type
  TJPEGDataHack = class(TSharedImage)
    FData: TCustomMemoryStream; // must be at the same relative location as in TJPEGData!
  end;

  // TJPEGDataHelper
function TJPEGDataHelper.Data: TCustomMemoryStream;
begin
  Result := TJPEGDataHack(self).FData;
end;

这仅在“hack”类的父类与原始类的父类相同时才有效。因此,在这种情况下,TJPEGData继承自TSharedImage,“hack”类也是如此。这些位置也需要匹配,所以如果列表中的FData之前有一个字段,那么等效字段应该位于“hack”类中,即使它没有被使用。

有关其工作原理的完整说明,请访问:

Hack #5: Access to private fields

答案 2 :(得分:7)

通过使用类助手和RTTI的组合,可以使用类助手与以前的Delphi版本具有相同的性能。

诀窍是使用RTTI解决启动时私有字段的偏移量,并将其作为类var 存储在帮助程序中。

CDATA

正如您所看到的,它需要一些额外的打字,但与修补整个单元相比,它很简单。