Skip to content

Instantly share code, notes, and snippets.

@mikeando
Last active March 20, 2024 10:47
Show Gist options
  • Star 47 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save mikeando/5394166 to your computer and use it in GitHub Desktop.
Save mikeando/5394166 to your computer and use it in GitHub Desktop.
Example of using C++ from C.
#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;
}
#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);
}
}
#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
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
#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");
}
#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