更改 C++ 的生成器API 转为 C 接口?

发布于 2024-12-09 12:47:39 字数 70 浏览 0 评论 0原文

是否有某种工具可以提供 C++ 标头,并将 API/lib/接口更改为 C 接口,并生成 C 函数来转换和调用 C++ 代码?

Is there some kind of tool i can give a c++ header to and have it change the API/lib/interface into a C interface as well as generate the C functions to cast and call the C++ code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

太阳公公是暖光 2024-12-16 12:47:39

我认为 SWiG 可能会完成大部分工作。

I think SWiG might do most of that.

喜爱纠缠 2024-12-16 12:47:39

我不知道有什么工具可以自动执行此操作,如果您将类作为 API 中公共函数的参数,那么它可能会变得非常棘手。

但如果您的 API 很简单并且主要使用本机类型,那么您可以手动完成此操作,不需要太多工作。下面是 C++ 类的 C 包装器的快速示例。假设这是要包装的 C++ 类,我们将其称为 test.h

class Test {
public:
    Test();
    int do_something(char* arg);
    bool is_valid(); // optional, but recommended (see below)
};

这是您的 C 标头 test_c.h

typedef void* TestHandle;
TestHandle newTest();
int deleteTest(TestHandle h);
int Test_do_something(TestHandle h, char* arg);

您的 C 实现将是一个带有以下内容的 C++ 文件 : C 函数,比方说 test_c.cpp

extern "C" TestHandle newTest()
{
    return (void*)new Test();
}

extern "C" int deleteTest(TestHandle h)
{
    Test* this = static_cast<Test*>(h);
    if (!this->is_valid())
        return -1; // here we define -1 as "invalid handle" error
    delete this;
    return 0; // here we define 0 as the "ok" error code
}

extern "C" int Test_do_something(TestHandle h, char* arg)
{
    Test* this = static_cast<Test*>(h);
    if (!this->is_valid())
        return -1; // here we define -1 as "invalid handle" error
    return this->do_something(arg);
}   

is_valid() 方法可以保证您不会获得错误的句柄。例如,您可以在所有实例中存储幻数,然后is_valid() 只是确保幻数存在。

I don't know of a tool that can do this automatically, it can get pretty tricky if you have classes as arguments to the public functions in your API.

But if your API is simple and mostly using native types, then you can do this by hand with not too much work. Here is a quick example of a C wrapper for a C++ class. Let's say this is the C++ class to wrap, let's call it test.h:

class Test {
public:
    Test();
    int do_something(char* arg);
    bool is_valid(); // optional, but recommended (see below)
};

This is your C header test_c.h:

typedef void* TestHandle;
TestHandle newTest();
int deleteTest(TestHandle h);
int Test_do_something(TestHandle h, char* arg);

And your C implementation will be a C++ file with C functions, let's say test_c.cpp:

extern "C" TestHandle newTest()
{
    return (void*)new Test();
}

extern "C" int deleteTest(TestHandle h)
{
    Test* this = static_cast<Test*>(h);
    if (!this->is_valid())
        return -1; // here we define -1 as "invalid handle" error
    delete this;
    return 0; // here we define 0 as the "ok" error code
}

extern "C" int Test_do_something(TestHandle h, char* arg)
{
    Test* this = static_cast<Test*>(h);
    if (!this->is_valid())
        return -1; // here we define -1 as "invalid handle" error
    return this->do_something(arg);
}   

The is_valid() method is there to guarantee that you were not given a bad handle. For example, you can store a magic number in all your instances, then is_valid() just ensures the magic number is there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文