swift zeromq c桥接标题 - 找不到类型

时间:2014-11-22 06:29:08

标签: c swift interop header-files

我正在尝试使用czmq为zeromq构建Swift绑定。

我在xcode中配置了一个桥接头,它似乎明白了,但我仍然会收到此错误:

/Users/jjl/code/swiftzmq/src/zsock.swift:47:37: error: use of undeclared type 'zsock_t'
typealias zsock_ptr = UnsafePointer<zsock_t>

在C中使用它,如果我这样做(这是我的桥接头的确切内容),我会有这种类型:

#include <czmq.h>

我知道它被包含在内,因为它在一个头文件中抱怨某些东西,直到我链接到正确的库路径。

我不知道从哪里开始。您可以提供任何帮助

我的项目位于https://github.com/jjl/swiftzmq

1 个答案:

答案 0 :(得分:0)

我弄清楚发生了什么事。快速的互操作层不够智能,无法理解czmq的作者以更好的代码的名义在编译工具链上播放的技巧,所以我们必须做一些C包装来将其隐藏起来。

简单的一点:

  • 从桥接标题中删除#include <czmq.h>
  • 添加一行导入您选择的另一个标题(我选择szsocket.h,因为它是swift zsocket包装器)
  • 创建相应的.c文件和#import <czmq.h>

更难的一点:

您需要在标头中重新创建库使用的任何结构。在我的例子中,zsock_t结构定义如下:

typedef struct zsock_t {
    uint32_t tag;               //  Object tag for runtime detection
    void *handle;               //  The libzmq socket handle
    char *endpoint;             //  Last bound endpoint, if any
    char *cache;                //  Holds last zsock_brecv strings
    int type;                   //  Socket type
    size_t cache_size;          //  Current size of cache
} zsock_t;

我们创建一个简单的包装器,如下所示:

typedef struct szsock_t {
    uint32_t tag;               //  Object tag for runtime detection
    void *handle;               //  The libzmq socket handle
    char *endpoint;             //  Last bound endpoint, if any
    char *cache;                //  Holds last zsock_brecv strings
    int type;                   //  Socket type
    size_t cache_size;          //  Current size of cache
} szsock_t;

您还需要重新创建这些结构中使用的任何typedef。在这种情况下,轻而易举的没有其他人。这些都进入新的标题(.h)文件

然后,您需要在库中包含接受这些结构之一的每个函数。我们以zsock_new函数为例。

首先,我们需要在标头中预先声明我们的版本以避免任何zsock类型。我们只是用zsock替换szsock的每一次出现(emacs可以帮助解决此问题):

szsock_t *szsock_new (int type, const char *filename, size_t line_nbr);

接下来我们需要在.c文件中创建包装函数:

szsock_t *szsock_new (int type, const char *filename, size_t line_nbr) {
    return (szsock_t *) zsock_new(type, filename, line_nbr);
}

注意我们如何在zsock_tszsock_t之间进行投射并使用内部zsock函数。这样做是安全的,因为swift编译器不会读它,只是c编译器。

接下来,有一堆varargs函数。这对我有用:

int szsock_bind (szsock_t *self, const char *format, ...) {
    int ret;
    va_list args;
    va_start(args, format);
    ret = zsock_bind( (zsock_t *) self, format, args);
    va_end(args);
    return ret;
}

祝所有读快速包装图书馆的人好运!