首页 > 编程语言 > 详细

c++ 的链接指示器 extern "C"

时间:2019-12-14 00:36:56      阅读:91      评论:0      收藏:0      [点我收藏+]


1. c++ 使用c的函数

c++ 标准库使用 c标准库,比如

cstdio   
/** @file include/cstdio
 *  This is a Standard C++ Library file.  You should @c #include this file
 *  in your programs, rather than any of the "*.h" implementation files.
 *
 *  This is the C++ version of the Standard C Library header @c stdio.h,
 *  and its contents are (mostly) the same as that header, but are all
 *  contained in the namespace @c std (except for names which are defined
 *  as macros in C).
 */


  extern "C" int
  (snprintf)(char * restrict, size_t, const char * restrict, ...);

 

再来一个简单例子

-- math.h

#ifndef __MATH_H__
#define __MATH_H__

#ifdef __cplusplus
extern "C" {
#endif

int func(int,int);

#ifdef __cplusplus
}
#endif

#endif

 

-- math.c

#include "math.h"
int func(int a,int b)
{
    return a+b;
}

 

-- 编译成静态库:
-- gcc -c math.c
-- ar -r librmath.a *.o


-- math.cpp

#include "math.h"
#include <iostream>
using namespace std;
int main()
{
    int a= 2,b = 3;
    int c = func(a,b);  // 直接调用c接口
    cout << c << endl;
}
  

 


-- 编译成可执行程序:
-- g++ math.cpp -L./ -lrmath

-- ./a.out


如果没有加上extern "C",则编译时报链接错误:
math.cpp:(.text+0x21): undefined reference to `func(int, int)‘
collect2: ld returned 1 exit status


2. 导出c++函数到c语言

-- math.h

class sample {
    public:
        int func(int a, int b);
};

 

-- math.cpp

#include "math.h"
int sample::func(int a, int b)
{
    return a + b;
}

 

-- g++ -fpic -shared -g -o librmath.so math.cpp -I ./


写c代码包装一下

-- mymath.h

#ifdef __cplusplus
extern "C" {
#endif

int myfunc(int, int);

#ifdef __cplusplus
}
#endif

 

-- mymath.c

#include "mymath.h"

#include "math.h"

int myfunc(int a, int b)
{
    sample s;
    return s.func(a, b);
}

 

-- g++ -fpic -shared -g -o libmymath.so mymath.cpp -lrmath -I ./ -L ./


测试一下:
-- main.c

#include <stdio.h>
#include "mymath.h"
int main()
{
    printf("%d\n", myfunc(1, 2));
    return 0;
}

 

-- gcc main.c -L./ -I ./ -lrmath -lmymath -Wl,-rpath=./

-- ./a.out

 

如果想要编译成静态库:

g++ -c math.cpp

ar -r librmath.a math.o

g++ -c mymath.cpp 

ar -r libmymath.a mymath.o

gcc main.c libmymath.a librmath.a -lstdc++

注意两点

1. -lstdc++

undefined reference to `__gxx_personality_v0‘

因为:

Note that programs using C++ object files must always be linked with g++, in order to supply the appropriate C++ libraries. Attempting to link a C++ object file with the C compiler gcc will cause "undefined reference" errors for C++ standard library functions

C++ source files conventionally use one of the suffixes .C, .cc, .cpp, .CPP, .c++, .cp, or .cxx; C++ header files often use .hh, .hpp, .H, or (for shared template code) .tcc; and preprocessed C++ files use the suffix .ii. GCC recognizes files with these names and compiles them as C++ programs even if you call the compiler the same way as for compiling C programs (usually with the name gcc).

大概意思是gcc根据后缀名去链接标准库,上面例子gcc没有检测到c++,所以默认不去链接c++基础库。

 

2. main.c libmymath.a librmath.a 这三个的顺序不能动,因为:

When the GNU linker sees a library, it discards all symbols that it doesn‘t need. In this case, your library appears before your .cpp file, so the library is being discarded before the .cpp file is compiled. 

所以推荐动态库的方式。

c++ 的链接指示器 extern "C"

原文:https://www.cnblogs.com/tenyearboyue/p/12037824.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!