【问题标题】:C++ library across different compilers跨不同编译器的 C++ 库
【发布时间】:2013-10-25 13:59:28
【问题描述】:

我正在使用 MinGW (4.8.0 dw2 posix) 编写一个 C++ 库。该库用于另一个使用另一个编译器(在本例中为 msvc)的 C++ 项目。

参考this 我正在重新设计我的 C++ 库。有两件事我不知道该怎么做:

  1. 我可以使用命名空间吗?
  2. 我注意到 MinGW 上的 time_t 是 32 位,而在 msvc 中是 64 位。我能做什么?

1)

这是否破坏了 ABI:

// Window.h

// MYLIB_API defined as __declspec( dllexports )
// MYLIB_CALL defined as __stdcall

namespace mylib {

class Window {
public:
  virtual void MYLIB_CALL destroy() = 0;
  virtual void MYLIB_CALL setTitle(const char* title) = 0;
  virtual const char* MYLIB_CALL getTitle() = 0;

  void operator delete(void* p) {
    if (p) {
      Window* w = static_cast<Window*>(p);
      w->destroy();
    }
  }
};

} // mylib

extern "C" MYLIB_API mylib::Window* MYLIB_CALL CreateWindow(const char* title);

2

如何确定不同编译器的基本类型相同。例如,在这种情况下,time_t 在 MinGW 上定义为 unsigned long,在 msvc 上定义为 `__int64'。我能做什么?

【问题讨论】:

  • 您使用的是什么版本的 MSVC?会是 2013 年吗?
  • @JohnBandela 可以是 2010、2012 或 2013 之间的一个。我们可以选择

标签: c++ dll shared-libraries abi


【解决方案1】:

https://github.com/jbandela/cppcomponents使用我的库cppcomponents

这是在 Windows 上使用 Visual C++ 2013(以前的版本没有足够的 c++11 支持)和 mingw gcc 4.7+ 测试的。它是在 boost 许可下发布的仅标头库。这允许您跨编译器使用 c++11 功能,例如 std::string、vector、tuple、pair、time_point。我很乐意回答您关于如何将它用于您的特定情况的任何问题。

这是你的例子

首先在Window.h中定义类

#include <cppcomponents/cppcomponents.hpp>

namespace mylib{

    struct IWindow :cppcomponents::define_interface<
        cppcomponents::uuid<0x0d02ac9a, 0x4188, 0x48fc, 0x8054, 0xafe7252ec188 >>
    {
        std::string getTitle();
        void setTitle(std::string new_title);

        CPPCOMPONENTS_CONSTRUCT(IWindow, getTitle, setTitle);

    };

    inline std::string WindowID(){ return "windowlibdll!Window"; }
    typedef cppcomponents::runtime_class<WindowID, cppcomponents::object_interfaces<IWindow>> Window_t;
    typedef cppcomponents::use_runtime_class<Window_t> Window;

}

然后在WindowImp.cpp中实现类

#include "Window.h"


struct ImplementWindow:cppcomponents::implement_runtime_class<ImplementWindow,mylib::Window_t>
{
    std::string title_;
    ImplementWindow(){}
    std::string getTitle(){
        return title_;
    }
    void setTitle(std::string new_title){
        title_ = new_title;
    }

};

CPPCOMPONENTS_DEFINE_FACTORY()

最后使用UseWindow.cpp中的代码

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

int main(){
    mylib::Window w;
    w.setTitle("my title");
    std::cout << w.getTitle();
}

这是使用 g++ 构建库的方法

g++ WindowImp.cpp -std=c++11 -shared -o windowlibdll.dll -I Source\Repos\cppcomponents

下面是您如何使用 MSVC 2013 构建程序

cl UseWindow.cpp /EHsc /I Source\Repos\cppcomponents

Source\Repose\cppcomponents替换为你有cppcomponents的路径

确保生成的 windowslibdll.dll 和 UseWindow.exe 在同一目录中并运行 UseWindow.exe

【讨论】:

  • 是不是类似于 ATL 实现?
  • @elvis.dukaj 之类的。它使用现代 c++11 技术。 ATL 不允许您使用标准类型,例如字符串或向量,并且不允许异常。 cppcomponents 允许异常和字符串、向量。我将在几分钟内发布一个如何使用的示例
  • @elvis.dukaj 示例已经完成,如果您想要一个带字符串参数的构造函数,请告诉我,我将添加到示例中
  • 我可以使用函数重载吗?
  • 是的。使用重载函数是透明的,但您必须稍微更改实现。给我一个例子,我会告诉你如何做重载
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-16
  • 1970-01-01
  • 2023-03-10
  • 2021-12-10
  • 1970-01-01
相关资源
最近更新 更多