1. ホーム
  2. c++

[解決済み] LinuxにおけるC++ダイナミックシェアードライブラリ

2022-04-20 22:13:11

質問

の続報です。 g++での動的共有ライブラリのコンパイル .

LinuxでC++の共有クラスライブラリを作成しようとしています。 私はライブラリをコンパイルすることができ、私が見つけたチュートリアルを使用して、いくつかの(非クラス)関数を呼び出すことができます。 こちら こちら . 私の問題は、ライブラリに定義されているクラスを使おうとしたときに始まります。 私がリンクした2番目のチュートリアルでは、ライブラリで定義されたクラスのオブジェクトを作成するためのシンボルをロードする方法が紹介されていますが、その前に 使用 そのオブジェクトを使用して、何らかの作業を行うことができます。

共有C++クラスライブラリを作成するための、より完全なチュートリアルをご存知の方はいらっしゃいますか? 使用 を別の実行ファイルで使用できますか? オブジェクトの作成、使用(単純なゲッターとセッターで結構です)、削除を示す非常にシンプルなチュートリアルがあれば素晴らしいです。 共有クラスライブラリの使用を説明するオープンソースコードへのリンクや参照も同様に良いだろう。


の回答がありましたが コードロジック ニムロドム は動作しますが、私はただ、私が拾ったのは Linuxプログラミング入門 この質問をしてから、その最初の章にC言語のサンプルコードと、静的ライブラリと共有ライブラリの両方の作成と使用に関する良い解説があります。 これらの例は、Googleブック検索で その本の古い版 .

解決方法は?

myclass.h

#ifndef __MYCLASS_H__
#define __MYCLASS_H__

class MyClass
{
public:
  MyClass();

  /* use virtual otherwise linker will try to perform static linkage */
  virtual void DoSomething();

private:
  int x;
};

#endif

myclass.cc

#include "myclass.h"
#include <iostream>

using namespace std;

extern "C" MyClass* create_object()
{
  return new MyClass;
}

extern "C" void destroy_object( MyClass* object )
{
  delete object;
}

MyClass::MyClass()
{
  x = 20;
}

void MyClass::DoSomething()
{
  cout<<x<<endl;
}

class_user.cc

#include <dlfcn.h>
#include <iostream>
#include "myclass.h"

using namespace std;

int main(int argc, char **argv)
{
  /* on Linux, use "./myclass.so" */
  void* handle = dlopen("myclass.so", RTLD_LAZY);

  MyClass* (*create)();
  void (*destroy)(MyClass*);

  create = (MyClass* (*)())dlsym(handle, "create_object");
  destroy = (void (*)(MyClass*))dlsym(handle, "destroy_object");

  MyClass* myClass = (MyClass*)create();
  myClass->DoSomething();
  destroy( myClass );
}

Mac OS Xの場合、でコンパイルします。

g++ -dynamiclib -flat_namespace myclass.cc -o myclass.so
g++ class_user.cc -o class_user

Linuxの場合、でコンパイルします。

g++ -fPIC -shared myclass.cc -o myclass.so
g++ class_user.cc -ldl -o class_user

これがプラグインシステムであれば、MyClassをベースクラスとして、必要な機能をすべてvirtualに定義することになる。プラグイン作成者は、MyClassを派生させ、仮想関数をオーバーライドして create_objectdestroy_object . メインアプリケーションは、何も変更する必要はありません。