此问题在此处已有答案:
What is an undefined reference/unresolved external symbol error and how do I fix it?(39答案)
11天前关闭。
背景知识:
首先,我解释一下到目前为止我对这些gcc
标志的理解:
-L
:gcc手册中说明,此标志将指定目录“添加到要搜索的目录列表中-l
”
**-l
:**再次按照手册所说的,“链接时搜索名为library的库”。
所以,我对这两个的理解是,第一个将目录添加到一个列表中,第二个将被链接器搜索到,并命名为library!
**-I
:对此,说明书上说:“将目录dir添加到在预处理期间搜索头文件的目录列表中”!所以我假设这一个和-L
**一样,但是用于头文件。-Wl
:-Wl部分向链接器发送逗号分隔的选项
我想做的是:
我想编译/构建一个使用3.so共享库的可执行文件;其中2个(libpq
和libsqlite3
)由官方第三方供应商(Postgresql和Sqlite)提供;并安装了apt install
。
第三个是我的;我自己写的,并试图将它与我的可执行文件链接,以便能够在运行时使用它。
目前为止我尝试的是:
如果我使用下面的命令编译我的代码,而不使用我自己的库(以及代码中的相应函数),它可以正常工作:
g++ -std=c++20 full.cpp -o loadTester -L/usr/include/postgresql/libpq -lpq -lsqlite3
字符串
然而,使用这些命令,也链接我自己的库与我的代码,我得到错误:
gcc -std=gnu17 -shared -o liblogwritter.so -fPIC logWritter.c
g++ -std=c++20 full-with-logger.cpp -o loadTester -L/usr/include/postgresql/libpq -L./ -lpq -lsqlite3 -llogwritter -Wl,-rpath=./ -I./
型
我还尝试用完整路径替换./
部分:/home/username/Desktop/Current/
.
错误:
/usr/bin/ld: /tmp/ccSFD38J.o: in function `pgConncetionInit(char const*)':
full-with-logger.cpp:(.text+0xc3): undefined reference to `logWritter(char const*)'
/usr/bin/ld: /tmp/ccSFD38J.o: in function `pgInsertQuery(char**)':
full-with-logger.cpp:(.text+0x709): undefined reference to `logWritter(char const*)'
/usr/bin/ld: /tmp/ccSFD38J.o: in function `main':
full-with-logger.cpp:(.text+0x1994): undefined reference to `logWritter(char const*)'
/usr/bin/ld: full-with-logger.cpp:(.text+0x19e2): undefined reference to `logWritter(char const*)'
/usr/bin/ld: full-with-logger.cpp:(.text+0x1b0e): undefined reference to `logWritter(char const*)'
collect2: error: ld returned 1 exit status
型
库代码:
logWriter.c
:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SV_SOCK_PATH "/tmp/shahab_logger"
int logWritter(const char* messageData)
{
struct sockaddr_un addr;
// Create a new client socket with domain: AF_UNIX, type: SOCK_STREAM, protocol: 0
int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
// Construct server address, and make the connection.
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, SV_SOCK_PATH, sizeof(addr.sun_path) - 1);
if (connect(sfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) == -1)
{
fprintf(stderr, "Error connecting to server\n");
return 0;
}
write(sfd, messageData, strlen(messageData));
close(sfd);
return 0;
}
型
logWriter.h
:
#ifndef LOGWRITTER_H
#define LOGWRITTER_H
int logWritter(const char* messageData);
#endif // LOGWRITTER_H
型
myprogram.cpp
:
... //Several lines removed
logWritter(jobExecTime.c_str());
... //Several lines removed
型
注意:
我为我的库做了一个简单的驱动程序,如下所示,它工作得很好(前提是我之前运行server.c
来接受套接字连接):
#include <stdio.h>
#include <stdlib.h>
#include "logWritter.h"
int main()
{
printf("Test driver program!\n");
if (logWritter("Test driver program!") > 0)
{
printf("Error!\n");
exit(1);
}
return 0;
}
型
我编译了这个驱动程序如下:
gcc -c -Wall -Werror -fpic logWritter.c
gcc -shared logWritter.o -o liblogwritter.so
gcc -Wall testDriver.c -o testDriver -L/home/username/Desktop/logger/ -llogwritter -Wl,-rpath=/home/username/Desktop/logger/
型
注2:
以下是/home/username/Desktop/Current/
中的文件列表(所有文件都存在),以防万一:
activity_main.db full.cpp full-with-logger.cpp liblogwritter.so logServer
logWritter.c logWritter.h postgresInit.sql run.sh server.c sqliteInit.sql unix_socket.h
型
提问:
我认为在这一点上是显而易见的,在阅读了这么长的帖子之后(我对你的国王努力和时间的最大敬意和赞赏),但要遵循这里的标准:
1.我在第一节中解释的理解是正确的吗?
1.“我是什么人?”张晓飞问道。
1.我应该如何编译我的可执行文件?请解释这两种情况,我复制的头文件在/usr/include/
和共享库文件在/usr/local/lib
,或者如果我想从当前的工作文件夹链接它们,因为它是现在在上面的例子的情况下.
1条答案
按热度按时间xj3cbfub1#
由于您在.c中定义了
logWritter
,因此在C++中使用时必须使用C链接声明它,因此logWriter.h必须是字符串