• ベストアンサー

C++の関数をCで呼ぶには??

C++の関数をCで呼ぶには、「extern C」を使用することが有名だと思いますが、これだとC++で記述したソースコードにextern Cを追加することにあると思います。 では、C++のほうはまったく手をつけず、C++の関数をCで呼ぶことは可能なのでしょうか? 知っている方がいましたらよろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

一般的には不可能です。既存のC++コードを修正することなく、Cから呼び出すには、 extern "C++" void f(); extern "C" int call_f() throw() {  try  {   f();  }  catch (...)  {   return -1;  }  return 0; } のようなラッパー関数を作り、それを呼び出す必要があります。 なお、C++の関数のマングル名を調べて強引に呼び出すことも、場合によっては可能ですが、処理系によってはC++結合とC結合のコーリングコンベンションが異なる場合があるので要注意です。また、仮に問題なく呼び出せたとしても、C++の関数から送出された例外を処理することができませんので、破綻するのは目に見えています。

lovelace
質問者

お礼

jactaさん、回答ありがとうございます。 やはり、C++の方にextern Cを記述したほうがよいのですね。

lovelace
質問者

補足

 現在,C++言語で記述された下位ライブラリから、C言語で関数を呼び出さなければならない状態にあります。  しかし、下位のライブラリがMinGWで実装されたものであり、.soファイルや.oファイルなどのライブラリファイルとC++ソースコードからなるという複雑な構造をしています。  しかも、上位のC言語プログラムはVisual Studioで動作させなければなりません。  どのようにすればこのような要求を満足できるソードを作成できるかを教えていただければ幸いです。

その他の回答 (2)

  • luckymako
  • ベストアンサー率55% (29/52)
回答No.3

cのソースをc++としてコンパイルするのはだめなのですか? GNUなら以下のコードで gcc source.c では通りませんが、 g++ source.c なら通ります。 分割してあったとしても同様です。 #include<stdio.h> int sub(int a){  return a; } int sub(int a, int b){  return a + b; } int main(){  printf("%d\n", sub(1));  printf("%d\n", sub(1, 2)); }

lovelace
質問者

お礼

luckymakoさん、回答ありがとうございます。 自己解決いたしました。 ありがとうございました。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

> しかし、下位のライブラリがMinGWで実装されたものであり、.soファイルや.oファイルなどのライブラリファイルとC++ソースコードからなるという複雑な構造をしています。 > しかも、上位のC言語プログラムはVisual Studioで動作させなければなりません。 MinGWで実装されたものだけを集めてDLLを作ってください。 そして、エクスポートする関数は、すべてCのインタフェースを持たせてください。Visual Studioとのことですが、VB等からの呼出しのことも考えると、__stdcallにしておいた方が融通が利く可能性があります。その場合、引数や返却値の型にも十分注意を払ってください。 また、前回も書きましたが、C結合にするだけでは不十分で、例外処理をDLLの外に漏らさないように、内部ですべてcatchし、エラーコードに置き換える必要があります。 もう一点、long double型のサイズがMinGWとVisual C++では異なります。また、double _Complex型や_Bool型など、C99の型はVisual C++では使えませんので要注意です。

lovelace
質問者

お礼

jactaさん、回答ありがとうございます。 やってみたいと思います。

