人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

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

●質問者: gzmgzm
●カテゴリ:コンピュータ 科学・統計資料
✍キーワード:C++ C言語 メソッド 関数
○ 状態 :終了
└ 回答数 : 3/4件

▽最新の回答へ

1 ● dev_zer0
●20ポイント

http://www.linux.or.jp/JM/html/GNU_binutils/man1/nm.1.html

Manpage of nm

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

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

nm a.o | grep func

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

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


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

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

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

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


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

◎質問者からの返答

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

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


2 ● virus
●20ポイント

http://www.csg.is.titech.ac.jp/~chiba/lecture/os/gui2.html

Lecture Notes

処理系依存の部分もあるので基本的なことだけ(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ではありません。


3 ● aukjs
●20ポイント

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++のメソッドを呼ぶ。

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

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