我正在尝试编译和链接访问postgresql数据库的c程序,从数据库调用函数并输出函数的结果。我正在关注此处https://www.postgresql.org/docs/current/libpq-example.html和此处https://www.postgresql.org/docs/17/libpq-build所述的文档。 html。这是我的程序代码:
#include <stdio.h>
#include <stdlib.h>
#include "libpq-fe.h"
static void Terminate(PGconn* conn) {
PQfinish(conn);
exit(1);
}
int main() {
const char* conn_info = "dbname = myDB";
PGconn* conn;
PGresult* res;
int nfields;
conn = PQconnectdb(conn_info);
if (PQstatus(conn) != CONNECTION_OK) {
printf("%s", PQerrorMessage(conn));
Terminate(conn);
}
res = PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)");
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
printf("%s", PQerrorMessage(conn));
PQclear(res);
Terminate(conn);
}
PQclear(res);
while (1 == 1) {
int command_code;
printf("Enter command code:\n");
scanf("%d", &command_code);
switch (command_code) {
case 1: // Fetch something.
res = PQexec(conn, "SELECT my_function();");
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
PQerrorMessage(conn);
PQclear(res);
Terminate(conn);
}
nfields = PQnfields(res);
for (int i = 0; i < nfields; ++i) {
printf("%-15s", PQfname(res, i));
printf("\n\n");
}
for (int i = 0; i < PQntuples(res); i++) {
for (int j = 0; j < nfields; j++) printf("%-15s", PQgetvalue(res, i, j));
printf("\n");
}
PQclear(res);
break;
case 0:
Terminate(conn);
break;
default:
printf("Unknown command.\n");
break;
}
}
}
我正在“Windows”操作系统上使用“clang”编译器使用以下命令来编译它:
clang Main.c -o server.obj -I 'C:\Program Files\PostgreSQL\17\include'
我正在尝试使用以下命令将生成的 server.obj 文件链接到库:
clang -o server server.obj -L 'C:\Program Files\PostgreSQL\17\lib' -lpq
程序编译得很好,但我在链接时遇到错误。以下是我得到的错误墙的一部分:
C:/Software/MSYS2/ucrt64/bin/ld: C:\Program Files\PostgreSQL\17\lib/libpq.a(src/interfaces/libpq/libpq.a.p/fe-misc.c.obj):(.text$mn+0xc7): undefined reference to `__imp_select'
C:/Software/MSYS2/ucrt64/bin/ld: C:\Program Files\PostgreSQL\17\lib/libpq.a(src/interfaces/libpq/libpq.a.p/fe-misc.c.obj):(.text$mn+0xd3): undefined reference to `__imp_WSAGetLastError'
C:/Software/MSYS2/ucrt64/bin/ld: C:\Program Files\PostgreSQL\17\lib/libpq.a(src/interfaces/libpq/libpq.a.p/fe-misc.c.obj):(.text$mn+0xe0): undefined reference to `__imp_WSAGetLastError'
C:/Software/MSYS2/ucrt64/bin/ld: C:\Program Files\PostgreSQL\17\lib/libpq.a(src/interfaces/libpq/libpq.a.p/fe-misc.c.obj):(.text$mn+0x12d): undefined reference to `__security_check_cookie'
C:/Software/MSYS2/ucrt64/bin/ld: C:\Program Files\PostgreSQL\17\lib/libpq.a(src/interfaces/libpq/libpq.a.p/fe-misc.c.obj):(.text$mn+0x7f): undefined reference to `libintl_dgettext'
C:/Software/MSYS2/ucrt64/bin/ld: C:\Program Files\PostgreSQL\17\lib/libpq.a(src/interfaces/libpq/libpq.a.p/fe-misc.c.obj):(.text$mn+0xd1): undefined reference to `__imp_WSAGetLastError'
C:/Software/MSYS2/ucrt64/bin/ld: C:\Program Files\PostgreSQL\17\lib/libpq.a(src/interfaces/libpq/libpq.a.p/fe-misc.c.obj):(.text$mn+0x10): undefined reference to `__security_cookie'
C:/Software/MSYS2/ucrt64/bin/ld: C:\Program Files\PostgreSQL\17\lib/libpq.a(src/interfaces/libpq/libpq.a.p/fe-misc.c.obj):(.text$mn+0x191): undefined reference to `__imp_select'
C:/Software/MSYS2/ucrt64/bin/ld: C:\Program Files\PostgreSQL\17\lib/libpq.a(src/interfaces/libpq/libpq.a.p/fe-misc.c.obj):(.text$mn+0x19d): undefined reference to `__imp_WSAGetLastError'
链接器是否应该自行解析所有未定义的引用?如果我指定包含目录本身而不指定要链接的所有对象文件(如果需要 - 按顺序),链接器不应该正确链接它吗?我应该使用什么链接命令才能使其最终链接? 如果需要,这里是程序版本: PostgreSQL 17.1; 铿锵19.1.3。 在搜索解决方案时,我了解到指定链接对象文件的顺序实际上很重要,因此应首先指定您的程序,然后应按依赖顺序指定所有链接文件:在依赖提供程序之后依赖。我还发现了这 2 个帖子:https://libpqxx-general.gborg.postgresql.narkive.com/pgLhr8zR/lots-of-undefined-references-linking-with-mingw-msys 和https://www.postgresql.org/message-id/CACS8yHKjrFOoTKKFOOted4d%2B16oN438DE0ydtp9y5QrxvcGp2w%40mail.gmail.com从那里我看到链接libpq还需要链接到lpgport和lpgcommon。我将链接命令更改为
clang -o server server.obj -L 'C:\Program Files\PostgreSQL\17\lib' -lpgport -lpgcommon -lpq
但没有什么区别。我尝试以不同的顺序放置链接文件,但它不起作用。我也尝试使用 gcc 编译器并得到相同的错误。我不知道是什么原因导致链接错误。我的 postgress(我于 2024 年 11 月 19 日从官方网站下载)工作得很好,但由于这个错误我无法使用它的 API。关于如何使其链接有什么建议吗?这个错误花了 5 个小时,希望得到任何帮助
通过降级到 postgreSQL 16.4 解决了该问题。安装版本 16.4 后,我按照文档教程“libpq-build”进行操作,并且我的应用程序与文档中提供的链接器命令链接,没有任何“未定义引用”或“未定义符号”错误。