将C编译的静态库链接到C ++程序

时间:2013-09-28 06:15:53

标签: c++ c linux gcc g++

我尝试将静态库(使用gcc编译)链接到c ++程序,我得到了“未定义的引用”。我在ubuntu 12.04服务器机器上使用了gcc和g ++版本4.6.3。例如,以下是factorial方法的简单库文件:

mylib.h

#ifndef __MYLIB_H_
#define __MYLIB_H_

int factorial(int n);

#endif

mylib.c

#include "mylib.h"

int factorial(int n)
{
    return ((n>=1)?(n*factorial(n-1)):1);
}

我使用gcc:

为这个mylib.c创建了对象
gcc -o mylib.o -c mylib.c

同样,静态库是使用AR实用程序从目标文件创建的:

ar -cvq libfact.a mylib.o

我用C程序(test.c)和C ++程序(test.cpp)测试了这个库

C和C ++程序都有相同的主体:

#include "mylib.h"
int main()
{
    int fact = factorial(5);
    return 0;
}

假设/ home / test目录中有静态库libfact.a,我编译了我的C程序没有任何问题:

gcc test.c -L/home/test -lfact

然而,在测试C ++程序时,它引发了一个链接错误:

g++ test.cpp -L/home/test -lfact

test.cpp:(.text+0x2f): undefined reference to `factorial(int)'
collect2: ld returned 1 exit status

我甚至尝试在test.cpp中添加extern命令:

extern int factorial(int n) //added just before the main () function

仍然是同样的错误。

  • 有人可以告诉我这里错了吗?
  • 创建静态库时是否有任何遗漏?
  • 我是否必须在test.cpp中添加任何内容才能使其正常工作?

2 个答案:

答案 0 :(得分:22)

问题是你没有告诉你的C ++程序是用C语言编写的因子。你需要更改你的test.h头文件。喜欢这个

#ifndef __MYLIB_H_
#define __MYLIB_H_

#ifdef __cplusplus
extern "C" {
#endif

int factorial(int n);

#ifdef __cplusplus
}
#endif

#endif

现在您的头文件应该适用于C和C ++程序。有关详细信息,请参阅here

包含双下划线的BTW名称是为compliler保留的(因此名称以下划线和大写字母开头),因此严格来说#ifndef __MYLIB_H_是非法的。我会改为#ifndef MYLIB_H #define MYLIB_H

答案 1 :(得分:1)

虽然接受的答案绝对正确,但我想我只是添加一个观察。有些编辑器在打开/关闭大括号时遇到问题,并且会缩进标题中的整个extern "C"范围。如果mylib.h是库的键标题,您可以考虑:

#if defined (__cplusplus)
#define _MYLIB_INIT_DECL extern "C" {
#define _MYLIB_FINI_DECL }
#else
#define _MYLIB_INIT_DECL
#define _MYLIB_FINI_DECL
#endif

mylib库中的所有其他标题,例如mylib_aux.h,可以采用以下格式:

#ifndef _MYLIB_AUX_H
#define _MYLIB_AUX_H

#include <mylib.h>

_MYLIB_INIT_DECL

... header content ...

_MYLIB_FINI_DECL

#endif /* _MYLIB_AUX_H */

显然,我使用的名称是任意的,但对于多个库标题,这种方法对我有用。