我可以使用共享用C在C程序中创建++库? [英] Can I use shared library created in C++ in a C program?

查看:148
本文介绍了我可以使用共享用C在C程序中创建++库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建使用C.程序。但是,我需要用很多有API,只有对C ++库。那么,是有可能,我可以在C创建一个共享对象++,然后访问它的功能使用C?


  1. 的唯一的数据我会被传递和返回是C兼容的数据类型。

  2. 转换或迁移到CPP是不是一种选择这里。

如果这是不可能从C ++ code到C code接口这些codeS,我该如何获取信息?
我试着从C调用C ++函数,但我在连接过程中得到错误,当我包括<串GT; 。所以,当我把C ++函数从C,我应该只使用code,这将是C编译器兼容?

C ++头cppfile.hpp

 的#ifndef CPPFILE_H
#定义CPPFILE_H
    #IFDEF __cplusplus
    为externC{
    #万一    EXTERN INT MyFunction的(为const char *文件名);   #IFDEF __cplusplus
   }
   #万一
#万一

C ++文件cppfile.cpp

 的#includecppfile.hpp
#包括LT&;串GT;
INT MyFunction的(为const char *文件名){
    字符串s(文件名);
    返回0;
}

C文件cmain.c

 的#includecppfile.hpp
INT主(INT ARGC,字符** argv的)
{
     INT I = myfunction的(的argv [1]);
     的printf(%d个\\ N,I);
     返回0;
}

编译:

  GCC -c cmain.c
G ++ -fPIC -shared -o cppfile.so cppfile.cpp


解决方案

您想要更多的东西像这样(在这里我将使用一个稍微更有意义的例子):

C / C ++头 - animal.h

 的#ifndef ANIMAL_H
#定义ANIMAL_H#IFDEF __cplusplus
类动物{
上市:
    动物():年龄(0),高度(0){}
    动物(中间体年龄,浮动高度):年龄(岁),身高(高度){}
    虚拟〜动物(){}    INT getAge();
    无效setAge(INT new_age)​​;    浮动的getHeight();
    无效自动调用setHeight(浮点new_height);私人的:
    INT年龄;
    浮动高度; //米!
};
#ENDIF / * __cplusplus * /#IFDEF __cplusplus
为externC{
#万一
    结构动物; //一个不错的不透明类型    结构动物* animal_create();
    结构动物* animal_create_init(INT年龄,身高浮动);
    无效animal_destroy(结构动物*一);    无效animal_setage(结构动物*一,INT new_age)​​;
    无效animal_setheight(结构动物*一,浮动new_height);
    INT animal_getage(结构动物*一);
    浮动animal_getheight(结构动物*一);
#IFDEF __cplusplus
}
#万一#ENDIF / * * ANIMAL_H /

C ++实现动物文件 - animal.cpp

 的#includeanimal.h
的#define TO_CPP(一)(reinter pret_cast&下;动物* GT;(a))的
的#define TO_C(一)(reinter pret_cast&下;动物* GT;(a))的无效动物:: setAge(INT new_age)​​{这个 - >年龄= new_age; }
INT动物:: getAge(){返回这个 - >年龄; }
无效动物::自动调用setHeight(浮点new_height){这个 - >高度= new_height; }
浮动物::的getHeight(){返回这个 - >高度; }动物* animal_create(){
    动物* A = TO_C(新动物);
    返回;
}动物* animal_create_init(INT年龄,身高浮动){
    动物* A = TO_C(新动物(年龄,身高));
    返回;
}无效animal_destroy(动物*一){
    删除TO_CPP(一);
}无效animal_setage(动物*一,诠释new_age)​​{
    TO_CPP(一) - > setAge(new_age)​​;
}无效animal_setheight(动物*一,浮动new_height){
    TO_CPP(一) - >自动调用setHeight(new_height);
}INT animal_getage(动物*一){
    TO_CPP(一) - > getAge();
}浮animal_getheight(动物*一){
    TO_CPP(一) - >的getHeight();
}

C客户code - 的main.c

 的#includeanimal.h
#包括LT&;&stdio.h中GT;诠释的main()
{
    // 6'025yo(也许是人类的:P)
    结构动物* A = animal_create(25岁,1.83);    animal_setage(一,26); //生日
    的printf(年龄:%d个\\ nHeight参数:%F,animal_getage(一),animal_getheight(一));    animal_destroy(一);
    返回0;
}

C ++客户端code - 的main.cpp

 的#includeanimal.h
#包括LT&;&iostream的GT;诠释的main()
{
    // 6'025yo(也许是人类的:P)
    动物* A =新的动物(25岁,1.83);
    A-> setAge(26); //生日
    性病::法院LT&;< 年龄:<< A-> getAge()&所述;&下;的std :: ENDL;
    性病::法院LT&;< 身高:<< A->的getHeight();    删除;
    返回0;
}

所以,当你编译库,编译 animal.cpp 用C ++编译器。然后,您可以链接到它与C code,并使用 animal_xxx 功能。

请注意使用结构动物动物动物是一个普通的C ++类型。这到底是什么样子。 结构动物,在另一方面,是一个不透明的类型。这意味着,你的C程序可以看到它的存在,并且可以有一个,但它不知道里面是什么吧。它只知道它有一个函数,它接受一个结构动物*

