【发布时间】:2014-09-12 23:17:42
【问题描述】:
我想将 7Zip 的 SDK 翻译成 Delphi/Pascal 的单元文件。首先,我尝试使用 BCC32.exe 为 Win32 平台编译 C 文件:
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 格式。
然后我尝试使用 Microsoft Windows SDK 中的 cl.exe 来生成 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 生成可以由Delphi 单元在Win32 和Win64 平台上编译的.OBJ 文件?
【问题讨论】:
-
我使用 cl 生成与
$LINK静态链接的对象。我看不到您是如何尝试这样做的,因此我无法告诉您出了什么问题。很难知道你为什么问这个问题,但忽略了所有关键细节。您为 bcc32 和 bcc64 提供了命令行,但没有为 cl 提供命令行,这就是您要问的!第 1 步是让一个简单的功能起作用。int sum(int x1, int x2) { return x1 + x2; }一旦你能做到这一点,让它变得更复杂。 -
FWIW,当我这样做时,我对 32 位对象使用 bcc32,对 64 位对象使用 cl。在我看来,您的错误似乎来自 32 位 Delphi 编译器。我建议您继续使用 32 位的 bcc32。
-
@DavidHeffernan:我编辑主题并添加 Delphi 示例和
cl.exe编译选项。 -
既然您已经有了一个适用于 32 位的解决方案,为什么要改变它呢?就目前而言,我什至不确定您是在询问 32 位还是 64 位。
-
FWIW,我听说,从尝试过这个的人那里(但我自己没有证实这一点),XE6 可以消耗 64 位 COFF 和 64 位 ELF 文件。