代码之家  ›  专栏  ›  技术社区  ›  Chau Chee Yang

无法在Delphi XE4 Win64平台中使用cl.exe编译的C的.OBJ文件

  •  0
  • Chau Chee Yang  · 技术社区  · 11 年前

    我想把7Zip的SDK翻译成Delphi/Pascal的单元文件。首先,我尝试使用 BCC32.exe 对于Win32平台:

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

    它的产量很少 .OBJ 文件,并且我能够在Delphi单元中使用这些对象而没有问题。

    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.
    

    然后尝试使用 BCC64.exe 对于Win64平台:

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

    这一次,它产生的 .o 文件,但编译Delphi单元时出错:

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

    我了解到Delphi Win64识别的对象文件格式是64位COFF,而BCC64.exe生成 ELF64 总体安排

    然后我尝试使用 cl.exe 从Microsoft Windows SDK生成Win32和Win64 .OBJ文件 文件夹,

    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
    

    但我得到了这些错误:

    [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'
    

    如何使用 cl.exe文件 生产 .OBJ文件 可以在Win32和Win64平台上由Delphi单元编译的文件?

    1 回复  |  直到 11 年前
        1
  •  2
  •   Community Mohan Dere    9 年前

    这有点令人困惑,但在德尔福,

    • 对于64位,可以使用例如Microsoft的64位编译器生成的64位COFF文件。据报道,Delphi XE6 64位也能够与64位ELF文件链接,因为C++Builder 64位生成了这些文件。

    • 对于32位,可以使用32位OMF C 对象文件,由C++Builder生成。Delphi XE2和更新版本(请参见 this link 来自David Heffernan的评论)也允许您链接到32位COFF。

    有关此主题的更多信息: Using C object files in Delphi

    因此,自从DelphiXE6以来,您实际上可以再次使用C++Builder为两个平台生成Delphi可链接对象文件。