Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Delphi exports global variables from DLLs in a similar way to how it exports functions:</p> <pre><code>library exp; var global: Integer; exports global; end. </code></pre> <p>Delphi can import global variables from DLLs, but it's a bit of a hack: declare a DLL import procedure of the same name as the global to import, then get the address of the procedure and adjust it appropriately. DLL imported procedures, from Delphi's perspective, are stubs that do an indirect jump through the DLL import table. Exported variables are linked by the OS loader by putting the address of the exported global in the import table, almost exactly like how addresses of exported procedures are similarly patched in.</p> <p>For example:</p> <pre><code>{$apptype console} procedure global; external 'exp.dll'; function GetGlobalAddr: PInteger; type PPPointer = ^PPointer; var p: PByte; begin p := @global; Assert(p^ = $FF); // $FF $25 =&gt; indirect jump m32 Inc(p); Assert(p^ = $25); Inc(p); Result := PPPointer(p)^^ end; begin Writeln(GetGlobalAddr^); end. </code></pre> <p>Of course, the latter details are implementation and platform dependent etc. Probably a safer approach is to use <code>LoadLibrary</code> with <code>GetProcAddress</code>, which will return the address of the global variable when passed its name. Of course, that's also platform dependent.</p> <p><strong>64-bit update:</strong></p> <p>In 64-bit on Windows, the code is slightly different. The opcodes are the same, but the addressing mode for the same instruction sequence is different; instead of a 32-bit absolute offset, it's a 32-bit relative offset.</p> <pre><code>function GetGlobalAddr: PInteger; type PPPointer = ^PPointer; var p: PByte; ofs: Integer; begin p := @global; Assert(p^ = $FF); // $FF $25 =&gt; indirect jump m32 Inc(p); Assert(p^ = $25); Inc(p); // 32-bit offset follows ofs := PInteger(p)^; // offset is relative to next instruction Inc(p, SizeOf(ofs) + ofs); Result := PPPointer(p)^^ end; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload