GNU/Linux >> Linux の 問題 >  >> Linux

Linux で共有ライブラリの遅延ロードを行う方法

遅延読み込みはランタイム機能ではありません。 MSVC++ は、Windows の助けを借りずに実装しました。そして dlopen のように Linux では GetProcAddress が唯一の方法です。 Windows で唯一のランタイム メソッドです。

それでは、遅延読み込みとは何ですか?それは非常に簡単です:DLL への呼び出しはすべてポインターを経由する必要があります (どこにロードされるかわからないため)。これは常にコンパイラとリンカーによって処理されます。ただし、遅延読み込みでは、MSVC++ は最初にこのポインターを LoadLibrary を呼び出すスタブに設定します。 と GetProcAddress あなたのために。

Clang は ld の助けがなくても同じことができます .実行時は普通の dlopen です 呼び出し、Linux は Clang がそれを挿入したと判断できません。

MSalters の回答に追加するには、dlopen しようとする小さな静的スタブ ライブラリを作成することで、Linux での遅延読み込みに対する Windows のアプローチを簡単に模倣できます。 その関数のいずれかへの最初の呼び出しで必要なライブラリ (診断メッセージを発行し、dlopen が失敗した場合は終了する) と、そのライブラリへのすべての呼び出しを転送します。

このようなスタブ ライブラリは、手動で記述したり、プロジェクト/ライブラリ固有のスクリプトで生成したり、ユニバーサル ツール Implib.so で生成したりできます:

$ implib-gen.py libxyz.so
$ gcc myapp.c libxyz.tramp.S libxyz.init.c ...

この機能は、プロキシ デザイン パターンを使用して移植可能な方法で実現できます。

コードでは次のようになります:

#include <memory>

// SharedLibraryProxy.h
struct SharedLibraryProxy
{
    virtual ~SharedLibraryProxy() = 0;

    // Shared library interface begin.
    virtual void foo() = 0;
    virtual void bar() = 0;
    // Shared library interface end.

    static std::unique_ptr<SharedLibraryProxy> create();
};

// SharedLibraryProxy.cc
struct SharedLibraryProxyImp : SharedLibraryProxy
{
    void* shared_lib_ = nullptr;
    void (*foo_)() = nullptr;
    void (*bar_)() = nullptr;

    SharedLibraryProxyImp& load() {
        // Platform-specific bit to load the shared library at run-time.
        if(!shared_lib_) { 
            // shared_lib_ = dlopen(...);
            // foo_ = dlsym(...)
            // bar_ = dlsym(...)
        }
        return *this;
    }

    void foo() override {
        return this->load().foo_();
    }

    void bar() override {
        return this->load().bar_();
    }
};

SharedLibraryProxy::~SharedLibraryProxy() {}

std::unique_ptr<SharedLibraryProxy> SharedLibraryProxy::create() {
    return std::unique_ptr<SharedLibraryProxy>{new SharedLibraryProxyImp};
}

// main.cc
int main() {
    auto shared_lib = SharedLibraryProxy::create();
    shared_lib->foo();
    shared_lib->bar();
}

Linux
  1. 古いコンピュータを再び便利にする方法

  2. Linux 上の C++ 動的共有ライブラリ

  3. Linux で共有ライブラリを初期化する方法

  1. LinuxにNcursesライブラリをインストールする方法

  2. Linux で共有ライブラリのバージョン管理を行う方法は?

  3. Linuxで差分バックアップを作成するには?

  1. Linux – Trに非ASCII(unicode)文字を認識させる方法は?

  2. Sftpで共有ディレクトリにアクセスできるようにする方法は?

  3. Linux 共有ライブラリの紹介 (共有ライブラリの作成方法)