使用ld.exe链接到kernel32.dll

问题描述 投票:0回答:3

我已经使用以下命令组装了我的汇编程序:

nasm -f win64 -o test.obj test.asm

test.asm 包含一些调用 Win32 函数的函数,如 GetStdHandle、HeapAlloc 等

通常,我会像这样链接我的装配项目之一:

ld -LC:/Windows/System32 -lkernel32 -e main -o test.exe test.obj

它会生成一个

test.exe
文件,正如预期的那样。

但是,一旦我开始使用 Win32 函数使用堆,例如 HeapAlloc、HeapFree、GetProcessHeap,链接时会出现以下错误:

C:\msys64\mingw64\bin\ld.exe: ertr000016.o:(.rdata+0x0): undefined reference to '_pei386_runtime_relocator'

然后我可以假设它与 MinGW 的文件被链接有关。所以我尝试在没有它们的情况下编译它:

ld -nostdlib -nostartfiles -LC:/Windows/System32 -lkernel32 -e main -o test.exe test.obj

并得到以下错误:

C:\msys64\mingw64\bin\ld.exe: cannot find -lkernel32

所以,我的问题是:我应该如何使用 ld.exe 链接到 kernel32(不包括启动文件或 stdlib),因为无论我尝试什么,我都无法让它工作。

谢谢您的帮助!

(我想要的答案不仅仅是告诉我使用GoLink,除非这是唯一可能的解决方案)。

assembly gcc nasm ld kernel32
3个回答
1
投票

我已经意识到答案就在评论中,但为了清楚起见,我将在此处发布所有步骤:

  1. 为要使用的 DLL 创建一个
    .def
    文件。这可以这样做:
LIBRARY [name of the dll]
EXPORTS
    [required export #1]
    [required export #2]
    [etc.]
  1. 使用
    dlltool.exe
    .def
    文件创建存档库文件:
dlltool -d "[path to the .def file]" -l "[path to output file C, defined below]"

在此命令中,

C
libXXX.a
,其中
XXX
更改为不同的名称(最好是不带扩展名的原始dll的名称)。

  1. 不要使用
    ld.exe
    ,而是使用
    gcc.exe
    中内置的链接器。另外,将
    -L
    之后的目录更改为包含
    libXXX.a
    存档文件的目录,并更改
    XXX
    中替换的
    libXXX.a
    后面的 dll 名称。在原始问题的背景下,这些步骤将是:
[Kernel32.def file]

LIBRARY KERNEL32.DLL
EXPORTS
    HeapAlloc
    HeapFree
    [...]
dlltool -d "kernel32.def" -l "libkernel32.a"
gcc -LC:/path/to/this/directory/ -lkernel32 -e main -o test.exe test.obj

0
投票

我正在

Cygwin
努力让
SDL2
发挥作用

并安装

w32api
/
w32api-headers
/
w32api-runtime
软件包已解决了该问题。

它提供了必要的头文件和lib文件其中

Cygwin
gcc
知道在哪里可以找到(
"/usr/lib/w32api/"


-2
投票
... -LC:/Windows/System32 -lkernel32 ...

这绝对是错误的:

-lkernel32
不会搜索名为
kernel32.dll
的DLL文件,而是搜索名为
libkernel32.a
的库文件。

...并且

libkernel32.a
肯定不位于
C:/Windows/System32

我将如何使用

dlltool.exe
生成我自己的
libkernel32.a

对于 64 位 Windows,这比 32 位 Windows 更容易(因为在 32 位 Windows 中,函数在 DLL 和目标文件中的命名方式不同)。

首先,创建一个定义文件 (

.def
),如下所示:

LIBRARY KERNEL32.DLL
EXPORTS
    HeapAlloc
    HeapFree
    GetProcessHeap
    CreateFileA
    ReadFile

有一个第三方工具可以读取

.dll
文件并生成包含DLL所有函数的
.def
文件;但是,您可以手动执行此操作,并且仅添加您需要的功能。

然后运行以下命令行:

dlltool -d kernel32.def -l libkernel32.a

不幸的是,我无法告诉您这是否可以解决您的问题

_pei386_runtime_relocator

编辑

undefined reference to 'SetFilePointer'

SetFilePointer
也是
kernel32.dll
中定义的函数。您是否将
SetFilePointer
添加到
.def
文件中?

LIBRARY KERNEL32.DLL
EXPORTS
    HeapAlloc
    HeapFree
    GetProcessHeap
    CreateFileA
    ReadFile
    SetFilePointer     <-- HERE?

我正在使用以下命令进行链接:

可能还有第二个问题:

某些版本的

gcc
需要按特定顺序输入命令行参数。也许对于
ld
来说也是如此。

尝试将

-L
-l
参数移至行尾:

ld ... -o test.exe test.o -L... -lkernel32
© www.soinside.com 2019 - 2024. All rights reserved.