A more complete example based on the code from my stack overflow answer: http://stackoverflow.com/questions/2045774/developing-c-wrapper-api-for-object-oriented-c-code/2045860
Last active
September 16, 2024 20:57
-
-
Save mikeando/5394166 to your computer and use it in GitHub Desktop.
Example of using C++ from C.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "HMyClass.h" | |
#include <stdio.h> | |
void my_eh( const char * error_message, void * unused) | |
{ | |
printf("my_eh: %s\n", error_message); | |
} | |
int main() | |
{ | |
MyClassEH eh = { &my_eh, NULL }; | |
HMyClass * h = myClass_create("hello", &eh); | |
int j = myClass_doSomething(h, 3, &eh); | |
printf("myClass_doSomething returned %d\n", j); | |
myClass_iCouldThrow(h, -1, &eh); | |
myClass_destroy(h, &eh); | |
printf("DONE...\n"); | |
return 1; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "MyClass.h" | |
extern "C" { | |
#include "HMyClass.h" | |
} | |
HMyClass * myClass_create( const char * s, MyClassEH * eh ) { | |
try { | |
return reinterpret_cast<HMyClass*>(new MyClass(s)); | |
} catch ( MyClassException e ) { | |
if(!eh) throw; | |
eh->eh(e.mesg_.c_str(), eh->user_data); | |
return NULL; | |
} | |
} | |
void myClass_destroy( HMyClass * h, MyClassEH * eh ) { | |
try { | |
delete reinterpret_cast<MyClass*>(h); | |
} catch ( MyClassException e ) { | |
if(!eh) throw; | |
eh->eh(e.mesg_.c_str(), eh->user_data); | |
} | |
} | |
int myClass_doSomething( HMyClass * h, int j, MyClassEH * eh ) { | |
try { | |
return reinterpret_cast<MyClass*>(h)->doSomething(j); | |
} catch ( MyClassException e ) { | |
if(!eh) throw; | |
eh->eh(e.mesg_.c_str(), eh->user_data); | |
return 0; | |
} | |
} | |
void myClass_iCouldThrow( HMyClass * h, int j, MyClassEH * eh ) { | |
try { | |
reinterpret_cast<MyClass*>(h)->iCouldThrow(j); | |
} catch ( MyClassException e ) { | |
if(!eh) throw; | |
eh->eh(e.mesg_.c_str(), eh->user_data); | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef MA_HMYCLASS | |
#define MA_HMYCLASS | |
struct HMyClass; // An opaque type that we'll use as a handle | |
typedef struct HMyClass HMyClass; | |
typedef void(*MyClassErrorHandlerFn)(const char * error_message, void * user_data); | |
typedef struct MyClassEH { | |
MyClassErrorHandlerFn eh; | |
void * user_data; | |
} MyClassEH; | |
HMyClass * myClass_create( const char * s, MyClassEH * eh ); | |
void myClass_destroy( HMyClass * v, MyClassEH * eh ); | |
int myClass_doSomething( HMyClass * v, int i, MyClassEH * eh ); | |
void myClass_iCouldThrow( HMyClass * v, int i, MyClassEH * eh ); | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Demo.x : MyClass.o Demo.o HMyClass.o | |
g++ Demo.o MyClass.o HMyClass.o -o Demo.x | |
MyClass.o : MyClass.h MyClass.cpp | |
g++ -Wall -c MyClass.cpp -o MyClass.o | |
Demo.o : HMyClass.h Demo.c | |
gcc -Wall -c Demo.c -o Demo.o | |
HMyClass.o : HMyClass.h HMyClass.cpp MyClass.h | |
g++ -Wall -c HMyClass.cpp -o HMyClass.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "MyClass.h" | |
#include <iostream> | |
MyClass::MyClass( const std::string & s ) { | |
std::cout<<__func__<<" : Creating MyClass["<<this<<"]"<<std::endl; | |
} | |
MyClass::~MyClass() { | |
std::cout<<__func__<<" : Destroying MyClass["<<this<<"]"<<std::endl; | |
} | |
int MyClass::doSomething( int j ) { | |
std::cout<<__func__<<" : doing something with "<<j<<std::endl; | |
return j+1; | |
} | |
void MyClass::iCouldThrow( int idx ) { | |
std::cout<<__func__<<" : called with "<<idx<<std::endl; | |
if( idx < 0 ) throw MyClassException("I hate negative numbers"); | |
if( idx == 13 ) throw MyClassException("Unlucky 13"); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef MA_MYCLASS | |
#define MA_MYCLASS | |
#include <string> | |
class MyClassException { | |
public: | |
explicit MyClassException( const std::string & mesg ) : mesg_(mesg) {} | |
std::string mesg_; | |
}; | |
class MyClass | |
{ | |
public: | |
explicit MyClass( const std::string & s ); | |
~MyClass(); | |
int doSomething( int j ); | |
void iCouldThrow( int idx ); | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment