简体   繁体   English

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

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

Let say I have a C++ DLL. 假设我有一个C ++ DLL。 AFAIK, there is no widely-adopted ABI standard for C++, therefore to make sure it works and does not depend on the compiler of the target application I would need to wrap my library in a C interface. AFAIK,没有广泛采用的C ++ ABI标准,因此为了确保它的工作原理并且不依赖于目标应用程序的编译器,我需要将我的库包装在C接口中。

Are there any tools that can automatically generate such interface? 有没有可以自动生成此类界面的工具? Would also be nice if they could generate wrappers around C interface to look as if they are original C++ objects, eg 如果他们可以围绕C接口生成包装器看起来好像它们是原始的C ++对象,那也会很好

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

translates into C functions that are invoked in my library using generated C ABI. 转换为使用生成的C ABI在我的库中调用的C函数。 I understand that C++ is fairly complicated language and not everything can be easily wrapped in a C interface, but I was wondering if there are any such solutions that even support a subset of the C++ language (maybe with the help of some manually written IDL/XML files)? 我知道C ++是相当复杂的语言,并不是所有东西都可以很容易地包装在C接口中,但我想知道是否有任何这样的解决方案甚至支持C ++语言的一个子集(可能借助于一些手动编写的IDL / XML文件)?

there is no widely-adopted ABI standard for C++ 没有广泛采用的C ++ ABI标准

I'm pretty sure that is a bit exaggerated - there aren't THAT many different compilers available for any given platform, so it would probably be easier to just produce a DLL for each vendor (eg Microsoft, GCC on Windows, GCC on Linux, Sun and GCC for Solaris, GCC for MacOS - CLANG is compatible with GCC as far as I know). 我很确定这有点夸张 - 对于任何给定的平台都没有那么多不同的编译器,所以为每个供应商生成一个DLL可能更容易(例如微软,Windows上的GCC,Linux上的GCC) ,Sun和GCC for Solaris,GCC for MacOS - 就我所知,CLANG与GCC兼容)。

To add a C layer interface basically means that the interface layer must not: 1. Use any objects of that require special copy/assignment/construction behaviour. 添加C层接口基本上意味着接口层不得:1。使用需要特殊复制/赋值/构造行为的任何对象。 2. Use any "throw" exceptions. 2.使用任何“抛出”例外。 3. Use virtual functions. 3.使用虚拟功能。 across that interface. 跨界面。

It is my opinion that it's easier to "fix" the problems caused by "lack of ABI" than it is to make a good interface suitable for C++ use with a C interface in the middle of it. 我认为,“修复”由“缺乏ABI”引起的问题比制作一个适合C ++使用C接口的良好界面更容易。

If you want a way to make C++ code callable from other compilers/standard libraries, you can use cppcomponents from https://github.com/jbandela/cppcomponents . 如果您想要一种方法使C ++代码可以从其他编译器/标准库调用,您可以使用https://github.com/jbandela/cppcomponents中的 cppcomponents。 Full disclosure - I am the author of the library. 完全披露 - 我是图书馆的作者。

Here is a simple hello world example 这是一个简单的hello world示例

First make a file called library.h In this file you will define the Component 首先创建一个名为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;

Next create library.cpp In this file you will implement the interface and component 接下来创建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);

Finally here is you main program (call it example1.cpp) that uses your implementation 最后,这是您使用实现的主程序(称为example1.cpp)

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

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

}

To build the program you will need to download cppcomponents (just clone from the git link above). 要构建程序,您需要下载cppcomponents(只需从上面的git链接克隆)。 It is a header only library and needs only a c++11 compiler. 它是一个仅头文件库,只需要一个c ++ 11编译器。

Here is how you would build it on Windows 以下是在Windows上构建它的方法

cl /EHsc example1.cpp /I pathtocppcomponents

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

where pathocppcomponents is the directory of cppcomponents. 其中pathocppcomponents是cppcomponents的目录。 I am assuming you have cl and g++ in your path. 我假设你的路上有cl和g ++。

To run the program, make sure library.dll is in the same directory as example1.exe and run example1.exe 要运行该程序,请确保library.dll与example1.exe位于同一目录中并运行example1.exe

This library requires fairly compliant c++11 support, so it needs MSVC 2013 Preview, and at least g++ 4.7. 这个库需要相当兼容的c ++ 11支持,所以它需要MSVC 2013 Preview,至少需要g ++ 4.7。 This library works on both Windows and Linux. 该库适用于Windows和Linux。

As far as I know the answer is no and you are supposed to handle this by yourself with a little bit of "hacking" and modifications, for example your t variable which is an std::string can possibly be "externed" to a C interface by t.c_str() because c_str returns a const char * which is a type that C understands without any problem at all. 据我所知,答案是否定的,你应该通过一些“黑客”和修改自己处理这个问题,例如你的t变量std::string可能被“externed”到C通过t.c_str()接口,因为c_str返回一个const char * ,这是一个C理解而没有任何问题的类型。

I personally don't find C++ complicated, I can't see that "ABI issue" either, I mean nothing is perfect but you are externalizing to C your entire code base to "solve" this issue ? 我个人没有发现C ++很复杂,我也看不到“ABI问题”,我的意思是没有什么是完美的,但是你将C整个代码库外化到“解决”这个问题? Just use C in the first place, also C it's no easy language to deal with either, for example in C there is not even the notion of "string", and problems that are trivial to solve in C++ while keeping everything type-safe, are really challenging in C if you want to meet the same goal. 首先使用C,也就是C,它也不是易于处理的语言,例如在C中甚至没有“字符串”的概念,以及在保持一切类型安全的同时在C ++中解决的问题,如果你想达到同样的目标,那么在C中真的很有挑战性。

I think that you are going a little bit too far with this, and you are complicating things, as it is now you have 3 + 1 main options on the most popular platforms : 我认为你对此有点太过分了,而且你正在使事情变得复杂,因为现在你在最流行的平台上有3 + 1个主要选项:

  • libsupc++ libsupc ++
  • libcxxrt libcxxrt
  • libc++abi 的libc ++ ABI
  • plus the whetever ABI is for the MSVC of your choice ( aka "only god knows") 加上ABI用于您选择的MSVC(又名“只有上帝知道”)

for me, on linux, libsupc++ works very well, I'm following the libc++abi project and I don't see any big problem either, the only real problem with this is that llvm is basically an Apple oriented project for now, so there isn't that real and good support for the other platforms, but libc++abi compiles and works quite well on linux too ( although it's basically useless and pointless, on linux there is libsupc++ already.) . 对我来说,在linux上,libsupc ++运行得非常好,我正在关注libc ++ abi项目,我也没有看到任何大问题,唯一真正的问题是llvm现在基本上是一个面向Apple的项目,所以对其他平台没有那么真实和良好的支持,但是libc ++ abi在linux上编译并运行得相当好(虽然它基本没用且毫无意义,在linux上已经有了libsupc ++。)。

I also would never ever use MSVC under Windows, in my opinion it's better to stick with a GCC-like compiler such as mingw, you got bleeding edge features, and you can simplify your codebase and your building phase a lot. 我也永远不会在Windows下使用MSVC,在我看来,最好坚持使用类似GCC的编译器,例如mingw,你有最新的功能,你可以简化代码库和构建阶段。

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

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