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 typedef
s 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):
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;
}Compile file C source as dynamic library, you can use R shortcut to do this:
$ R CMD SHLIB lib.c
Load dynamic library from R:
dyn.load("foo.so")
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
C++11 Does Not Deduce Type When Std::Function or Lambda Functions Are Involved
How to Achieve the Theoretical Maximum of 4 Flops Per Cycle
How to Erase an Element from Std::Vector≪≫ by Index
What's the Difference Between Assignment Operator and Copy Constructor
Difference Between 'New Operator' and 'Operator New'
What Are the Errors, Misconceptions or Bad Pieces of Advice Given by Cplusplus.Com
Template Specialization VS Function Overloading
How to Call C++ Function from C
How to Access Private Members from Outside the Class Without Using Friends
C99 Stdint.H Header and Ms Visual Studio
Why Does C++ Disallow Anonymous Structs
Rules For C++ String Literals Escape Character
Testing Pointers For Validity (C/C++)
Why Does Omission of "#Include ≪String≫" Only Sometimes Cause Compilation Failures
Initializer_List and Move Semantics
How to Detect Reliably MAC Os X, Ios, Linux, Windows in C Preprocessor