C言語からC++のメソッドを呼び出す方法があるでしょうか。あるならばどのようにすればよいでしょうか。注、C++からCの関数を呼び出す方法ではありません。

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:2005/07/06 15:01:55
  • 終了:--

回答(4件)

id:dev_zer0 No.1

dev_zer0回答回数332ベストアンサー獲得回数252005/07/06 15:47:12

ポイント20pt

かなり処理系依存の処理になってしまいますが

LinuxではC++のメソッドがa.oに存在するfuncと仮定すると

nm a.o | grep func

とすると該当のCのシンボル名がわかります。

# 例えば、その名前は「__Z4funcPKc」とかいう名前かもしれません


そのシンボル名に適切な引数を与えれば呼び出せます

# オブジェクトを引数にとるメソッドだと非常に面倒です

a.oが変更されるとシンボル名も変更される可能性があります。

そのたびに、呼び出し先のシンボル名も変更しなければなりません。


不可能ではありませんが、あまりお勧め出来る方法ではありません。

id:gzmgzm

言い忘れていましたが、OSはRedHat、コンパイラはGCCです。

ありがとうございます。確かにやりたい方法ではありませんね..。ではどうしましょう。

2005/07/06 16:05:50
id:virus No.2

virus回答回数182ベストアンサー獲得回数12005/07/06 16:49:21

ポイント20pt

処理系依存の部分もあるので基本的なことだけ(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はクラスの実体まで踏み込んで説明してあるので参考にしてください(あまり適切なページが見つからなかったので(汗)。

id:gzmgzm

ありがとうございます。

今回はvirtualではありません。

2005/07/06 17:34:58
id:aukjs No.3

aukjs回答回数7ベストアンサー獲得回数02005/07/06 16:50:26

ポイント20pt

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();

}

id:gzmgzm

ありがとうございました。

>> C関数から

>>  -> C++の extern ”C” な関数を呼んで

>>  -> そのなかからC++のメソッドを呼ぶ。

これでいけるかもしれません。

2005/07/06 17:43:18

質問者が未読の回答一覧

 回答者回答受取ベストアンサー回答時間
1 くまっぷす 3784 3534 185 2005-07-06 17:31:56

コメントはまだありません

この質問への反応(ブックマークコメント)

トラックバック

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません