让 swig 处理 c struct hack (__flexarray)
let swig handle a c struct hack (__flexarray)
我正在尝试为 linux' inotify
和 inotifywait
.
创建 c# 包装器代码
问题是 swig 无法处理 inotify
中使用的 flex 数组结构 hack
swig 版本是 4.0.2,inotify.h 来自 glib-headers 2.17-324(根据 rpm -q --whatprovides /usr/include/sys/inotify.h
)
struct inotify_event
{
int wd;
uint32_t mask;
uint32_t cookie;
uint32_t len;
char name __flexarray; // <- this fails
}
根据 What is __flexarr and how/why do c programmers use it?,这是一个 struct hack 和有效的 C99。
我的 swig-interface 文件看起来像
%module mymodule
%{
#include "/usr/includes/sys/inotify.h"
#include "/usr/includes/inotifywait/inotifytools.h"
};
%include "/usr/includes/sys/inotify.h"
%include "/usr/includes/inotifywait/inotifytools.h"
当我像 swigg -csharp -I/usr/include/inotifytools -I/usr/incldue/sys -Wall inotifybinding.i
那样调用 swig 时,它失败并显示错误 Syntax error - possibly a missing semicolon
并指向带有结构 hack 的行。
然后我想也许我可以创建自己的 inotify_event
版本并忽略来自 inotify.h
的声明,例如
%{
struct inotify_event
{
int wd;
uint32_t mask;
uint32_t cookie;
uint32_t len;
char name []; // <- should be the same as with __flexarray
}
// the #includes
};
%ignore inotify_event
// the %includes
不幸的是,错误仍然存在,我需要这个结构,因为其他重要的功能,如 inotifytools_next_event
return 某种 cptr
我不知道如何用 C# 处理。
我认为忽略基本上只会从包装代码中删除名为 inotify_event
的每个声明,但似乎在触发 %ignore 之前验证了 %includes。
有没有办法在我的包装代码中正确创建 inotify_event
?
编辑::最新的 swig 版本也不起作用
SWIG 不理解很多特定于编译器的东西,例如 Windows 上的 __cdecl
和 __stdcall
,但是如果您查看 Lib\windows.i
SWIG 安装,您会看到预处理器用于删除它们,例如#define __cdecl
.
我没有办法验证这一点,但您可以通过以下方法将未知的 SWIG 编译器选项转换为更标准的声明:
%module mymodule
%{
// included normally here
#include "/usr/includes/sys/inotify.h"
#include "/usr/includes/inotifywait/inotifytools.h"
};
#define __flexarray [] // turn "char name __flexarray;" into "char name[];"
%include "/usr/includes/sys/inotify.h"
%include "/usr/includes/inotifywait/inotifytools.h"
Mark Tolonens 解决方案确实解决了我最初的问题,但出现了语法错误等其他问题。
分别弹出不是因为 Mark Tolonens 的建议破坏了某些东西,而是因为它解决了第一个问题,而 SWIG 只是偶然发现了下一个问题。
经过一番挖掘后,我添加了以下 header 这解决了我所有的问题。
%module mymodule
%{
#include "/usr/includes/sys/inotify.h"
#include "/usr/includes/inotifywait/inotifytools.h"
};
%include "/usr/includes/sys/cdefs.h" // <- add this line here
%include "/usr/includes/sys/inotify.h"
%include "/usr/includes/inotifywait/inotifytools.h"
通过这一行,SWIG 为 inotify_event
生成了一个 c# class,一些快速测试证实了它的工作。
或者您可以自己进行封送处理,但是您必须处理 c# 等中的内存分配。
我正在尝试为 linux' inotify
和 inotifywait
.
问题是 swig 无法处理 inotify
中使用的 flex 数组结构 hack
swig 版本是 4.0.2,inotify.h 来自 glib-headers 2.17-324(根据 rpm -q --whatprovides /usr/include/sys/inotify.h
)
struct inotify_event
{
int wd;
uint32_t mask;
uint32_t cookie;
uint32_t len;
char name __flexarray; // <- this fails
}
根据 What is __flexarr and how/why do c programmers use it?,这是一个 struct hack 和有效的 C99。
我的 swig-interface 文件看起来像
%module mymodule
%{
#include "/usr/includes/sys/inotify.h"
#include "/usr/includes/inotifywait/inotifytools.h"
};
%include "/usr/includes/sys/inotify.h"
%include "/usr/includes/inotifywait/inotifytools.h"
当我像 swigg -csharp -I/usr/include/inotifytools -I/usr/incldue/sys -Wall inotifybinding.i
那样调用 swig 时,它失败并显示错误 Syntax error - possibly a missing semicolon
并指向带有结构 hack 的行。
然后我想也许我可以创建自己的 inotify_event
版本并忽略来自 inotify.h
的声明,例如
%{
struct inotify_event
{
int wd;
uint32_t mask;
uint32_t cookie;
uint32_t len;
char name []; // <- should be the same as with __flexarray
}
// the #includes
};
%ignore inotify_event
// the %includes
不幸的是,错误仍然存在,我需要这个结构,因为其他重要的功能,如 inotifytools_next_event
return 某种 cptr
我不知道如何用 C# 处理。
我认为忽略基本上只会从包装代码中删除名为 inotify_event
的每个声明,但似乎在触发 %ignore 之前验证了 %includes。
有没有办法在我的包装代码中正确创建 inotify_event
?
编辑::最新的 swig 版本也不起作用
SWIG 不理解很多特定于编译器的东西,例如 Windows 上的 __cdecl
和 __stdcall
,但是如果您查看 Lib\windows.i
SWIG 安装,您会看到预处理器用于删除它们,例如#define __cdecl
.
我没有办法验证这一点,但您可以通过以下方法将未知的 SWIG 编译器选项转换为更标准的声明:
%module mymodule
%{
// included normally here
#include "/usr/includes/sys/inotify.h"
#include "/usr/includes/inotifywait/inotifytools.h"
};
#define __flexarray [] // turn "char name __flexarray;" into "char name[];"
%include "/usr/includes/sys/inotify.h"
%include "/usr/includes/inotifywait/inotifytools.h"
Mark Tolonens 解决方案确实解决了我最初的问题,但出现了语法错误等其他问题。 分别弹出不是因为 Mark Tolonens 的建议破坏了某些东西,而是因为它解决了第一个问题,而 SWIG 只是偶然发现了下一个问题。
经过一番挖掘后,我添加了以下 header 这解决了我所有的问题。
%module mymodule
%{
#include "/usr/includes/sys/inotify.h"
#include "/usr/includes/inotifywait/inotifytools.h"
};
%include "/usr/includes/sys/cdefs.h" // <- add this line here
%include "/usr/includes/sys/inotify.h"
%include "/usr/includes/inotifywait/inotifytools.h"
通过这一行,SWIG 为 inotify_event
生成了一个 c# class,一些快速测试证实了它的工作。
或者您可以自己进行封送处理,但是您必须处理 c# 等中的内存分配。