C/C++混合编译 - C调用C++

C++调用C比较简单,直接在C++中extern c声明要调用的函数即可。

C调用C++的话,如果C++的代码是可以修改的,那么可以在C++代码里面新写一个wrapper function, 这个函数声明为extern c, 并且在这个函数的定义里面调用C++的函数。这样C++通过g++编译以后,这个wrapper function不会被name mangling.

但是如果被调用的C++是不能够被修改的,比如C调用C++的库函数,那么可以采用下面的方式:

https://www.teddy.ch/c++_library_in_c/

 

Tutorial: HowTo integrate a C++ library/class into a C programm

Emagine the situation: You have written a program in C and now you have the requirement to integrate an existing third parity C++ library into your program.

The C++ Library

The only thing you have is the class definition in the header file of the library:

MyClass.h
#ifndef __MYCLASS_H
#define __MYCLASS_H

class MyClass {
        private:
                int m_i;
        public:
                void int_set(int i);

                int int_get();
};

#endif

It is a simple class with only one member variable m_i and one setter and one getter method.

Perhaps you don't have the source code of the library, perhaps you only have a compiled version. To be able to reproduce the example here is the source of the class:

MyClass.cc
#include "MyClass.h"
void MyClass::int_set(int i) {
        m_i = i;
}

int MyClass::int_get() {
        return m_i;
}

To compile the class with GNU C++ comiler simply type:

g++ -c MyClass.cc -o MyClass.o

This gives you the object file that can be linked into your programm. In this place I won't explain how to create a complete library.

The C++ way

Just for comparison here a simple C++ program that uses our new class:

MyMain_c++.cc
#include "MyClass.h"
#include <iostream>

using namespace std;

int main(int argc, char* argv[]) {
        MyClass *c = new MyClass();
        c->int_set(3);
        cout << c->int_get() << endl;
        delete c;
}

This program can be compiled with:

g++ -c MyMain_c++.cc -o MyMain_c++.o

And linked with:

g++ MyMain_c++.o MyClass.o -o MyMain_c++

Start the C++ program with:

./MyMain_c++

The Problem

If we want to access a C++ library from C code we have two problems that we have to solve:

  • The name mangling of C is differnt to C++.
  • C doesn't know classes.

The C-Wrapper

To solve these problems we have to write a C-wrapper around our C++ class. Our wrapper header file will be readable by the C and the C++ compiler.

MyWrapper.h
#ifndef __MYWRAPPER_H
#define __MYWRAPPER_H

#ifdef __cplusplus
extern "C" {
#endif

typedef struct MyClass MyClass;

MyClass* newMyClass();

void MyClass_int_set(MyClass* v, int i);

int MyClass_int_get(MyClass* v);

void deleteMyClass(MyClass* v);

#ifdef __cplusplus
}
#endif
#endif

The extern "C" {} statement tells the C++ compiler to use the C style name mangling so a C compiler will find the correct symbols in the object file later. The #ifdef __cplusplus contition is because the C compiler does not know the keyword extern.

For the C compiler we define a dummy class handler with typedef struct MyClass MyClass.

And then the constructor, method and destructor wrappers.

The following file is the wrapper code, written in C++, but with one important thing: it is defined as extern "C"!

MyWrapper.cc
#include "MyClass.h"
#include "MyWrapper.h"

extern "C" {
        MyClass* newMyClass() {
                return new MyClass();
        }

        void MyClass_int_set(MyClass* v, int i) {
                v->int_set(i);
        }

        int MyClass_int_get(MyClass* v) {
                return v->int_get();
        }

        void deleteMyClass(MyClass* v) {
                delete v;
        }
}

To compile the wrapper with GNU C++ comiler simply type:

g++ -c MyWrapper.cc -o MyWrapper.o

The C Program

Now we are ready to use the C++ class in our C code:

MyMain_c.c
#include "MyWrapper.h"
#include <stdio.h>

int main(int argc, char* argv[]) {
        struct MyClass* c = newMyClass();
        MyClass_int_set(c, 3);
        printf("%i\n", MyClass_int_get(c));
        deleteMyClass(c);
}

This program can be compiled with the C compiler:

gcc -c MyMain_c.c -o MyMain_c.o

Note that the linking has to be done with the C++ comiler, a C linker like ldd does not work:

g++ MyMain_c.o MyWrapper.o MyClass.o -o MyMain_c

Start the C program with:

./MyMain_c

You should now get the same result as with your C++ program above.

I hope this mini tutorial helped you.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值