C++ -> C -> C++ とさせる場合にメンバ関数を無理矢理くわせる

//common.h
struct kantara{
	void *obj;
	int (*get)(void);
	void (*set)(int);
};
extern "C"{
	void execute(const struct kantara *k);
}
//1st.hh
class nantara{
public:
	int Get(void);
	void Set(int);
};

ここまではよくて、クラスからのオブジェクトの関数ポインタをそのままくっつけたらクラスがあわないとか、オブジェクトの関数ポインタのアドレスをはっつけてはいけないと怒られた。

//1st.cc さいしょ
#include "common.h"
#include "1st.hh"
int main(int c, char **v)
{
	struct kantara k;
	nantara *n = new nantara();
	k.obj = n;
	k.get = &n->Get;
	k.set = &n->Set;
}

のでこうした。 void ポインタのやりたい放題は助かるが、仕様的には穴だよね。

#include "common.h"
#include "1st.hh"
//1st.cc やりなおし
static int get(void *obj)
{
	nantara *n = static_cast<nantara *n>(obj);
	return n->Get();
}
static void set(void *obj, int v)
{
	nantara *n = static_cast<nantara *n>(obj);
	n->Set(v);
}
int main(int c, char **v)
{
	struct kantara k;
	nantara *n = new nantara();
	k.get = get;
	k.set = set;
	execute(k);
}

こーかいたら関数ポインタは通った。extern "C" を忘れてリンクに失敗したけど。ここまでが C++ -> C で、次は C -> C++ となる。

//2nd.c
#include "common.h"
void execute(const struct kantara *k)
{
	int val = k->get(k->obj);
	k->set(k->obj, val);
}

こんな感じに無理矢理 wxWidget を通した。wxWidget 自体はとても優秀でコーディング量も少ない上に、OS に依存しないアプリが作れるのでおすすめ。