繁体   English   中英

为C ++库创建自动C包装器?

[英]Create automatic C wrapper for C++ library?

假设我有一个C ++ DLL。 AFAIK,没有广泛采用的C ++ ABI标准,因此为了确保它的工作原理并且不依赖于目标应用程序的编译器,我需要将我的库包装在C接口中。

有没有可以自动生成此类界面的工具? 如果他们可以围绕C接口生成包装器看起来好像它们是原始的C ++对象,那也会很好

Foo* f = new Foo();  // FooWrapper* fw = Foo_create();
f->bar("test");      // Foo_bar(fw, "test")

转换为使用生成的C ABI在我的库中调用的C函数。 我知道C ++是相当复杂的语言,并不是所有东西都可以很容易地包装在C接口中,但我想知道是否有任何这样的解决方案甚至支持C ++语言的一个子集(可能借助于一些手动编写的IDL / XML文件)?

没有广泛采用的C ++ ABI标准

我很确定这有点夸张 - 对于任何给定的平台都没有那么多不同的编译器,所以为每个供应商生成一个DLL可能更容易(例如微软,Windows上的GCC,Linux上的GCC) ,Sun和GCC for Solaris,GCC for MacOS - 就我所知,CLANG与GCC兼容)。

添加C层接口基本上意味着接口层不得:1。使用需要特殊复制/赋值/构造行为的任何对象。 2.使用任何“抛出”例外。 3.使用虚拟功能。 跨界面。

我认为,“修复”由“缺乏ABI”引起的问题比制作一个适合C ++使用C接口的良好界面更容易。

如果您想要一种方法使C ++代码可以从其他编译器/标准库调用,您可以使用https://github.com/jbandela/cppcomponents中的 cppcomponents。 完全披露 - 我是图书馆的作者。

这是一个简单的hello world示例

首先创建一个名为library.h的文件。在此文件中,您将定义Component

#include <cppcomponents/cppcomponents.hpp>

struct IPerson
:public cppcomponents::define_interface<cppcomponents::uuid<0xc618fd04,0xaa62,0x46e0,0xaeb8,0x6605eb4a1e64>>
{

    std::string SayHello();

    CPPCOMPONENTS_CONSTRUCT(IPerson,SayHello);



};

inline std::string PersonId(){return "library!Person";}

typedef cppcomponents::runtime_class<PersonId,cppcomponents::object_interfaces<IPerson>> Person_t;
typedef cppcomponents::use_runtime_class<Person_t> Person;

接下来创建library.cpp在此文件中,您将实现接口和组件

#include "library.h"

struct PersonImplementation:cppcomponents::implement_runtime_class<PersonImplementation,Person_t>
{

    std::string SayHello(){return "Hello World\n";}

};

CPPCOMPONENTS_DEFINE_FACTORY(PersonImplementation);

最后,这是您使用实现的主程序(称为example1.cpp)

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

int main(){
    Person p;
    std::cout << p.SayHello();

}

要构建程序,您需要下载cppcomponents(只需从上面的git链接克隆)。 它是一个仅头文件库,只需要一个c ++ 11编译器。

以下是在Windows上构建它的方法

cl /EHsc example1.cpp /I pathtocppcomponents

g++ -std=c++11 library.cpp -o library.dll -shared -I pathtocppcomponents

其中pathocppcomponents是cppcomponents的目录。 我假设你的路上有cl和g ++。

要运行该程序,请确保library.dll与example1.exe位于同一目录中并运行example1.exe

这个库需要相当兼容的c ++ 11支持,所以它需要MSVC 2013 Preview,至少需要g ++ 4.7。 该库适用于Windows和Linux。

据我所知,答案是否定的,你应该通过一些“黑客”和修改自己处理这个问题,例如你的t变量std::string可能被“externed”到C通过t.c_str()接口,因为c_str返回一个const char * ,这是一个C理解而没有任何问题的类型。

我个人没有发现C ++很复杂,我也看不到“ABI问题”,我的意思是没有什么是完美的,但是你将C整个代码库外化到“解决”这个问题? 首先使用C,也就是C,它也不是易于处理的语言,例如在C中甚至没有“字符串”的概念,以及在保持一切类型安全的同时在C ++中解决的问题,如果你想达到同样的目标,那么在C中真的很有挑战性。

我认为你对此有点太过分了,而且你正在使事情变得复杂,因为现在你在最流行的平台上有3 + 1个主要选项:

  • libsupc ++
  • libcxxrt
  • 的libc ++ ABI
  • 加上ABI用于您选择的MSVC(又名“只有上帝知道”)

对我来说,在linux上,libsupc ++运行得非常好,我正在关注libc ++ abi项目,我也没有看到任何大问题,唯一真正的问题是llvm现在基本上是一个面向Apple的项目,所以对其他平台没有那么真实和良好的支持,但是libc ++ abi在linux上编译并运行得相当好(虽然它基本没用且毫无意义,在linux上已经有了libsupc ++。)。

我也永远不会在Windows下使用MSVC,在我看来,最好坚持使用类似GCC的编译器,例如mingw,你有最新的功能,你可以简化代码库和构建阶段。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM