How to Call C++ Function from C

How to call C++ function from C?

You need to create a C API for exposing the functionality of your C++ code. Basically, you will need to write C++ code that is declared extern "C" and that has a pure C API (not using classes, for example) that wraps the C++ library. Then you use the pure C wrapper library that you've created.

Your C API can optionally follow an object-oriented style, even though C is not object-oriented. Ex:

 // *.h file
// ...
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif

typedef void* mylibrary_mytype_t;

EXTERNC mylibrary_mytype_t mylibrary_mytype_init();
EXTERNC void mylibrary_mytype_destroy(mylibrary_mytype_t mytype);
EXTERNC void mylibrary_mytype_doit(mylibrary_mytype_t self, int param);

#undef EXTERNC
// ...


// *.cpp file
mylibrary_mytype_t mylibrary_mytype_init() {
return new MyType;
}

void mylibrary_mytype_destroy(mylibrary_mytype_t untyped_ptr) {
MyType* typed_ptr = static_cast<MyType*>(untyped_ptr);
delete typed_ptr;
}

void mylibrary_mytype_doit(mylibrary_mytype_t untyped_self, int param) {
MyType* typed_self = static_cast<MyType*>(untyped_self);
typed_self->doIt(param);
}

Call a C function from C++ code

Compile the C code like this:

gcc -c -o somecode.o somecode.c

Then the C++ code like this:

g++ -c -o othercode.o othercode.cpp

Then link them together, with the C++ linker:

g++ -o yourprogram somecode.o othercode.o

You also have to tell the C++ compiler a C header is coming when you include the declaration for the C function. So othercode.cpp begins with:

extern "C" {
#include "somecode.h"
}

somecode.h should contain something like:

 #ifndef SOMECODE_H_
#define SOMECODE_H_

void foo();

#endif



(I used gcc in this example, but the principle is the same for any compiler. Build separately as C and C++, respectively, then link it together.)

How can I call a C++ function from C?

Unfortunately, my first attempt answered the wrong question....

For the question you did ask...

You can, as someone point out, pass around void *'s. And that's what I would also recommend. As far as C is concerned, pointers to C++ objects should be totally opaque.

C++ functions can be labeled extern "C" as well if they are in the global namespace. Here is an example:

myfunc.hpp:

#ifdef __cplusplus
extern "C" {
#endif

extern int myfunction(int, void *ob);

#ifdef __cplusplus
}
#endif

myfunc.cpp:

#include "myfunc.hpp"

void myfunction(int x, void *vobptr)
{
ClassType *ob = static_cast<ClassType *>(vobptr);
}

afoofile.c

#include "myfunc.hpp"

void frobble(int x, void *opaque_classtype_ptr) {
myfunction(x, opaque_classtype_ptr);
/* do stuff with buf */
}

The other option is to do basically the same thing with creative use of typedefs in C. This, IMHO, is quite ugly, but here is an example anyway:

myfunc.hpp:

#ifdef __cplusplus
extern "C" {
#else
typedef void ClassType; /* This is incredibly ugly. */
#endif

extern int myfunction(int, ClassType *ob);

#ifdef __cplusplus
}
#endif

myfunc.cpp:

#include "myfunc.hpp"

void myfunction(int x, ClassType *ob)
{
// Do stuff with ob
}

afoofile.c

#include "myfunc.hpp"

void frobble(int x, ClassType *opaque_classtype_ptr) {
myfunction(x, opaque_classtype_ptr);
/* do stuff with buf */
}

How to invoke function from external .c file in C?

Use double quotes #include "ClasseAusiliaria.c" [Don't use angle brackets (< >) ]

And I prefer to save the file with .h extension In the same directory/folder.

TLDR:
Replace #include <ClasseAusiliaria.c> with
#include "ClasseAusiliaria.c"

How to call a C++ method from C?

The common approach to this problem is providing a C wrapper API. Write a C function that takes a pointer to a MyClass object (as MyClass is not valid C, you will need to provide some moniker, simplest one is moving void* around) and the rest of the arguments. Then inside C++ perform the function call:

extern "C" void* MyClass_create() {
return new MyClass;
}
extern "C" void MyClass_release(void* myclass) {
delete static_cast<MyClass*>(myclass);
}
extern "C" void MyClass_sendCommandToSerialDevice(void* myclass, int cmd, int params, int id) {
static_cast<MyClass*>(myclass)->sendCommandToSerialDevice(cmd,params,id);
}

Then the C code uses the C api to create the object, call the function and release the object:

// C
void* myclass = MyClass_create();
MyClass_sendCommandToSerialDevice(myclass,1,2,3);
MyClass_release(myclass);

calling C++ method from C code

You need similar wrapper methods to create and destroy the C++ object.

C++ code:

extern "C" C * create_c()
{
return new C;
}

extern "C" void destroy_c(C *p)
{
delete p;
}

C code:

// forward declarations (better to put those in a header file)
struct C;
struct C * create_c();
double call_C_f(struct C* p, int i);
void destroy_c(struct C *p);

struct C * p = create_c();
double result = call_C_f(p, i);
destroy_c(p);
p = NULL;

How to call a C function from Assembly?

You should add something like

extern  _printer

on the top of your assembly and use call with this name

call _printer

Correct name of function depends on naming convention of your C compiler. Compiler may add some characters to the C name of the function.

Correct "extern" keyword depends on your assembler and it could be ".extern" or so.

Edit 1:
In Turbo Assembler and for that case with function without parameter, it should be just

extrn printer

or

extrn printer:NEAR

I am not familiar with TASM.

How to call C function from R?

I've searched stackoverflow first but I noticed there is no answer for that in here.

The general idea is (commands for linux, but same idea under other OS):

  1. Create function that will only take pointers to basic types and do everything by side-effects (returns void). eg:

    void addOneToVector(int* n, double* vector) {
    for (int i = 0; i < *n; ++i)
    vector[i] += 1.0;
    }
  2. Compile file C source as dynamic library, you can use R shortcut to do this:

    $ R CMD SHLIB lib.c
  3. Load dynamic library from R:

    dyn.load("foo.so")
  4. Call C functions using .C R function, IE:

    x = 1:3
    ret_val = .C("addOneToVector", n=length(x), vector=as.double(x))

It returns list from which you can get value of inputs after calling functions eg.

ret_val$x # 2, 3, 4

You can now wrap it to be able to use it from R easier.

There is a nice page describing whole process with more details here (also covering Fortran):

http://users.stat.umn.edu/~geyer/rc/



Related Topics



Leave a reply



Submit