您的位置:首页 > 编程语言 > C语言/C++

C++程序与非C++程序的链接

2015-09-18 06:39 459 查看
C++
程序中可能包含由其他语言(例如C语言)写出的内容。不同的语言可能在使用寄存器保存参数的方式、参数放入堆栈的顺序及编译器传递给链接器的方面存在差异,造成程序之间的协作比较困难。例如
C++
为支持重载,程序编译后的名称与
C
语言不同,例如一个
foo
函数:

int foo(int x, int y);


C++
语言编译后生成的名字就是类似
_foo_int_int
的名称,而C语言编译后就是
_foo
。因此当在
C++
声明引用一个
C
程序库的
foo
函数时,在链接过程中,它就会从
C
程序库中去寻找
_foo_int_int
函数,而实际上在
C
库中只存在
_foo
函数,因此就会出现找不到指定的链接符号的错误。

为了解决这类问题,可以在一个
extern "c"
声明中给出链接约定,基本形式如下:

extern "c" int foo(int x, int y);


说明函数将以
C
链接约定的方式进行链接。 这样在C++程序中,它就会以
_foo
的名称去从C程序库中寻找链接的函数,就可以链接成功。

声明为
extern "c"
只是改变了链接方式,但不影响函数的语义,在
C++
中,声明为
extern "c"
的函数仍然遵循
C++
的类型检查和参数转换原则。

除了一条一条地声明
extern "c"
,还可以以下面链接块的方式提供一组声明描述链接的约定:

extern "c"
{
char* strcpy(char*, const char*);
int strlen(const char*);
extern int length;
}


链接块也可以包裹整个头文件:

extern "c"
{
#include <string.h>
}


C++
提供了
_cplusplus
宏,可以 保证在C文件下不包含
extern "c
“链接约定,而在
C++
程序中,包含
C
链接约定:

#ifdef _cplusplus
extern "c"{
#endif
char* strcpy(char*, const char*);
int strlen(const char*);
...
#ifdef _cplusplus
}
#endif


不使用
extern "c"
链接约定造成链接错误的示例:

/**************************************
* foolib.h                           *
*                                    *
* 一个简单C程序库的头文件            *
**************************************/

int foo(int, int);

/**************************************
* foolib.c                           *
*                                    *
* 一个简单C程序库的定义文件          *
**************************************/
#include <stdio.h>
#include "foolib.h"

int foo(int x, int y)
{
printf("x = %d, y = %d\n", x, y);

return x;
}


/****************************************
* foolib_caller.cpp                    *
*                                      *
* 调用C程序库的函数的C++程序           *
****************************************/

#include <iostream>

#include "foolib.h"

int main()
{
int x =10;
int y = 20;

int z = foo(x, y);
std::cout<<"foo(x,y)调用成功,结果为"<<z<<std::endl;
}


首先构建
foolib.c
文件构建
C
程序库
libfoolib.a
,然后链接到
C++
程序中,由于两种模式编译出的函数名称不同,链接失败,找不到函数定义。



现在在C++程序中添加链接定义,声明foolib.h中的函数都是以C语言的模式进行链接的,现在可以成功链接。

/****************************************
* foolib_caller.cpp                    *
*                                      *
* 调用C程序库的函数的C++程序           *
****************************************/

#include <iostream>

extern "C"
{
#include "foolib.h"
}

int main()
{
int x =10;
int y = 20;

int z = foo(x, y);
std::cout<<"foo(x,y)调用成功,结果为"<<z<<std::endl;
}




参考文献

Bjarne Stroustrup著,裘宗燕译. C++程序设计语言(特别版).机械工业出版社 2009.

http://developer.51cto.com/art/200510/9066.htm
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: