C ++标准表明main
可以two possible signatures。
int main() // (1)
int main(int, char*[]) // (2)
此外,main()
通常是从__libc_start_main
调用的,csu/libc-start.c
在glibc源代码的main
中定义。此函数内的result = main (argc, argv, __environ MAIN_AUXVEC_PARAM);
调用将复制到下面。
main()
我们观察到这里的调用使用了三个参数,这似乎不会产生任何链接器错误,尽管签名与上述两种形式都不匹配。
我正在编写一个定义int AppMain() // (1)
int AppMain(int, char*[]) // (2)
的线程库,并希望应用程序能够定义以下两个函数之一。
AppMain
不幸的是,如果我使用上面的第二个表单声明main
并从我的库glibc
调用它,并且应用程序使用第一个表单,那么我得到一个未解析的引用链接器表示我调用的函数不存在的错误。
因为main
对CCFLAGS=-Wall -Werror
all: libLib.a App
libLib.a: Lib.o
ar rcs $@ $^
App: App.o libLib.a
g++ -o $@ $< -L. -lLib
%.o: %.cc
g++ $(CCFLAGS) -O3 $(LIBS) -fPIC -c -o $@ $<
来说似乎不是问题,如何以避免链接器错误的方式编写我的调用或声明?
这是一种重现问题的简便方法。
#include <stdio.h>
int AppMain(int argc, char** argv);
#undef main
int main(int argc, char** argv){
printf("Hello World\n");
AppMain(argc, argv);
}
#include <stdio.h>
int AppMain(int argc, char** argv){
printf("Application says Hello world\n");
return 0;
}
#include <stdio.h>
int AppMain(){
printf("Application says Hello world\n");
return 0;
}
./libLib.a(Lib.o): In function `main':
Lib.cc:(.text.startup+0x24): undefined reference to `AppMain(int, char**)'
collect2: error: ld returned 1 exit status
Makefile:9: recipe for target 'App' failed
make: *** [App] Error 1
在第二个版本下,这是链接器错误。
SELECT a.id, a.user_id, a.tc1, a.tc4, a.tc2, b.avatar, c.username,
(select rank from (SELECT
IF (@score=s.tc5, @rank:=@rank, @rank:=@rank+1) rank,
@score:=s.tc5 tc5s
FROM treningove_casy s,
(SELECT @score:=0, @rank:=0) r
ORDER BY tc5 DESC) s ) as rank
FROM
treningove_casy a INNER JOIN
sn_users b ON a.user_id=b.id INNER JOIN
users c ON a.user_id=c.id , (SELECT @curRank := 0) r
WHERE a.tc2 LIKE 'Motokáry Modrice'
GROUP BY a.user_id
答案 0 :(得分:0)
不管有什么不同建议,我都会回答你的问题
如何避免链接程序错误来编写调用或声明?
您可以在App.cc
中将定义写为
extern "C" int AppMain()
{
…
,您在Lib.cc
中的声明为
extern "C" int AppMain(int argc, char** argv);
避免使用name mangling,这与最可能在glibc
中执行的操作相同。可能有些C ++编译器无法执行此操作,但肯定可以与GCC一起使用。