user494461
user494461

Reputation:

How to use c++ objects in c?

I have 2 projects decoder and dec in my visual studio. One has C code and other has C++ code using stl respectively.How do I instantiate the c++ classes in my c code inside decode project?

for e.g.
//instantiating object
reprVectorsTree *r1 = new reprVectorsTree(reprVectors1,8);
//using one of its function
r1->decode(code);

What do I need to do for this?

How do I access files from another project?

How do I make use of existing c++ code in C files?

--------edit---------- I have a class like this

class Node//possible point in our input space
{
public:
    std::vector<float> valuesInDim;//values in dimensions
    std::vector<bool> code;
    Node(std::vector<float>value);
    Node::Node(float x, float y);
Node::Node(std::vector<float> value,std::vector<bool> binary);


};

How do I use the above class in c++? If C only allows structs how do I map it to a struct?

Upvotes: 10

Views: 24122

Answers (4)

Gowtham
Gowtham

Reputation: 51

In simple terms, you just do these:

  1. Write an interface function to convert all the class functions (constructor, destructor, member functions) as pure functions, and encapsulate them as extern "C"{ }
  2. Convert the pointer to the class as pointer to void, and carefully use type-cast wherever you define the "pure functions"
  3. Call the pure functions in the C-code.

For example here is my simple Rectangle class:

/*** Rectangle.h ***/
class Rectangle{
private:
    double length;
    double breadth;
public:
    Rectangle(double iLength, double iBreadth);
    ~Rectangle();
    double getLength();
    double getBreadth();
};

/*** Rectangle.cpp ***/
#include "Rectangle.h"
#include <iostream>
extern "C" {
    Rectangle::Rectangle(double l, double b) {
        this->length = l;
        this->breadth = b;
    }

    Rectangle::~Rectangle() {
        std::cout << "Deleting object of this class Rectangle" << std::endl;
    }

    double Rectangle::getLength() {
        return this->length;
    }

    double Rectangle::getBreadth() {
        return this->breadth;
    }
}

Now here is my interface to convert the class functions to pure functions. Notice how the pointer to the class is handled!

/*** RectangleInterface.h ***/
#ifdef __cplusplus
extern "C" {
#endif
    typedef void * RHandle;
    RHandle create_Rectangle(double l, double b);
    void    free_Rectangle(RHandle);
    double  getLength(RHandle);
    double  getBreadth(RHandle);

#ifdef __cplusplus
}
#endif

/*** RectangleInterface.cpp ***/ 
#include "RectangleInterface.h"
#include "Rectangle.h"
extern "C"
{
    RHandle create_Rectangle(double l, double b){
        return (Rectangle*) new Rectangle(l, b);
    };
    void free_Rectangle(RHandle p){
        delete (Rectangle*) p;
    }
    double getLength(RHandle p){
        return  ((Rectangle*) p)->getLength();
    }
    double getBreadth(RHandle p){
        return ((Rectangle*)p)->getBreadth();
    }
}

Now I can use these interface functions in my ".c" file as shown below. I just have to include the RectangleInterface.h function here, and the rest is taken care by its functions.

/*** Main function call ***/
#include <stdio.h>
#include "RectangleInterface.h"

int main()
{
    printf("Hello World!!\n");
    RHandle myRec = create_Rectangle(4, 3);
    printf("The length of the rectangle is %f\n", getLength(myRec));
    printf("The area of the rectangle is %f\n", (getLength(myRec)*getBreadth(myRec)));
    free_Rectangle(myRec);
    return 0;
}

Upvotes: 5

Kerrek SB
Kerrek SB

Reputation: 477040

Give the C++ module a C interface:

magic.hpp:

struct Magic
{
    Magic(char const *, int);
    double work(int, int);
};

magic.cpp: (Implement Magic.)

magic_interface.h:

struct Magic;

#ifdef __cplusplus
extern "C" {
#endif

typedef Magic * MHandle;
MHandle create_magic(char const *, int);
void    free_magic(MHandle);
double  work_magic(MHandle, int, int);

#ifdef __cplusplus
}
#endif

magic_interface.cpp:

#include "magic_interface.h"
#include "magic.hpp"

extern "C"
{
    MHandle create_magic(char const * s, int n) { return new Magic(s, n); }
    void    free_magic(MHandle p) { delete p; }
    double  work_magic(MHandle p, int a, int b) { return p->work(a, b); }
}

Now a C program can #include "magic_interface.h" and use the code:

MHandle h = create_magic("Hello", 5);
double d = work_magic(h, 17, 29);
free_magic(h);

(You might even want to define MHandle as void * and add casts everywhere so as to avoid declaring struct Magic in the C header at all.)

Upvotes: 33

perilbrain
perilbrain

Reputation: 8197

Make wrapper for instantiating C++ objects using C++ exported functions.And then call these functions from C code to generate objects.

Since one is function oriented and other is object oriented, you can use a few ideas in your wrapper:-

  1. In order to copy class member, pass an equivalent prespecified struct from C code to corresponding C++ function in order to fetch the data.
  2. Try using function pointers, as it will cut the cost, but be careful they can be exploited as well.

A few other ways.

Upvotes: 1

Gir
Gir

Reputation: 849

you would need to write a wrapper in C.

something like this:

in class.h:

struct A{
   void f();
}

in class.cpp:

void A::f(){
}

the wrapper.cpp:

#include "wrapper.h"
void fWrapper(struct A *a){a->f();};
struct A *createA(){
   A *tmp=new A();
   return tmp;
}

void deleteA(struct A *a){
 delete a;
}

the wrapper.h for C:

struct A;
void fWrapper(struct A *a);
A *createA();

the C program:

#include "wrapper.h"
int main(){
    A *a;
    a=createA();
    fWrapper(a);
    deleteA(a);
}

Upvotes: 0

Related Questions