Hi Nic, >How would this thunk layer work ? The C-ABI thunk layer acts as a bridge from the disparate C++-ABI's of 2.95 and 3.2. The effect: [1] <--> [2] <--> [3] <--> [4] 1) C++ 2.95 library 2) C thunk library 3) C++ 3.2 facade library 4) your application >The first thing our product architect asked me is what would happen if their were any static initializers in the library being thunked ? The static initializers should still get called when the library is loaded. Like normal. >How does one even get at a C++ object from C ? namespace Database { class Foo { int m; public: Foo() : m(0) { } void reset(int i) { m = i; } ... }; } - - - - - - - - - - - - - - - - // C-ABI thunk layer knows about the Database namespace, but does not expose the Database namespace. extern "C" void* NewFoo(); extern "C" void FooReset(void* p, int i); extern "C" int GetError(); - - - - - - - - - - - - - - - - static int gError = 0; // Foo factory. void* NewFoo() { try { Foo* foo = new Foo; } catch(...) { // You'd want something a little more robust than this. gError = 1; } } // Thunk for Foo's reset method. void FooReset(void* p, int i) { Foo* foo = (Foo*)p; foo->reset(i); } // Exception helper. int GetError() { return gError; } - - - - - - - - - - - - - - - - namespace Facade { struct ThunkError { }; class Foo { void* foo; public: Foo(); void reset(int i); }; Foo::Foo() : foo(NewFoo()) { if(GetError()) throw ThunkError; } void Foo::reset(int i) { FooReset(foo, i); if(GetError()) throw ThunkError; } } - - - - - - - - - - - - - - - - Each database class would need it's own Facade (or proxy) counterpart. Each method and constructor (that you utilize) would need a C-ABI thunk routine. It's not actually very hard to do; but it is a lot of rote work. The jagged edge is making sure you handle exceptions correctly (usefully). And remember: exceptions CANNOT pass through a C-ABI barrier! HTH, --Eljay