我想用Rust语言调用C库"mysql.h"

Tak*_*tsu 11 c rust

我正在尝试从防锈代码连接到mysql.我试过这些步骤.

    我用c编写了代码mysql.h,并在下面命令.
    
     $ gcc -shared mysqlrust.c -o libmysqlrust.so  $(mysql_config --cflags) $(mysql_config --libs)   $(mysql_config --cflags)
     $ cp libmysqlrust.so /usr/local/lib/rustc/i686-unknown-linux-gnu/lib/
    
    Run Code Online (Sandbox Code Playgroud) 我写了Rust代码libmysqlrust.so.

但我无法想办法使用C型结构" MYSQL"," MYSQL_RES"," MYSQL_ROW".请告诉我如何使用锈蚀代码的c型结构.

brs*_*son 17

目前还没有任何方法可以从C结构中自动创建Rust类型定义.在这些情况下,有几种方法可以继续.不知道MySQL API,我不能确切地说你应该做什么,但这里有一些选择.

1)完全将它们视为不透明的指针.

这是在最好的情况,并依赖于C API一向以结构为指针,有其自身的构造函数和析构函数,并提供任何你需要的结构内访问存取功能.在这些情况下,您只需定义type MYSQL = ctypes::void并仅将其用作不安全指针*MYSQL.有时最简单的方法是编写自己的C包装器来填补空白并使这种情况成为可能.

其余的场景都涉及重新定义Rust数据结构,其结构与C结构相同.锈试图奠定了其数据结构的方式,兼容C(尽管并不总是成功还),所以经常可以创建一个生锈的记录或枚举与C结构的大小,对齐和布局你关心.您将需要确保使用类型core::ctypes,因为它们被定义为匹配各种常见的C类型.

请注意,该ctypes模块将很快消失,以支持更全面的libc兼容性模块.

2)定义部分正确的Rust记录.

如果API提供构造函数和析构函数,但您仍然需要访问结构的某些字段,那么您可以定义足够的结构来获取您关注的字段,忽略正确的大小和对齐等内容.例如type MSQL = { filler1: ctypes::int, ..., connector_fd: *ctypes::char }.您可以停止在您关心的最后一个字段定义结构,因为您有一个C函数可以在堆上使用正确的大小和对齐方式分配它.在Rust代码中,您始终使用不安全的指针来引用它:let mysql: *MYSQL = mysqlrust::create_mysql();

3)定义正确大小和对齐的Rust记录,而不关心内容.

如果您没有构造函数/析构函数,或者需要将结构存储在堆栈上,但是您具有操作结构内容的访问器函数,那么您需要使用正确的大小和对齐来定义Rust记录.要做到这一点,只需添加类型的字段uint(总是指针大小)或元组uint,直到两个C sizeofcore::sys::size_of同意大小.u8如果大小不是指针大小的倍数,则使用s 填充.获得正确的对齐是一个更神秘的过程,但通过使用uint字段,您通常会得到一个可用的对齐(可能 - 我真的不知道该语句的准确程度).

我建议添加测试以进行健全性检查Rust和C是否同意尺寸以防止未来破损.

3)实际上重新定义整个C结构.

对于大型结构来说,这是一个非常可怕的情况,理论上它是可能的,但我认为没有人为一个像它一样大的结构做过MYSQL.如果可以,我会避免它.最终会有一个基于铿锵声的工具来自动完成.

以下是与C结构互操作的一些示例:

https://github.com/jdm/rust-socket/blob/master/socket.rs - 这将重新定义各种套接字结构,为它不关心的字段添加占位符.请注意,它u8用于填充,但我认为uint更有可能产生正确的对齐方式.

https://github.com/erickt/rust-zmq/blob/master/zmq.rs

https://github.com/pcwalton/rust-spidermonkey - 这个演示了一个有点复杂的API互操作.