34

Cを使ってプログラムを作っていますが、C++専用のAPIを持つライブラリをたくさん使う必要があります。では、C++ で共有オブジェクトを作成し、C を使用してその機能にアクセスすることは可能ですか?

  1. 私が渡したり返したりする唯一のデータは、C 互換のデータ型です。
  2. ここでは、cpp への変換または移行はオプションではありません。

これらのコードをインターフェイスできない場合、C++ コードから C コードへの情報を取得するにはどうすればよいですか? C から C++ 関数を呼び出してみましたが、リンク中に を含めるとエラーが発生します<string>。では、C から C++ 関数を呼び出す場合、C コンパイラと互換性のあるコードのみを使用する必要がありますか?

C++ ヘッダー cppfile.hpp

#ifndef CPPFILE_H
#define CPPFILE_H
    #ifdef __cplusplus
    extern "C" {
    #endif

    extern int myfunction(const char *filename);

   #ifdef __cplusplus
   }
   #endif
#endif

C++ ファイル cppfile.cpp

#include "cppfile.hpp"
#include <string>
int myfunction(const char *filename) {
    String S(filename);
    return 0;
}

C ファイル cmain.c

#include "cppfile.hpp"
int main(int argc, char **argv)
{
     int i = myfunction(argv[1]);
     printf("%d\n", i);
     return 0;
}

コンパイル:

gcc -c cmain.c
g++ -fPIC -shared -o cppfile.so cppfile.cpp
4

3 に答える 3

10

これは完全に可能です。方法は次のとおりです。1。)Cplusinessを含まないCAPIを備えたheader.hがあります。

#ifndef MIXEDCCPP_H
#define MIXEDCCPP_H

#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h> // Any C-compatible headers will go here.

// C API goes here.  C Functions can't contain any CPPiness.
void myclass_setName( void *pClassObj, const char *pName, int nameLen );

#ifdef __cplusplus
}
#endif

#ifdef __cplusplus

// Stuff that is only compatible with CPP goes here
// __cplusplus section won't get processed while compiling C files.

#include <vector> // CPP headers.


class MyClass {
   // Classes etc.
};
#endif // #ifdef __cplusplus

#endif // MIXEDCCPP_H

次に、.cppで、CPPを直接含めることができるいくつかのC-API関数を作成するだけです。

#include "mixedccpp.h"

extern "C" {
// C API goes here.  C Functions can't contain any CPPiness in their prototypes.
void myclass_setName( void *pClassObj, const char *pName, int nameLen )
{
    // But CPP knowledge can go inside the function - no problem, since this is a CPP file.
    MyClass *pMyClass = static_cast<MyClass *>(pClassObj);
    pMyClass->setName( pName, nameLen );
}

} // #extern "C"


// CPP Stuff goes here... or vice-versa.

あなたの場合、外部ライブラリを呼び出しているので、実際にはヘッダーで宣言されたCPPコードは必要ありません。ただし、CPPライブラリを呼び出すことができるC互換関数をCPPファイルに作成する必要があります。Cファイルから呼び出す必要のある関数にはextern"C"を使用し、クラスの代わりにC構造体を使用します。クラスが必要な場合は、void *を使用してそれらをポイントし、からクラスにキャストし直します。それらにアクセスする必要があるときはいつでもC機能。標準のmakefileは、.cppファイルを.cppとしてコンパイルし、extern "C" {}を理解していると仮定すると、これを問題なくコンパイルできるはずです。

于 2013-02-17T05:49:24.093 に答える
4

C コードでは C++ ヘッダーを使用できません<string>。Cから呼び出されるC++ APIの関数が(あなたが持っているように)宣言されていることを確認し、extern "C"(あなたが持っているように)Cコンパイラによって認識される型のみを使用する必要があります.

また、コードのいずれかが C++ である場合は、C++ コンパイラとリンクする必要があります。ローダー オプションを正しく設定するために多くのエネルギーを費やす準備ができている場合は、別の方法でも実行できますが、C++ コンパイラを使用するだけの方がはるかに簡単です。

gcc -c cmain.c
g++ -fPIC -shared -o cppfile.so cppfile.cpp
g++ -o cmain cmain.o cppfile.so

もちろん、次のことを行う必要があります。

  1. を追加#include <stdio.h>cmain.cます。
  2. で使用std::string S(filename);cppfile.cppます。

また、プログラムが引数なしで呼び出されると、次のようになります。

$ ./cmain
terminate called throwing an exceptionAbort trap: 6
$ ./cmain x3
0
$

テスト プログラムであっても、誤用から保護する必要があります。

于 2013-02-17T04:40:49.163 に答える