我正在尝试使用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>
我知道它被包含在内,因为它在一个头文件中抱怨某些东西,直到我链接到正确的库路径。
我不知道从哪里开始。您可以提供任何帮助
答案 0 :(得分:0)
我弄清楚发生了什么事。快速的互操作层不够智能,无法理解czmq的作者以更好的代码的名义在编译工具链上播放的技巧,所以我们必须做一些C包装来将其隐藏起来。
简单的一点:
#include <czmq.h>
行szsocket.h
,因为它是swift zsocket包装器)#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_t
和szsock_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;
}
祝所有读快速包装图书馆的人好运!