.so ライブラリでの C++ クラスの使用
-
09-06-2019 - |
質問
C++ コース用の小さなクラス ライブラリを作成しようとしています。
共有オブジェクトでクラスのセットを定義し、ライブラリをデモするメイン プログラムでそれらを直接使用することができるかどうか疑問に思っていました。何かトリックがあるのでしょうか?昔 (実際にプログラミングを始める前に) C++ クラスは MFC .dll でのみ動作し、通常の dll では動作しないという内容を読んだ記憶がありますが、それは Windows 側だけの話です。
解決
C++ クラスは .so 共有ライブラリで正常に動作します (Windows 上の非 MFC DLL でも動作しますが、それは本当の質問ではありません)。ライブラリからシンボルを明示的にエクスポートする必要がないため、実際には Windows よりも簡単です。
このドキュメントでは、ほとんどの質問に答えます。 http://people.redhat.com/drepper/dsohowto.pdf
覚えておくべき主なことは、 -fPIC
コンパイル時のオプション、および -shared
リンク時のオプションです。ネット上でたくさんの例を見つけることができます。
他のヒント
私の解決策/テスト
これが私の解決策です、そしてそれは私が期待したことを行います。
コード
猫、ああ :
#include <string>
class Cat
{
std::string _name;
public:
Cat(const std::string & name);
void speak();
};
猫.cpp :
#include <iostream>
#include <string>
#include "cat.hh"
using namespace std;
Cat::Cat(const string & name):_name(name){}
void Cat::speak()
{
cout << "Meow! I'm " << _name << endl;
}
main.cpp :
#include <iostream>
#include <string>
#include "cat.hh"
using std::cout;using std::endl;using std::string;
int main()
{
string name = "Felix";
cout<< "Meet my cat, " << name << "!" <<endl;
Cat kitty(name);
kitty.speak();
return 0;
}
編集
最初に共有ライブラリをコンパイルします。
$ g++ -Wall -g -fPIC -c cat.cpp
$ g++ -shared -Wl,-soname,libcat.so.1 -o libcat.so.1 cat.o
次に、ライブラリ内のクラスを使用して、メインの実行可能プログラムまたは C++ プログラムをコンパイルします。
$ g++ -Wall -g -c main.cpp
$ g++ -Wall -Wl,-rpath,. -o main main.o libcat.so.1 # -rpath linker option prevents the need to use LD_LIBRARY_PATH when testing
$ ./main
Meet my cat, Felix!
Meow! I'm Felix
$
私の理解では、すべて同じコンパイラを使用してコンパイルされた .so ファイルをリンクしている限り、これは問題ありません。コンパイラが異なれば、シンボルが異なる方法で破壊され、リンクに失敗します。
これは、Windows で COM を使用する利点の 1 つであり、OOP オブジェクトを DLL に配置するための標準を定義します。GNU g++ を使用して DLL をコンパイルし、それを MSVC (または VB) でコンパイルされた EXE にリンクできます。