使用c的Windows api编程:对OpenJobObject的未定义引用

F. *_* K. 5 c windows winapi

我正在尝试编写一个简短的程序,它允许我通过其名称终止Windows作业对象.这是TerminateJobObject.c文件的(shortend)代码:

#ifndef _WIN32_WINNT
    #define _WIN32_WINNT 0x600
#endif

#define JOB_OBJECT_TERMINATE 0x0008

#include <windows.h>
#include <tchar.h> 
#include <stdio.h>
#include <limits.h>



LPTSTR jobObjectName; 
HANDLE jobObj; 

int main(int argc, TCHAR *argv[]){
    jobObjectName = argv[0];    
    jobObj = OpenJobObject(JOB_OBJECT_TERMINATE,FALSE,jobObjectName);
    TerminateJobObject(jobObj,0);

}
Run Code Online (Sandbox Code Playgroud)

使用"gcc TerminateJobObject.c -o TerminateJobObject"进行编译时出现以下错误:

TerminateJobObject.c: In function 'main'
C:/<...>:TerminateJobObject.c:(.text+0x62):undefined reference to 'OpenJobObject'
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

我不明白为什么链接器无法解析OpenJobObject.TerminateJobObject正确链接,也来自windows api.

到目前为止我尝试了什么:

  • 编译器:gcc,clang
  • _WIN32_WINNT的不同版本(0x500,0x600,0x601)
  • 不同的操作系统:Windows 7和Windows Server 2008
  • "OpenJobObjectW"和"OpenJobObjectA"
  • 定义WINVER

我对c和windows api不是很有经验,也找不到任何关于这个问题的东西,所以如果有人能指出我的话会很棒.

Api参考:OpenJobObject

F. *_* K. 1

我解决了。问题是 mingw32 的头文件 winbase.h(通过 windows.h 包含)缺少 OpenJobObject 的函数定义,正如 Harry Johnston 所怀疑的那样。

我将以下行添加到 .../mingw/include/winbase.h

#define OpenJobObject __MINGW_NAME_AW(OpenJobObject)
WINBASEAPI HANDLE WINAPI OpenJobObjectA (DWORD dwDesiredAccess, WINBOOL bInheritHandle, LPCSTR lpName);
WINBASEAPI HANDLE WINAPI OpenJobObjectW (DWORD dwDesiredAccess, WINBOOL bInheritHandle, LPCWSTR lpName);
Run Code Online (Sandbox Code Playgroud)

我在mingw-w64的 winbase.h 中找到的

接下来,我将调用更改为“OpenJobObjectA”,现在它可以工作了。:) 谢谢您的帮助!

编辑:正如 Hans Passant 指出的,更干净的方法可能是迁移到 mingw-64 或其他东西。

  • 我希望你意识到这是你会后悔的事情。像这样破解标头有创建“仅在我的机器上编译”项目的技巧。最好将其放入源代码中,并用#ifndef OpenJobObject 封装。切换到 mingw-w64 是可持续的解决方案。 (3认同)