関連するQ&A

  • クラスを使ったC++の関数をCで呼び出すには?

     QNo.152285と類似の質問になりますが、独自に用意したクラスを内部で使用し、extern "C" を宣言した、C++の関数をCプログラムから呼び出し、Cコンパイラでリンクすることを考えています。  この場合、C++関数内で使用されるクラスについても、extern "C"の記述が必要でしょうか?  またその記述の仕方はどのようになるでしょうか?  あるいは、そういったことはできないのでしょうか?(coutが使えることを考えると、できないわけではないとも思っていますが)  あるいは、コンパイルの際の、オプションなどで解決できるでしょうか?  クラスはnewで生成して使用しています。 環境はソラリスのCCとccを使っています。 どうか、ご回答よろしくお願いします。

  • CからC++の関数呼び出し

    CからC++の関数を呼び出して値を取得したいのですが、コンパイルエラーになってしまいます。 呼び出す関数内でさらに同じクラスの関数を呼び出して値をreturnしたいだけなのですが、 ご教示願います。 ソースは下記のような感じです。 Cソース(AAA.c) main(){ ・・・・・ if ( funcA() ){ ・・・・ } } C++ソース(BBB.cpp) int clsB::funcB { return iflg; } extern "C" { int funcA() { return funcB(); } } ※上記externは特に何かの関数内に書いているわけではありません。 C++ヘッダ(BBB.hpp) class clsB : public XXX { private: int iflg; ・・・・ public: int funcB(); ・・・・ } 上記にコンパイルすると、 externしている箇所でfuncBはスコープにありません?のようなエラーが出てしまいます。 ラッパ関数を使って使用するなどと聞いたのですが、やり方がいまいちわかりません。 どうか教えていただけますでしょうか。 また、他にやり方があるかと思いますが、いいやり方があれば教えていただけると幸いです。 以上です、よろしくお願いいたします。 不足内容あれば指定願います。

  • extern "C" の利用方法に関して

    皆さんこんにちは。 extern "C"使って、 C++に書いてある関数をCでも使おうと、 もがいている最中の者です。 C++側のソース内にある、 Cでも使いたい関数に「eztern "C"」をつけ足しコンパイルに成功しました。 これから、C側でも、 C++から引用したい関数にexternをつけて、 コンパイルをしてしまおうとは思っているのですが、 C++のソース内にある関数を C側でも使うための作業としては、 これだけでいいのでしょうか? 今回作成した 「C++」のソースと「C」のソースは、 全然違うディレクトリにそれぞれ存在しているのですが、 それぞれは、認識され合うものなのでしょうか? お互いのコンパイルにあたってオプションを指定するか、 Makefileで書き換えるべき部分があるのでしょか? 笑ってしまうよな質問でしたらすいませんが、 アドバイスいただけるとありがたいです。 宜しくお願い致します。

  • Cの関数からC++の関数(DLL)を呼ぶ方法について

    C++関数からCの関数を呼ぶには extern "C" を使うのはわかるのですが C関数からC++の関数を呼ぶ方法がわかりません。 『外部参照 1 が未解決』になってリンクが出来ません。 ちなみにC++の関数はDLLで、他のC++関数からは呼ぶことも実行出来ることも 確認済みです。 よろしくお願いします。

  • CからC++の関数を使用するには

    C++からCの関数を参照する場合は extern "C"{ void test(void); } などと定義すれば可能なのですが、逆に C++で定義した関数をCで使うにはどのようにすれば よいのでしょうか?

  • C言語で、記憶クラス指定子extern・staticを関数に指定

    C言語の本に、「関数の定義と呼び出す側が別ソースファイルの場合、プロトタイプはヘッダーファイルに書き、定義側と呼び出し側の両方でインクルードしましょう」ということが書かれていました。 例えば、 ===code1a.c=== extern void funcB(int); static void funcA() { funcB(1); } ===code1b.c=== void funcB(int a) { printf("%d\n",a); } このような場合には、もしcode1b.cの中の関数funcBに引数を追加した場合、再コンパイルしても気づかないのでよくない。 そこで、次のようにヘッダーファイルを作り、プロトタイプはそこに書くべきだ。 ***code2b.h*** extern void funcB(int); ***code2a.c*** #include "code2b.h" static void funcA() { funcB(1); } ******code2b.c**** #include "code2b.h" void funcB(int a) { printf("%d\n",a); } 記述は以上のようなことです。 #include "code2b.h" とは、 extern void funcB(int); が書いてあるのと同じだと思います。 私が思ったのは、本の勧める方法では、 funcBを定義しているcode2b.cで、プロトタイプの記憶クラス指定子が、externになっているが良いのか(externとは、別のソースファイルで定義されているという意味ではないか)ということです。 extern, staticは、プロトタイプに書くべきなのか、関数の定義に書くべきなのか、も両方に書くべきなのでしょうか。 私の処理系では、 ・プロトタイプ宣言でexternを付けて関数定義でstaticを付ける、 ・staticを付けた関数を他のソースファイルで呼ぶ、 などの明らかに矛盾する場合は、コンパイルエラーになります。 でも、extern単独での役割はなさそうです。 他の処理系でも同じでしょうか。 (main等省略)

  • CとC++、どちらでコンパイルされているかをソース中で判別する方法

    タイトルのとおり、CとC++のどちらでコンパイルされているのかを、ソース中で判別する方法(#ifなど)を教えて下さい。 目的は、extern "C" という記述がCではエラーになってしまうのですが、CでもC++でもインクルード可能なヘッダファイルにするため、ヘッダファイル中で   #if「C++でコンパイル中」     extern "C" {   #endif としたいのです。 よろしくお願い致します。

  • Cで作成したDLLからC++内で関数を利用する。

    こんにちは。 Cで作成したDLLをC++で呼び出してその関数を使いたいのですが、リンクがうまくいきません。 externを使えばいいのですか?? 具体的な使い方が分からないので、教えてください。

  • extern指定子と実装(#include)について

    2点質問があります。 #1.#includeできるのはヘッダーファイルのみなのでしょうか。    ヘッダファイルをインクルードしなくてはいけないのは、わかっ   てます。.c(Cソースコード)はインクルードできないのでしょう   か。 #2.#1と絡んだことについてです。    たとえば、2つの関数Func1()とFunc2()とをメインルーチンと   は別のソースコードに関数の処理を記述したとします。    ファイル名:Func.c    中身:Func1とFunc2の処理内容    次にこれをメインルーチン内で使用するために以下のように記述   して保存したとします。    ファイル名:Func.h    中身:#include "Func.c" extern void Func1(void); extern void Func2(void); 最終的に、ファイル名:main.c         #include "Func.h" --------------- Func1(); Func2(); というようなことは可能でしょうか。

  • JNAでc言語ファイルの読み込み方が分かりません

    JNAでc言語ファイルの読み込み方が分かりません JNAを使用して、javaからcを読み込み動作するプログラムを作っています。 なんとなく定義は分かってきたのですが、 javaのソースコードに CLibrary.INSTANCE.printf(); のように、c言語を書き込んでいる状況なのですが、 JNAを利用した.javaファイルから.cファイルを読み込む方法はありますか? c言語の場合、.cファイルごとに分割された関数をmainが呼び出すとき、 extern void Sample(); とプロトタイプ宣言の後に Sample(); で呼び出せるみたいなので、 これを使って、 CLibrary.INSTANCE.extern void Sample(); とやってみましたが、コンパイルできませんでした;; 他にやり方がありますか? 知ってる方がいらっしゃいましたら、教えてください。 よろしくお願いします。

    • ベストアンサー
    • Java

専門家に質問してみよう