【问题标题】:Using C++ classes in .so libraries在 .so 库中使用 C++ 类
【发布时间】:2010-09-08 15:41:44
【问题描述】:

我正在尝试为 C++ 课程编写一个小型类库。

我想知道是否可以在我的共享对象中定义一组类,然后直接在我演示库的主程序中使用它们。有没有什么技巧?我记得很久以前(在我开始真正编程之前)读过这篇文章,C++ 类只适用于 MFC .dll 而不是普通的,但这只是 windows 方面的。

【问题讨论】:

    标签: c++ linux class-library


    【解决方案1】:

    C++ 类在 .so 共享库中工作正常(它们也可以在 Windows 上的非 MFC DLL 中工作,但这不是你的问题)。它实际上比 Windows 更容易,因为您不必从库中显式导出任何符号。

    本文档将回答您的大部分问题:http://people.redhat.com/drepper/dsohowto.pdf

    要记住的主要事项是在编译时使用-fPIC 选项,在链接时使用-shared 选项。你可以在网上找到很多例子。

    【讨论】:

      【解决方案2】:

      据我了解,只要您链接 .so 文件,这些文件都是使用相同的编译器编译的,这很好。不同的编译器会以不同的方式对符号进行处理,导致链接失败。

      这是在 Windows 上使用 COM 的优势之一,它定义了将 OOP 对象放入 DLL 的标准。我可以使用 GNU g++ 编译 DLL 并将其链接到使用 MSVC 甚至 VB 编译的 EXE!

      【讨论】:

      • 对此有一个警告:您可以使用包含由不同编译器编译的 C++ 代码的共享库,如果:(a) 符号修改方案匹配或 (b) 您有一些 extern C 函数要使用作为 API 粘合剂。
      【解决方案3】:

      我的解决方案/测试

      这是我的解决方案,它符合我的预期。

      代码

      cat.hh:

      #include <string>
      
      class Cat
      {
          std::string _name;
      public:
          Cat(const std::string & name);
          void speak();
      };
      

      cat.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
      $
      

      【讨论】:

      • 此代码显示属于跨共享库的 C++ 类的“陷阱”之一。通过在“共享”接口中使用 STL 类意味着库和应用程序都在编译自己的 STL 类“字符串”实现。如果这两个项目是在同一台机器上使用同一个编译器同时编译的,那么一切看起来都很好。编译库,等待 18 个月,然后编译应用程序,它“可能”工作。但不能保证。将您的共享库以二进制形式分发给其他开发人员,您将遇到“问题”
      • 正如其他人所建议的那样,这种方法存在缺陷,因为编译器之间的名称修饰差异。我找到了一个很好的资源,似乎显示了正确的方式(第 3.3 节):tldp.org/HOWTO/C++-dlopen/thesolution.html
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多