まず、Cから呼び出せる関数は、C++でいうところの「C結合」でなければなりません。具体的には、C++側で関数を宣言・定義する際に、extern "C" を付ける必要があるわけです。extern "C" を付けてC結合にするだけで、とりあえずC++側で定義した関数を呼び出すための最低限の条件を整えることができます。
ここで注意しなければならないのは、C結合にしたとしてもC++特有の型が駆り引数並びまたは返却値型に使われていてはならないということです。ただし、wchar_t型はC++にあってCにはない型ですが、Cでも<stddef.h>ヘッダ等でtypedef名として定義されていますので、それを使えばまず問題はないと思われます。
bool型は微妙で、C99では_Bool型がサポートされ、<stdbool.h>ヘッダではboolという名前が定義されますが、できれば使用は避けた方が無難です。また、列挙型もCとC++ではサイズが異なる可能性があるので、できれば避けた方が無難です。
もう一つ注意すべき点としては、C++の関数は例外を送出する可能性がありますが、Cから呼び出した際に例外が送出されてもどうすることもできませんので、C++側で関数を定義する際に、内部で全ての例外を捕捉して、エラーコードを返すなどの方法に置き換えてやる必要があります。
最後に、クラス型へのポインタを引数または返却値に使いたい場合、C側では何か別のポインタに置き換える必要があります。C++側でクラスを定義する際、クラスキーにclassではなくstructを使っていれば、そのままC側でも同じ型名で扱うことができます。具体的には次のようになります。
// C++側
struct A
{
...
};
extern "C"
int func(A* p)
{
...
}
/* C側 */
struct A; /* 不完全型の宣言 */
int func(struct A* p);
いずれにしても、C++からCの関数を呼び出す場合に比べて、CからC++の関数を呼び出すのは何かと面倒です。特に、メンバ関数を直接呼び出すことができないので、いったん非メンバ関数でラッピングする必要があるなど、いろいろと手間がかかります。


