c++ - name - unix shared libraries




Linux上的C++動態共享庫 (2)

這是使用g ++進行動態共享庫編譯的後續步驟。

我試圖在Linux上用C ++創建一個共享類庫。 我可以讓庫進行編譯,並且可以使用我在herehere找到的教程來調用一些(非類)函數。 當我嘗試使用庫中定義的類時,我的問題就開始了。 我鏈接到的第二個教程展示瞭如何加載符號來創建庫中定義的類的對象,但是停止使用這些對象來完成任何工作。

有誰知道有關創建共享C ++類庫的更完整教程,該教程還展示瞭如何在單獨的可執行文件中使用這些類? 一個非常簡單的教程,顯示對象的創建,使用(簡單的getter和setter會很好),刪除將是太棒了。 說明使用共享類庫的一些開源代碼的鏈接或引用同樣適用。

儘管codelogic和here的答案確實起作用,但我想補充一點,自從提出這個問題以來,我選擇了一個here ,它的第一章提供了示例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作為基類,並定義虛擬的所有必需函數。 然後,插件作者將從MyClass派生,覆蓋虛擬並實現create_objectdestroy_object 。 您的主應用程序不需要以任何方式進行更改。


下面顯示了一個共享類庫的例子[h,cpp]和一個使用該庫的main.cpp模塊。 這是一個非常簡單的例子,makefile可以做得更好。 但它可以幫助你:

shared.h定義了這個類:

class myclass {
   int myx;

  public:

    myclass() { myx=0; }
    void setx(int newx);
    int  getx();
};

shared.cpp定義了getx / setx函數:

#include "shared.h"

void myclass::setx(int newx) { myx = newx; }
int  myclass::getx() { return myx; }

main.cpp使用該類,

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

using namespace std;

int main(int argc, char *argv[])
{
  myclass m;

  cout << m.getx() << endl;
  m.setx(10);
  cout << m.getx() << endl;
}

和生成libshared.so的makefile以及與共享庫鏈接的main:

main: libshared.so main.o
    $(CXX) -o main  main.o -L. -lshared

libshared.so: shared.cpp
    $(CXX) -fPIC -c shared.cpp -o shared.o
    $(CXX) -shared  -Wl,-soname,libshared.so -o libshared.so shared.o

clean:
    $rm *.o *.so

要實際運行'main'並鏈接到libshared.so,您可能需要指定加載路徑(或將其放在/ usr / local / lib或類似文件中)。

以下指定當前目錄作為庫的搜索路徑並運行main(bash語法):

export LD_LIBRARY_PATH=.
./main

要看到該程序與libshared.so鏈接,你可以嘗試ldd:

LD_LIBRARY_PATH=. ldd main

在我的機器上打印:

  ~/prj/test/shared$ LD_LIBRARY_PATH=. ldd main
    linux-gate.so.1 =>  (0xb7f88000)
    libshared.so => ./libshared.so (0xb7f85000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb7e74000)
    libm.so.6 => /lib/libm.so.6 (0xb7e4e000)
    libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0xb7e41000)
    libc.so.6 => /lib/libc.so.6 (0xb7cfa000)
    /lib/ld-linux.so.2 (0xb7f89000)




shared-libraries