<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body smarttemplateinserted="true">
    <div id="smartTemplate4-template">Hi,<br>
      <br>
      <blockquote type="cite"><br>
        This field was introduced for Delphi compatibility: <br>
        The implementation of TMonitor requires this data. <br>
        <br>
        Delphi has this field as well but "hides" the field behind all
        other actually declared fields. <br>
        <br>
        If you examine the actual memory size allocated for TObject,
        you'll see that an extra field is actually present. <br>
      </blockquote>
      <br>
      <p>that is bad news <br>
      </p>
    </div>
    <div>Now all objects become 8 bytes larger?<br>
    </div>
    <div><br>
    </div>
    <div>That is going to waste a lot of space. FPC was supposed to be
      memory efficient.<br>
    </div>
    <div><br>
    </div>
    <div><br>
    </div>
    <div><br>
    </div>
    <div>Could this not use a global hashmap with tobject as key? <br>
    </div>
    <div><br>
    </div>
    <div><br>
      Cheers,<br>
      Benito <br>
      <br>
    </div>
    <div class="moz-cite-prefix">On 02.05.24 14:55, Michael Van Canneyt
      via fpc-pascal wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:68f53a46-e0c2-85f-91af-921ea72cd5e@freepascal.org"> <br>
      <br>
      On Thu, 2 May 2024, Tony Whyman via fpc-pascal wrote: <br>
      <br>
      <blockquote type="cite">This is a problem reported to me by an IBX
        user. I have not yet confirmed it (need to find the time to set
        up the latest development branch of FPC), but the issue looks
        solid, and is due to the following addition to TObject (copied
        from the GitLab master branch) <br>
        <br>
        |TObject = class|{$IFDEF SYSTEM_HAS_FEATURE_MONITOR} <br>
        strictprivate <br>
        _MonitorData : Pointer; <br>
        private <br>
        functionSetMonitorData(aData,aCheckOld : Pointer):Pointer;
        inline; <br>
        functionGetMonitorData:Pointer; inline; <br>
        {$ENDIF} <br>
              ... <br>
        <br>
        Since Firebird 3.0, the Firebird project has provided a file
        called "Firebird.pas" in order to provide an interface to Pascal
        (both Delphi and FPC) from a C++ environment. There is an
        underlying assumption in the interface. That is TObject contains
        no fields. <br>
      </blockquote>
      <br>
      This assumption is not valid in Delphi either. It also has this
      field, but <br>
      it is 'hidden' at a not-fixed location. <br>
      <br>
      <blockquote type="cite"> <br>
        The idea is simple enough. There is a single entry point to the
        Firebird client library with the Pascal signature <br>
        <br>
        function fb_get_master_interface : IMaster; cdecl; <br>
        <br>
        This returns a pointer to a structure that may contain fields
        but is primarily a list of pointers to cdecl functions. These
        functions can perform various tasks. In the case of IMaster,
        they can also return similar structures representing other
        "interfaces". <br>
        <br>
        On the Pascal side, IMaster is defined as a class with no
        virtual methods and a single field called "vTable" and this is
        set to the pointer to the structure returned by
        fb_get_master_interface. The rest of the class comprises methods
        used to call functions from the vTable. This makes IMaster look
        like a normal class and hides the use of function pointers. The
        code is generated by a program know as "cloop". All Firebird
        interfaces declared in Firebird.pas follow the same approach. <br>
        <br>
        Given the assumption that TObject defines no fields, it is
        possible to coerce the pointer returned by
        fb_get_master_interface to appear as an object "instance" of the
        IMaster class, and similarly for every other Firebird interface
        class. This coercion ceases to be valid as soon as a field, such
        as _MonitorData is added to TObject. <br>
        <br>
        It is probably a valid argument to say that this is Firebird's
        problem as the TObject definition is an internal data structure.
        However, this ignores a serious real world problem. <br>
      </blockquote>
      <br>
      The real problem is the invalid assumption. <br>
      <br>
      This assumption is invalid for Delphi as well. TObject is not
      empty there either. The memory layout is simply different. <br>
      <br>
      <blockquote type="cite">A fix or workaround is needed and that has
        to be in Firebird.pas. It would be a logistic nightmare to try
        and change the C++ Firebird client DLL/SO. <br>
      </blockquote>
      <br>
      It would be a logistic nightmare in FPC as well. <br>
      <br>
      <blockquote type="cite"> <br>
        Also, does anyone know whether a similar problem will arise with
        Delphi, or is thus just an FPC issue? <br>
        <br>
        One of the following seems to be needed: <br>
        <br>
        a) Rewriting Firebird.pas to set the vTable field explicitly
        rather than implicitly through coercion - ideally without
        breaking any user code... (note: no current need to free IMaster
        etc) <br>
        <br>
        b) Taking a different approach to introducing _MonitorData e.g.
        <br>
      </blockquote>
      <br>
      This field was introduced for Delphi compatibility: <br>
      The implementation of TMonitor requires this data. <br>
      <br>
      Delphi has this field as well but "hides" the field behind all
      other actually declared fields. <br>
      <br>
      If you examine the actual memory size allocated for TObject,
      you'll see that an extra field is actually present. <br>
      <br>
      In FPC this turned out to be not so easy to do without modifying
      the compiler, so it was decided that the cleanest approach is to
      actually introduce the field as part of TObject. <br>
      <br>
      The firebase people use a trick to save you some work, based on an
      invalid assumption. <br>
      I don't think this is sufficient reason to expect the FPC team to
      adapt their compiler. <br>
      <br>
      The correct solution is to change the cloop program to produce a
      pascal record definition with procedural type fields at the
      correct offsets. It should be perfectly usable without too many
      changes. <br>
      <br>
      So something like (adapt to actual procedure types) <br>
      <br>
      Type <br>
        RMaster = Record <br>
          init : procedure(xyz:sometype); <br>
          // etc <br>
        end; <br>
        IMaster = ^RMaster; <br>
      <br>
        // optionally; although it seems this already exists? <br>
        TMaster = class <br>
          intf : IMaster; <br>
          procedure Init(xyz : sometype); <br>
          constructor create; <br>
        end; <br>
      <br>
      <br>
      function fb_get_master_interface : IMaster; cdecl; <br>
      <br>
      constructor TMaster.Create; <br>
      <br>
      begin <br>
        intf:=fb_get_master_interface; <br>
      end; <br>
      <br>
      Procedure TMaster.Init(xyz : sometype); <br>
      begin <br>
        intf^.init(xyz); <br>
      end; <br>
      <br>
      if you cannot change cloop, you can use fcl-passrc or some other
      tool to actually parse the definition generated by cloop and
      change it to a record, possibly with a wrapper class for easier
      access as in the above. <br>
      <br>
      That should not be difficult to do, and it will work in Delphi as
      well. <br>
      The advantage is that it will be more robust against future
      changes as it <br>
      makes no assumptions about the layout of objects. <br>
      <br>
      Michael. <br>
      _______________________________________________ <br>
      fpc-pascal maillist  -  <a
        class="moz-txt-link-abbreviated moz-txt-link-freetext"
        href="mailto:fpc-pascal@lists.freepascal.org">fpc-pascal@lists.freepascal.org</a>
      <br>
      <a class="moz-txt-link-freetext"
href="https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal">https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal</a>
      <br>
    </blockquote>
  </body>
</html>