かなり処理系依存の処理になってしまいますが
LinuxではC++のメソッドがa.oに存在するfuncと仮定すると
nm a.o | grep func
とすると該当のCのシンボル名がわかります。
# 例えば、その名前は「__Z4funcPKc」とかいう名前かもしれません
そのシンボル名に適切な引数を与えれば呼び出せます
# オブジェクトを引数にとるメソッドだと非常に面倒です
a.oが変更されるとシンボル名も変更される可能性があります。
そのたびに、呼び出し先のシンボル名も変更しなければなりません。
不可能ではありませんが、あまりお勧め出来る方法ではありません。
処理系依存の部分もあるので基本的なことだけ(GCCは使ってないので)。
たとえば
class a_class {
int foo(int bar,char *s);
と言うメソッドを呼び出す場合、a_class のポインターを得て
a_class *pClass = ...;
foo(pClass, bar, s);
のようにC側では第一引数としてクラスポインターを渡し、第二以降に本来の引数を渡します。
fooと言うメソッド名は、1番の方が書いているように何らかの名称に変わっているのが普通です。基本的には、foo にクラス名と返す型を示す文字が頭に付加され、引数を示す文字が後に付きます(コンパイラ、環境に依存)。
ただし、これは「静的」なメソッドの場合です。virtual なメソッドはクラスポインターが指し示す先に構造体(これがクラスインスタンスの実体)があり、その何番目かのエントリーにメソッドへのポインターがセットされていますので
(*pClass->a_class_vtbl[?])(pClass, bar, s);
のような呼び出し方になります。
?の部分はクラス定義とコンパイラで一意に決まります。
ご自分でCの部分もC++の部分も書かれるのであれば、IDL できちんとinterface定義すれば処理系依存の部分を最小限にすることが出来ます。
なお、URLはクラスの実体まで踏み込んで説明してあるので参考にしてください(あまり適切なページが見つからなかったので(汗)。
ありがとうございます。
今回はvirtualではありません。
http://www.hatena.ne.jp/1120629715
人力検索はてな - C言語からC++のメソッドを呼び出す方法があるでしょうか。あるならばどのようにすればよいでしょうか。注、C++からCの関数を呼び出す方法ではありません。..
CとC++では呼出し規約が違います。
(処理系によっては一部同じかもしれませんが、違っても文句が言えない)
1.引数を左からスタックに積むか右から積むか。
2.スタックの復帰を誰がやるのか
呼び出し側がやるか呼ばれた側がやるか
3.シンボルのコーディングの違い
すでにdev_zer0さんが回答しています。
C++の関数名のコーディングには、引数の型情報やクラス名などが
含まれていますが、C言語にはそういった概念がありません。
(あったら、それはC言語ではありません)
4.メンバ関数なら、thisポインタをどう渡すか。
そもそもCにはthisポインタなどという概念もない。
で、問題の件を実現するためには
これらの違いを吸収しなければなりません。
これらをC言語側から解決する手段はちょっと考え付きません。
そこで、C++の機能としてextern ”C”
(C言語と互換性がある呼出し規約の関数との宣言)がありますから
これをつかって
C関数から
-> C++の extern ”C” な関数を呼んで
-> そのなかからC++のメソッドを呼ぶ。
という作戦しかないでしょう。
extern ”C”な関数を呼び出す対象ごとに用意する必要がありますが。
-- cpp_source.C ------------------------
#include <iostream>
extern ”C” void cpp_thunk();
/* C++ Function */
void cpp_func()
{
std::cout << ”cpp_func()” << std::endl;
}
void cpp_thunk()
{
cpp_func();
}
-- c_source.c --------------------------
extern void cpp_thunk();
void main()
{
cpp_thunk();
}
ありがとうございました。
>> C関数から
>> -> C++の extern ”C” な関数を呼んで
>> -> そのなかからC++のメソッドを呼ぶ。
これでいけるかもしれません。
回答者 | 回答 | 受取 | ベストアンサー | 回答時間 | |
---|---|---|---|---|---|
1 | ![]() |
3784回 | 3534回 | 185回 | 2005-07-06 17:31:56 |
言い忘れていましたが、OSはRedHat、コンパイラはGCCです。
ありがとうございます。確かにやりたい方法ではありませんね..。ではどうしましょう。