0
votes

I want to translate 7Zip's SDK to Delphi/Pascal's unit file. First, I try compile the C files using BCC32.exe for Win32 platform:

bcc32.exe -c -D_LZMA_PROB32 -D_WIN32 -v -y Threads.c LzFind.c LzFindMt.c LzmaDec.c LzmaEnc.c

It produces few .OBJ files and I am able to use these objects in Delphi units without problem.

unit Threads;

interface

uses System.Win.Crtl, Winapi.Windows, LzmaTypes, System.Classes;

{$Z4}
type
  TCEvent = THandle;

  TCSemaphore = THandle;

  TCCriticalSection = TRTLCriticalSection;

  TCAutoResetEvent = TCEvent;

  TCThread = THandle;

  TThread_Func_Type = Pointer;

function __beginthreadex(__security_attr: Pointer; __stksize: Cardinal; __start:
    TThread_Func_Type; __arg: Pointer; __create_flags: Cardinal; var
    __thread_id: Cardinal): Cardinal; cdecl; external msvcrt name _PU +
    '_beginthreadex';

function _Event_Reset(var p: TCEvent): TWRes; cdecl; external name _PU +
    'Event_Reset';

function _Event_Set(var p: TCEvent): TWRes; cdecl; external name _PU +
    'Event_Set';

function _Handle_WaitObject(h: THandle): TWRes; cdecl; external name _PU +
    'Handle_WaitObject';

function _Semaphore_Release1(var p: TCSemaphore): TWRes; cdecl; external name
    _PU + 'Semaphore_Release1';

function _HandlePtr_Close(var h: THandle): TWRes; cdecl; external name _PU +
    'HandlePtr_Close';

function _CriticalSection_Init(var p: TCCriticalSection): TWRes; cdecl; external
    name _PU + 'CriticalSection_Init';

function _AutoResetEvent_CreateNotSignaled(var p: TCAutoResetEvent): TWRes;
    cdecl; external name _PU + 'AutoResetEvent_CreateNotSignaled';

function _Semaphore_Create(var p: TCSemaphore; initCount: UInt32; maxCount:
    UInt32): TWRes; cdecl; external name _PU + 'Semaphore_Create';

function _Thread_Create(var p: TCThread; func: TThread_Func_Type; param:
    LPVOID): TWRes; cdecl; external name _PU + 'Thread_Create';

implementation

{$ifdef Win64}
  {$L Win64\Threads.o}
{$else}
  {$L Win32\Threads.obj}
{$endif}

end.

I then attempt to compile these object files using BCC64.exe for Win64 platform:

bcc64.exe -c -D_LZMA_PROB32 -D_WIN64 -v -y Threads.c LzFind.c LzFindMt.c LzmaDec.c LzmaEnc.c

This time, it produces few .o files but I get errors when compile the Delphi unit:

[dcc64 Fatal Error] LzFind.pas(128): F2084 Internal Error: AV0756F5D3-R2D06DB90-0

I learned that the object file format recognized for Delphi Win64 is 64 bit COFF whereas BCC64.exe produces ELF64 format.

I then try to use cl.exe from Microsoft Windows SDK to produce both Win32 and Win64 .OBJ files,

cl.exe -c -D_LZMA_PROB32 -D_WIN32 Threads.c LzFind.c LzFindMt.c LzmaDec.c LzmaEnc.c

x86_amd64\cl.exe -c -D_LZMA_PROB32 -D_WIN64 Threads.c LzFind.c LzFindMt.c LzmaDec.c LzmaEnc.c

but I get these errors:

[dcc32 Error] Threads.pas(64): E2065 Unsatisfied forward or external declaration: '__imp__CloseHandle@4'
[dcc32 Error] Threads.pas(64): E2065 Unsatisfied forward or external declaration: '__imp__GetLastError@0'
[dcc32 Error] Threads.pas(64): E2065 Unsatisfied forward or external declaration: '__imp__InitializeCriticalSection@4'

Any ideas how to use cl.exe to produce .OBJ files that may compiled by Delphi unit in both Win32 and Win64 platform?

1
I use cl to produce objects that I link statically with $LINK. I cannot see how you are attempting to do this, so I cannot tell you what is wrong. Very hard to know why you asked the question but omitted all the crucial details. You supplied command lines for bcc32 and bcc64, but not for cl, which is what you are asking about! Step 1 is to get a simple function to work. int sum(int x1, int x2) { return x1 + x2; } Once you can do that, make it more complex.David Heffernan
FWIW, when I do this, I use bcc32 for the 32 bit objects, and cl for the 64 bit objects. It looks to me as though your errors are from the 32 bit Delphi compiler. I recommend that you continue with bcc32 for 32 bit.David Heffernan
@DavidHeffernan: I edit the topic and add Delphi example and cl.exe compiling options.Chau Chee Yang
Since you've already got a working solution for 32 bit, why change that? As it stands I don't even know for sure whether you are asking about 32 bit or 64 bit.David Heffernan
FWIW, I heard, from people who tried this (but did not confirm this myself), that XE6 can consume 64 bit COFF and 64 bit ELF files.Rudy Velthuis

1 Answers

2
votes

It is a bit confusing, but in Delphi,

  • for 64 bit, you can use 64 bit COFF files as produced by, for instance, Microsoft's 64 bit compiler. Delphi XE6 64 bit is reportedly capable of linking with 64 bit ELF files too, as C++Builder 64 bit produces them.

  • for 32 bit, you can use 32 bit OMF C object files, as produced by C++Builder. Delphi XE2 and newer (see this link from David Heffernan's comment) allow you to link to 32 bit COFF too.

Some more info on the subject: Using C object files in Delphi

So since Delphi XE6, you can actually use C++Builder to generate Delphi-linkable object files for both platforms again.