1

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?

Chau Chee Yang
  • 18,422
  • 16
  • 68
  • 132
  • 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 Jul 22 '14 at 08:31
  • 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 Jul 22 '14 at 08:35
  • @DavidHeffernan: I edit the topic and add Delphi example and `cl.exe` compiling options. – Chau Chee Yang Jul 22 '14 at 08:48
  • 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 Jul 22 '14 at 08:57
  • 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 Jul 22 '14 at 08:58
  • @DavidHeffernan: I want to use .obj files for both Win32 and Win64 platform. – Chau Chee Yang Jul 22 '14 at 09:00
  • @RudyVelthuis: Yes, XE6 can consume both COFF and ELF files. Unfortunately, I need solution for XE4. – Chau Chee Yang Jul 22 '14 at 09:03
  • I can help you with 64 bit cl, but not 32 bit cl. Sorry. – David Heffernan Jul 22 '14 at 09:04
  • @DavidHeffernan: How to solve the `__imp_` prefix issue? – Chau Chee Yang Jul 22 '14 at 09:07
  • Like I said, I can help with 64 bit cl, but not 32 bit cl. So I cannot help you since your errors are with 32 bit Delphi, dcc32. I have lots of experience with 64 bit cl, but none with 32 bit cl. Sorry I cannot help. Good luck. – David Heffernan Jul 22 '14 at 09:11
  • And as I already said, you should start with something simple, as I described in my original comment. FWIW, I have a lot of experience linking to C code this way, and I think I could help you if you wanted to be helped. But you'd have to be receptive to my advice. As it stands you are not listening to my advice and instead ask "how do I solve my problem?" repeatedly. You are looking for a quick 30s fix, but you will need to slow down a bit. In my view. – David Heffernan Jul 22 '14 at 09:18

1 Answers1

2

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.

Community
  • 1
  • 1
Rudy Velthuis
  • 28,387
  • 5
  • 46
  • 94
  • Is there an easy way to construct Delphi unit for both the Win32 and Win64 platform? By adding `_PU` in declaration seems not enough. – Chau Chee Yang Jul 22 '14 at 09:09
  • It's strange that people up vote answers that are clearly wrong. Pity upvoting is really rather strange. Perhaps the best policy to collect rep is to write answers with mistakes in as bait for pity upvoters. The point of downvoting is not to hate on people, but to encourage them to either correct or delete their answers. When Rudy realises his mistake, he will of course correct it. And I'll remove the downvote and all will be well. – David Heffernan Jul 22 '14 at 09:27
  • The second bullet point. Read Allen's answer fully in the linked question. – David Heffernan Jul 22 '14 at 11:07
  • What is wrong with the second bullet point? Most Delphi versions need 32 bit OMF files, but the latest versions (not sure if this true for XE4 too) also allow the use of 32 bit COFF files. Note that they must be C object files, i.e. compiled with the C compiler (usually this is achieved by giving the source files the extension .c). – Rudy Velthuis Jul 22 '14 at 11:12
  • @DavidHeffernan: Ok, I rearranged the text a little, and pulled the statement about 32 bit COFF into the bullet. – Rudy Velthuis Jul 22 '14 at 11:19
  • Your answer is now factually accurate. However, it doesn't really address the question that was asked. – David Heffernan Jul 22 '14 at 13:04