我可以使用共享用C在C程序中创建++库? [英] Can I use shared library created in C++ in a C program?
问题描述
我创建使用C.程序。但是,我需要用很多有API,只有对C ++库。那么,是有可能,我可以在C创建一个共享对象++,然后访问它的功能使用C?
- 的唯一的数据我会被传递和返回是C兼容的数据类型。
- 转换或迁移到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?
- The only data I would be passing and returning would be C compatible data types.
- 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屋!