[racket] Problems wrapping the RabbitMQ C client library using the ffi
You need
(define-amqp amqp_queue_declare
(_fun _amqp-connection-state-pointer
_amqp_channel_t _pointer _int _int _int _int _pointer
-> _amqp_queue_declare_ok_t-pointer))
Using `_amqp_queue_declare_ok_t' corresponds to the return type
`_amqp_queue_declare_ok_t', while `_amqp_queue_declare_ok_t-pointer'
corresponds to `_amqp_queue_declare_ok_t*'.
At Sun, 26 Aug 2012 18:10:18 +0100, Juan Garcia wrote:
> Hi,
>
> I'm having a problem wrapping the Rabbit MQ C client
> library (https://github.com/alanxz/rabbitmq-c) using the ffi. My
> problem is with the amqp_queue_declare function. The C
> declaration is:
>
> amqp_queue_declare_ok_t *
> amqp_queue_declare(amqp_connection_state_t state,
> amqp_channel_t channel,
> amqp_bytes_t queue,
> amqp_boolean_t passive,
> amqp_boolean_t durable,
> amqp_boolean_t exclusive,
> amqp_boolean_t auto_delete,
> amqp_table_t arguments);
>
> It seems to run successfully when wrapped to return an opaque
> pointer:
>
> (define _amqp-queue-declare-ok-pointer (_cpointer 'QUEUE-DECLARE-OK))
>
> (define-amqp amqp_queue_declare
> (_fun _amqp-connection-state-pointer
> _amqp_channel_t _pointer _int _int _int _int _pointer
> -> _amqp-queue-declare-ok-pointer))
>
> > #<cpointer:QUEUE-DECLARE-OK>
>
> Wrapping it to return a cstruct pointer fails with a SEGV.
>
> > SIGSEGV MAPERR si_code 1 fault on addr (nil)
>
> The wrapping code for the c structs is as follows:
>
> (define _size_t _uint32)
> (define _amqp_channel_t _uint16)
>
> (define-cstruct _amqp_bytes_t
> ([len _size_t]
> [bytes _pointer]))
>
> ;; c definition of amqp_bytes_t is:
> ;; typedef struct amqp_bytes_t_ {
> ;; size_t len;
> ;; void *bytes;
> ;; } amqp_bytes_t;
>
> (define-cstruct _amqp_queue_declare_ok_t
> ([queue _amqp_bytes_t]
> [message_count _uint32]
> [consumer_count _uint32]))
>
> ;; typedef struct amqp_queue_declare_ok_t_ {
> ;; amqp_bytes_t queue;
> ;; uint32_t message_count;
> ;; uint32_t consumer_count;
> ;; } amqp_queue_declare_ok_t;
>
> (define-amqp amqp_queue_declare
> (_fun _amqp-connection-state-pointer
> _amqp_channel_t _pointer _int _int _int _int _pointer
> -> _amqp_queue_declare_ok_t))
>
> Any ideas what I'm doing wrong here?
>
> The full code so far is below:
>
> #lang racket/base
>
> (require ffi/unsafe
> ffi/unsafe/define)
>
> (define lib-rabbit-mq (ffi-lib "librabbitmq"))
> (define-ffi-definer define-amqp lib-rabbit-mq)
>
> ;; C types
>
> (define _size_t _uint32)
> (define _amqp_channel_t _uint16)
>
> (define-cstruct _amqp_bytes_t
> ([len _size_t]
> [bytes _pointer]))
>
> (define-cstruct _amqp_queue_declare_ok_t
> ([queue _amqp_bytes_t]
> [message_count _uint32]
> [consumer_count _uint32]))
>
> (define-cstruct _amqp_method_t
> ([id _uint32]
> [decoded _pointer]))
>
> (define-cstruct _amqp_rpc_reply_t
> ([reply_type _int]
> [reply _amqp_method_t]
> [library_error _int]))
>
> (define _amqp-connection-state-pointer (_cpointer 'CONNECTION-STATE))
> (define _amqp-channel-open_ok-pointer (_cpointer 'CHANNEL-OPEN-OK))
>
> ;; C functions
>
> (define-amqp amqp_error_string (_fun _int -> _string))
> (define-amqp amqp_get_rpc_reply (_fun _amqp-connection-state-pointer ->
> _amqp_rpc_reply_t))
>
> (define-amqp amqp_new_connection (_fun -> _amqp-connection-state-pointer))
> (define-amqp amqp_open_socket (_fun _string _int -> _int))
> (define-amqp amqp_set_sockfd (_fun _amqp-connection-state-pointer
> _int -> _int))
> (define-amqp amqp_login (_fun _amqp-connection-state-pointer
> _string _int _int _int _int _string _string ->
> _amqp_rpc_reply_t))
> (define-amqp amqp_channel_open (_fun _amqp-connection-state-pointer
> _amqp_channel_t ->
> _amqp-channel-open_ok-pointer))
>
> ;; *** THIS DOES NOT WORK
>
> (define-amqp amqp_queue_declare
> (_fun _amqp-connection-state-pointer
> _amqp_channel_t _pointer _int _int _int _int _pointer
> -> _amqp_queue_declare_ok_t))
>
> ;; *** THIS SEEMS TO WORK
>
> (define _amqp-queue-declare-ok-pointer (_cpointer 'QUEUE-DECLARE-OK))
>
> (define-amqp amqp_queue_declare
> (_fun _amqp-connection-state-pointer
> _amqp_channel_t _pointer _int _int _int _int _pointer
> -> _amqp-queue-declare-ok-pointer))
>
> ;; main
>
> (define conn (amqp_new_connection))
> (define sockfd (amqp_open_socket "localhost" 5672))
> (when (< sockfd 0) (amqp_error_string (* -1 sockfd)))
> (amqp_set_sockfd conn sockfd)
> (define *AMQP_SASL_METHOD_PLAIN* 0)
> (define resp (amqp_login conn "/" 0 131072 0
> *AMQP_SASL_METHOD_PLAIN* "user" "pwd"))
>
> (amqp_channel_open conn 1)
> (amqp_queue_declare conn 1 #f 0 0 0 1 #f)
> ____________________
> Racket Users list:
> http://lists.racket-lang.org/users