奇怪的"未定义引用"错误

6

我正在尝试使用C语言在Windows API之上创建一个非常简单的抽象库。我制作了一个简单的Makefile,但是当我尝试使用Msys构建项目时,出现了以下错误:

winapi.o: In function `get_client_pid':
(long path)/winapi.c:13: undefined reference to `GetExtendedTcpTable'
(long path)/winapi.c:31: undefined reference to `GetExtendedTcpTable'
collect2.exe: error: ld returned 1 exit status
make: *** [lib] Error 1

get_client_pid()在winapi.c中被定义为:

#include <stdint.h>
#include <stdio.h>
#include <windows.h>
#include <Iphlpapi.h>

#define true 1
#define false 0


    uint32_t get_client_pid()
    {
        MIB_TCPTABLE_OWNER_PID *tcpTable;
        PDWORD tableSize;
        DWORD ret = GetExtendedTcpTable(tcpTable, 
                                        tableSize, 
                                        true, 
                                        2, 
                                        TCP_TABLE_OWNER_PID_ALL,
                                        0);

        if (ret == NO_ERROR) {
            printf("ERROR get_client_pid: No error with table size at 0?\n");
            return 0;
        }
        if (ret != ERROR_INSUFFICIENT_BUFFER) {
            printf("ERROR get_client_pid: No insufficient buffer with table size at 0?\n");
            return 0;
        }
        printf("TABLE SIZE %d\n", *tableSize);
        tcpTable = malloc(*tableSize);

        ret = GetExtendedTcpTable(  tcpTable,
                                    tableSize, 
                                    true,
                                    2,
                                    TCP_TABLE_OWNER_PID_ALL,
                                    0);

        if (ret != NO_ERROR) {
            printf("ERROR get_client_pid: GetExtendedTcpTable error: %d\n", ret);
            free(tcpTable);
            return 0;
        }

        int i;
        for (i = 0; i < tcpTable->dwNumEntries; i++) {
            MIB_TCPROW_OWNER_PID row = tcpTable->table[i];
            if (row.dwRemotePort == 0x208 && row.dwRemoteAddr == 0x100007F) {
                printf("FOUND PROCESS: %d\n", row.dwOwningPid);
                free(tcpTable);
                return row.dwOwningPid;
            }
        }

        free(tcpTable);
        return 0;
    }

因为这是一个链接错误,所以我会添加我的makefile:

current_dir = $(shell pwd)

all: test

test: lib
    gcc -c -g tests.c
    gcc -o tests.exe tests.o -L$(current_dir) -lwinapi

lib:
    gcc -c -g winapi.c
    gcc -shared -o winapi.dll winapi.o -lIphlpapi -luser32

clean:
    rm *.o

我必须说,我尝试了每一个可能的地方来插入“-lIphlpapi”,以防链接顺序出错,但那并没有起到帮助作用。


C++ 名称修饰问题? - Etan Reisner
尝试添加一个来自user32的函数调用,看看是否链接。 - user325117
我对你的 makefile 不是完全满意。winapi.dll 应该依赖于 winapi.o,而 winapi.o 应该依赖于 winapi.c。"clean" 应该删除 tests.exe 和 winapi.dll。 - user325117
@MartinBroadhurst 我是个初学者,所以这个 makefile 不怎么样。我会加上那些改动的。我刚刚测试了一下,来自 user32 的 IsWindow() 没有返回链接错误。 - vuolen
抓住稻草,你尝试过更改大小写吗?使用“-liphlpapi”而不是“-lIphlpapi”? - user325117
显示剩余6条评论
1个回答

2

在windef.h中,MinGW将WINVER定义为0x400(Windows NT),这意味着一些较新的Windows功能将无法链接。

#ifndef WINVER
#define WINVER 0x0400
/*
 * If you need Win32 API features newer the Win95 and WinNT then you must
 * define WINVER before including windows.h or any other method of including
 * the windef.h header.
 */
#endif

如果你需要针对特定版本的Windows进行开发,那么在包含任何Windows头文件之前,你需要自己定义WINVER的版本。

可以使用以下任意一个定义:

#define WINVER 0x0500 // Windows 2000
#define WINVER 0x0501 // Windows XP
#define WINVER 0x0502 // Windows Server 2003
#define WINVER 0x0600 // Windows Vista, Windows Server 2008
#define WINVER 0x0601 // Windows 7
#define WINVER 0x0602 // Windows 8
#define WINVER 0x0603 // Windows 8.1
#define WINVER 0x0A00 // Windows 10

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接