为啥链接器看不到我的函数(定义宏来替换系统日志)?
Posted
技术标签:
【中文标题】为啥链接器看不到我的函数(定义宏来替换系统日志)?【英文标题】:Why the linker does not see my function (define macro to substitute the syslog)?为什么链接器看不到我的函数(定义宏来替换系统日志)? 【发布时间】:2017-02-24 10:37:11 【问题描述】:我尝试用这种方式替换 syslog
函数:
#include <cstdio>
#include <cstdarg>
void syslog_printf(int level, char* format, ...)
va_list params;
va_start(params, format);
vprintf(format, params);
printf("\n");
va_end(params);
#define syslog(...) syslog_printf(__VA_ARGS__)
#include <modbus/modbus.c>
这是我的 modbus.cpp 文件的列表。 modbus.c 也在那里,但我无法修改它,因为它在多个地方使用过。 modbus.cpp 编译正确,但链接器报告找不到syslog_printf
函数。
问题很简单:为什么?
编辑:
make -k all
Building file: ../modbus.cpp
Invoking: GCC C++ Compiler
g++ -std=c++0x -DDEBUG -I../../include -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"modbus.d" -MT"modbus.d" -o "modbus.o" "../modbus.cpp"
Finished building: ../modbus.cpp
Building target: fire
Invoking: GCC C++ Linker
g++ -o "fire" ./main.o ./modbus.o
./modbus.o: In function `error_treat(modbus_param_t*, int, char const*)':
../../include/modbus/modbus.c:144: undefined reference to `syslog_printf'
./modbus.o: In function `modbus_send(modbus_param_t*, unsigned char*, int)':
../../include/modbus/modbus.c:379: undefined reference to `syslog_printf'
./modbus.o: In function `receive_msg(modbus_param_t*, int, unsigned char*, int*)':
../../include/modbus/modbus.c:482: undefined reference to `syslog_printf'
../../include/modbus/modbus.c:484: undefined reference to `syslog_printf'
../../include/modbus/modbus.c:511: undefined reference to `syslog_printf'
./modbus.o:../../include/modbus/modbus.c:524: more undefined references to `syslog_printf' follow
collect2: error: ld returned 1 exit status
make: *** [makefile:46: fire] Error 1
make: Target 'all' not remade because of errors.
编辑:
如果我尝试将 modbus.cpp 切换到 modbus.c,我会得到:
make -k all
Building file: ../modbus.c
Invoking: GCC C Compiler
gcc -DDEBUG -I../../include -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"modbus.d" -MT"modbus.d" -o "modbus.o" "../modbus.c"
../modbus.c:13:21: error: conflicting types for ‘syslog_printf’
#define syslog(...) syslog_printf(__VA_ARGS__)
^
../modbus.c:4:6: note: previous definition of ‘syslog_printf’ was here
void syslog_printf(int level, char* format, ...)
^~~~~~~~~~~~~
make: *** [subdir.mk:34: modbus.o] Error 1
make: Target 'all' not remade because of errors.
【问题讨论】:
你可能错过了extern "C" ...
除了 modbus.c 之外,您现在还有其他调用 syslog_printf 的 C 文件吗?
@KlitosKyriacou,没有。
如果您将 modbus.cpp 编译为 modbus.o 并将 modbus.c 编译为 modbus.o,您在最后一步中链接的是哪一个?
啊,真的。但从好的方面来说,通过将他的 .cpp 文件重命名为 .c,看起来它揭示了实际问题? :)
【参考方案1】:
“外部”modbus.c 的正确变体是
#include <stdio.h>
#include <stdarg.h>
#include <syslog.h> // I could include it earlier than the "inner" modbus.c will do...
void syslog_printf(int level, char* format, ...)
va_list params;
va_start(params, format);
vprintf(format, params);
printf("\n");
va_end(params);
#define syslog(...) syslog_printf(__VA_ARGS__)
#include <modbus/modbus.c>
感谢大家,评论了我的问题。
【讨论】:
我不确定我是否理解您的回答。您是说通过在 syslog_printf 的定义之前包含<syslog.h>
来解决问题?
@KlitosKyriacou,是的,你(几乎)是对的。我可以在#define syslog...
之前使用#include <syslog.h>
,因为“内部” modbus.c 也包含了syslog.h
,而这种包含在第一个变体中影响了我的#define syslog...
。以上是关于为啥链接器看不到我的函数(定义宏来替换系统日志)?的主要内容,如果未能解决你的问题,请参考以下文章