who lenguaje learning learn example book c rust

c - lenguaje - rust vs go



Quiero llamar a la biblioteca C "mysql.h" del lenguaje Rust (1)

Estoy tratando de conectarme a mysql desde el código de óxido. Probé estos pasos.

    1. Escribí el código c usando mysql.h , y comando debajo.

    $ 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/ 2. Escribí el código Rust, que llama a libmysqlrust.so .

Pero no pude encontrar la manera de usar la estructura tipo C " MYSQL ", " MYSQL_RES ", " MYSQL_ROW ". Por favor, muéstrame cómo usar la estructura tipo c del código de óxido.


Todavía no hay forma de crear automáticamente definiciones de tipo Rust a partir de las estructuras C. En estas situaciones, hay algunas maneras de proceder. Al no conocer la API de MySQL, no puedo decir exactamente lo que debe hacer, pero aquí hay algunas opciones.

1) Trátelos por completo como punteros opacos.

Esta es la mejor situación para estar, y depende de que la API C tome siempre la estructura como un puntero, tenga sus propias funciones de constructor y destructor, y proporcione funciones de acceso para todo lo que necesite acceder dentro de la estructura. En estos casos, simplemente define el type MYSQL = ctypes::void y solo lo usa como un puntero inseguro *MYSQL . Algunas veces, la ruta más fácil es escribir sus propios envoltorios de C para llenar los vacíos y hacer posible este escenario.

Todos los escenarios restantes implican la redefinición de una estructura de datos Rust con la misma estructura que la estructura C. Rust intenta diseñar sus estructuras de datos de una manera que sea compatible con C (aunque no siempre lo logra), por lo que a menudo es posible crear un registro o enumeración de Rust con el tamaño, la alineación y el diseño de la estructura C preocuparse. Deberá asegurarse de utilizar los tipos en core::ctypes , ya que están definidos para coincidir con varios tipos de C comunes.

Tenga en cuenta que el módulo ctypes desaparecerá pronto a favor de un módulo de compatibilidad de libc más completo.

2) Defina un registro de óxido que sea parcialmente correcto.

Si la API proporciona constructores y destructores, pero aún necesita acceso a algunos campos de la estructura, puede definir lo suficiente de la estructura para llegar a los campos que le interesan, sin tener en cuenta aspectos como el tamaño y la alineación correctos. por ejemplo, type MSQL = { filler1: ctypes::int, ..., connector_fd: *ctypes::char } . Puede dejar de definir la estructura en el último campo que le interesa ya que tiene una función C para asignarla en el montón con el tamaño y la alineación correctos. En el código de Rust, siempre te refieres a él con un puntero inseguro: let mysql: *MYSQL = mysqlrust::create_mysql();

3) Defina un registro de óxido que tenga el tamaño y la alineación correctos, sin preocuparse por el contenido.

Si no tiene funciones de constructor / destructor, o necesita almacenar la estructura en la pila, pero tiene funciones de acceso para manipular el contenido de la estructura, entonces necesita definir un registro de óxido con el tamaño y la alineación correctos. Para hacer esto, simplemente agregue los campos de tipo uint (que siempre es del tamaño de un puntero) o tuplas de uint , hasta que el tamaño de C y el core::sys::size_of en el tamaño. u8 con u8 s si el tamaño no es un múltiplo del tamaño del puntero. Obtener la alineación correcta es un proceso más místico, pero al usar los campos de uint , generalmente se terminará con una alineación utilizable (tal vez, realmente no tengo idea de qué tan precisa es esa afirmación).

Recomendaría agregar pruebas al control de cordura que Rust y C acuerden sobre el tamaño para evitar futuras roturas.

3) En realidad redefinir toda la estructura C

Esta es una situación bastante grave para grandes estructuras, y es posible en teoría, pero no creo que nadie lo haya hecho por una estructura tan grande como MYSQL . Lo evitaría si puedes. Eventualmente habrá una herramienta basada en clang para hacer esto automáticamente.

Aquí hay algunos ejemplos de interoperabilidad con estructuras C:

https://github.com/jdm/rust-socket/blob/master/socket.rs - Esto redefine varias estructuras de socket, agregando marcadores de posición para campos que no le importan. Tenga en cuenta que usa u8 para el relleno, pero creo que uint es más probable que produzca una alineación correcta.

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

https://github.com/pcwalton/rust-spidermonkey - Esto demuestra la interoperabilidad con una API algo compleja.