<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>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>
    </p>
    <pre class="code highlight" lang="delphi"><code><span class=""> TObject = </span><span
    class="hljs-keyword">class</span><span class="">
</span></code><span><span class="hljs-meta">{$IFDEF SYSTEM_HAS_FEATURE_MONITOR}</span><span
    class=""></span></span>
<span><span class="">       </span><span class="hljs-keyword">strict</span><span
    class=""> </span><span class="hljs-keyword">private</span><span
    class=""></span></span>
<span><span class="">          _MonitorData : Pointer;</span></span>
<span><span class="">       </span><span class="hljs-keyword">private</span><span
    class=""></span></span>
<span><span class="">          </span><span class="hljs-function"><span
    class="hljs-keyword">function</span><span class="hljs-function"> </span><span
    class="hljs-title">SetMonitorData</span><span class="hljs-params">(aData,aCheckOld : Pointer)</span><span
    class="hljs-function"> :</span></span><span class=""> Pointer; </span><span
    class="hljs-keyword">inline</span><span class="">;</span></span>
<span><span class="">          </span><span class="hljs-function"><span
    class="hljs-keyword">function</span><span class="hljs-function"> </span><span
    class="hljs-title">GetMonitorData</span><span class="hljs-function">:</span></span><span
    class=""> Pointer; </span><span class="hljs-keyword">inline</span><span
    class="">;</span></span>
<span><span class="">       </span><span class="hljs-meta">{$ENDIF}</span><span
    class=""></span></span>
       ...
</pre>
    <p> </p>
    <p>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.</p>
    <p>The idea is simple enough. There is a single entry point to the
      Firebird client library with the Pascal signature</p>
    <p><font face="monospace">function fb_get_master_interface :
        IMaster; cdecl;</font> <br>
    </p>
    <p>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".</p>
    <p>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>
    </p>
    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>
    <p>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. 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.</p>
    <p>Also, does anyone know whether a similar problem will arise with
      Delphi, or is thus just an FPC issue?</p>
    <p>One of the following seems to be needed:</p>
    <p>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>
    </p>
    <p>b) Taking a different approach to introducing _MonitorData e.g.</p>
    <p>i) Putting in a class helper (is this possible?)</p>
    <p>ii) Having a version of TObject (e.g. TUnmonitoredObject) which
      is the current TObject and making TObject a descendent class
      introducing _MonitorData. The Firebird classes can then descend
      from TUnMonitoredObject, either explicitly or as a result of a new
      compiler directive setting the default class ancestor.</p>
    <p>iii) Anything else that works.<br>
    </p>
    <p>I am primarily looking for a solution that will work with IBX,
      but also one that I can suggest to the Firebird Devs to make
      generally available. <br>
    </p>
    <p>Tony Whyman</p>
    <p>MWA Software<br>
    </p>
  </body>
</html>