在一个真正的图书馆,你会希望有定制点进行内存分配。因此,假如这是库 libjungle ,你可能至少需要 jungle_setmalloc jungle_setfree 与合理的默认值。然后,您可以设置全局删除 libjungle 的C ++ code使用这些用户定义的函数。

I am creating programs using C. However, I require to use a lot of libraries that have API's only for C++. So, is it possible that I can create a shared object in C++ and then access its functionality using C?

  1. The only data I would be passing and returning would be C compatible data types.
  2. Converting or migrating to cpp is not an option here.

If it is not possible to interface these codes, how do I get information from C++ code to C code? I tried calling C++ functions from C, but I get errors during linking when I include <string>. So when I call C++ functions from C, should I only use that code which will be C compiler compatible?

C++ header cppfile.hpp

#ifndef CPPFILE_H
#define CPPFILE_H
    #ifdef __cplusplus
    extern "C" {
    #endif

    extern int myfunction(const char *filename);

   #ifdef __cplusplus
   }
   #endif
#endif

C++ file cppfile.cpp

#include "cppfile.hpp"
#include <string>
int myfunction(const char *filename) {
    String S(filename);
    return 0;
}

C file cmain.c

#include "cppfile.hpp"
int main(int argc, char **argv)
{
     int i = myfunction(argv[1]);
     printf("%d\n", i);
     return 0;
}

Compiling:

gcc -c cmain.c
g++ -fPIC -shared -o cppfile.so cppfile.cpp

解决方案

You want something more like this (and here I will use a slightly more meaningful example):

C/C++ header - animal.h

#ifndef ANIMAL_H
#define ANIMAL_H

#ifdef __cplusplus
class Animal {
public:
    Animal() : age(0), height(0) {}
    Animal(int age, float height) : age(age), height(height) {}
    virtual ~Animal() {}

    int   getAge();
    void  setAge(int new_age);

    float getHeight();
    void  setHeight(float new_height);

private:
    int age;
    float height; // in metres!
};
#endif /* __cplusplus */

#ifdef __cplusplus
extern "C" {
#endif
    struct animal; // a nice opaque type

    struct animal *animal_create();
    struct animal *animal_create_init(int age, float height);
    void           animal_destroy(struct animal *a);

    void           animal_setage(struct animal *a, int new_age);
    void           animal_setheight(struct animal *a, float new_height);
    int            animal_getage(struct animal *a);
    float          animal_getheight(struct animal *a);
#ifdef __cplusplus
}
#endif

#endif /* ANIMAL_H */

C++ animal implementation file - animal.cpp

#include "animal.h"
#define TO_CPP(a) (reinterpret_cast<Animal*>(a))
#define TO_C(a)   (reinterpret_cast<animal*>(a))

void  Animal::setAge(int new_age) { this->age = new_age; }
int   Animal::getAge() { return this->age; }
void  Animal::setHeight(float new_height) { this->height = new_height; }
float Animal::getHeight() { return this->height; }

animal *animal_create() {
    animal *a = TO_C(new Animal);
    return a;
}

animal *animal_create_init(int age, float height) {
    animal *a = TO_C(new Animal(age, height));
    return a;
}

void animal_destroy(animal *a) {
    delete TO_CPP(a);
}

void animal_setage(animal *a, int new_age) {
    TO_CPP(a)->setAge(new_age);
}

void animal_setheight(animal *a, float new_height) {
    TO_CPP(a)->setHeight(new_height);
}

int animal_getage(animal *a) {
    TO_CPP(a)->getAge();
}

float animal_getheight(animal *a) {
    TO_CPP(a)->getHeight();
}

C client code - main.c

#include "animal.h"
#include <stdio.h>

int main()
{
    // 6'0" 25yo (perhaps a human? :P)
    struct animal *a = animal_create(25, 1.83); 

    animal_setage(a, 26); // birthday
    printf("Age: %d\nHeight: %f", animal_getage(a), animal_getheight(a));

    animal_destroy(a);
    return 0;
}

C++ client code - main.cpp

#include "animal.h"
#include <iostream>

int main()
{
    // 6'0" 25yo (perhaps a human? :P)
    Animal* a = new Animal(25, 1.83);
    a->setAge(26); // birthday
    std::cout << "Age:    " << a->getAge() << std::endl;
    std::cout << "Height: " << a->getHeight();

    delete a;
    return 0;
}

So when you compile the library, you compile animal.cpp with a C++ compiler. You can then link to it with C code, and use the animal_xxx functions.

Note the use of struct animal and Animal. Animal is a normal C++ type. It's exactly what it looks like. struct animal, on the other hand, is an "opaque" type. That means that your C program can see it's there, and can have one, but it doesn't know what is inside it. All it knows is that it has a function that takes a struct animal*.

In a real library you will want to have customisation points for memory allocation. So assuming this is the library libjungle, you probably want at least jungle_setmalloc and jungle_setfree with sensible defaults. You can then set up the global new and delete in libjungle's C++ code to use these user-defined functions.

这篇关于我可以使用共享用C在C程序中创建++库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