已知限制
由于仓颉语言的表达能力有限,目前 cjbind
有以下限制:
Bitfield
仓颉没有提供原生的位域支持,因此 cjbind
无法直接生成位域的绑定代码。在遇到位域时,cjbind
会把位域当作不透明类型处理。
有计划使用 VArray
来模拟位域,但目前还没有实现。
Union
仓颉没有提供原生的联合体支持,因此 cjbind
无法直接生成联合体的绑定代码。在遇到联合体时,cjbind
会把联合体当作不透明类型处理。
有计划使用 VArray
来模拟联合体,但目前还没有实现。
宏
仓颉目前没有合适的表达式解析库,因此无法直接计算宏的值。在遇到宏时,cjbind
会跳过整个 #define
。
有计划加入对于简单的字符串和数字宏的支持,但目前还没有实现。
不透明类型
cjbind
会尝试为不透明类型生成绑定代码,同时为其附加一个总是抛出异常的构造函数,但是用户仍然可能使用 zeroValue
来创建结构体的实例。不透明类型的内存布局并不总是保证正确,因此使用不透明类型时需要特别小心,通常不应该在仓颉侧进行内存分配,而是持有 C 侧返回的指针。
内存对齐
仓颉没有提供对齐控制的语法,因此 cjbind
会使用 C 默认的对齐方式。如果 C 代码中使用了 #pragma pack
或者 __attribute__((packed))
等方式来控制对齐,cjbind
生成的绑定代码可能会出现问题。可以在 Issue#1618 中追踪这个问题的进展。
柔性数组成员(Flexible Array Members)
仓颉不支持柔性数组成员,因此 cjbind
会跳过包含柔性数组成员的结构体。
调用约定
cjbind
会尝试根据 C 代码中的函数签名推断调用约定,但是可能会出现错误。如果你发现绑定代码中的函数签名不正确,应该手动修改绑定代码。
由于仓颉文档对于 STDCALL
调用约定描述不清晰,因此当前生成的调用约定总是 CDECL
。可以在 Issue#1595 中追踪这个问题的进展。