Hi again -
I have the following C function definition (from RabbitMQ C client):
typedef enum amqp_response_type_enum_ { AMQP_RESPONSE_NONE = 0, AMQP_RESPONSE_NORMAL, AMQP_RESPONSE_LIBRARY_EXCEPTION, AMQP_RESPONSE_SERVER_EXCEPTION } amqp_response_type_enum;
typedef struct amqp_rpc_reply_t_ { amqp_response_type_enum reply_type; amqp_method_t reply; int library_errno; } amqp_rpc_reply_t;
/* Opaque struct. */ typedef struct amqp_connection_state_t_ *amqp_connection_state_t;
typedef enum amqp_sasl_method_enum_ { AMQP_SASL_METHOD_PLAIN = 0 } amqp_sasl_method_enum;
extern amqp_rpc_reply_t amqp_login(amqp_connection_state_t state, char const *vhost, int channel_max, int frame_max, int heartbeat, amqp_sasl_method_enum sasl_method, ...);
which I hand-translated to the following CFFI statements:
(defcenum amqp-sasl-method-enum (:AMQP-SASL-METHOD-PLAIN 0))
(defcenum amqp-response-type-enum (:AMQP-RESPONSE-NONE 0) :AMQP-RESPONSE-NORMAL :AMQP-RESPONSE-LIBRARY-EXCEPTION :AMQP-RESPONSE-SERVER-EXCEPTION)
(defcstruct amqp-rpc-reply-struct (reply-type amqp-response-type-enum) (reply amqp-method-t) (library-errno :int))
(defctype amqp-rpc-reply-t amqp-rpc-reply-struct)
(defctype amqp-connection-state-t :pointer)
(defcfun ("amqp_login" %amqp-login) amqp-rpc-reply-t (state amqp-connection-state-t) (vhost :string) (channel-max :int) (frame-max :int) (heartbeat :int) (sasl-method amqp-sasl-method-enum) &rest) ;; varargs !
You still there ? ;-) Good. Now for my "issue":
Calling the C function amqp_login function as follows:
(defparameter *hostname* "192.168.2.121") (defparameter *port* 5672) (defparameter *user* "ccag.pib") (defparameter *password* "ccag.pib") (defparameter *vhost* "/ccag/pib")
(let* ((conn (%amqp-new-connection)) (sockfd (%amqp-open-socket *hostname* *port*)))
(%amqp-login conn *vhost* 0 131072 0 :AMQP-SASL-METHOD-PLAIN :string *user* :string *password*) ...
results in the following output from the C function amqp_login (which I instrumented):
*** AMQP_LOGIN sees: -> state = 0x64034010 -> vhost = (null) -> channel_max = 131072 -> frame_max = 0 -> heartbeat = 0 -> sasl_method = 1677934672
Hmmmmmm - let's see:
vhost .........: Not good. Should be "/ccag/pib". channel_max ...: Not good. Should be 0. frame_max .....: Not good. Should be 131072. sasl_method ...: Not good. Should be 0.
What am I doing wrong here? By now I'm trying to figure this out for more than 10 hours and I am at a loss here.... Any help/ ideas really appreciated!
TIA!!! Frank
Nobody ? Really nobody ? Well, please !!
Am 18.01.2010 um 00:40 schrieb Frank Goenninger:
Hi again -
I have the following C function definition (from RabbitMQ C client):
typedef enum amqp_response_type_enum_ { AMQP_RESPONSE_NONE = 0, AMQP_RESPONSE_NORMAL, AMQP_RESPONSE_LIBRARY_EXCEPTION, AMQP_RESPONSE_SERVER_EXCEPTION } amqp_response_type_enum;
typedef struct amqp_rpc_reply_t_ { amqp_response_type_enum reply_type; amqp_method_t reply; int library_errno; } amqp_rpc_reply_t;
/* Opaque struct. */ typedef struct amqp_connection_state_t_ *amqp_connection_state_t;
typedef enum amqp_sasl_method_enum_ { AMQP_SASL_METHOD_PLAIN = 0 } amqp_sasl_method_enum;
extern amqp_rpc_reply_t amqp_login(amqp_connection_state_t state, char const *vhost, int channel_max, int frame_max, int heartbeat, amqp_sasl_method_enum sasl_method, ...);
which I hand-translated to the following CFFI statements:
(defcenum amqp-sasl-method-enum (:AMQP-SASL-METHOD-PLAIN 0))
(defcenum amqp-response-type-enum (:AMQP-RESPONSE-NONE 0) :AMQP-RESPONSE-NORMAL :AMQP-RESPONSE-LIBRARY-EXCEPTION :AMQP-RESPONSE-SERVER-EXCEPTION)
(defcstruct amqp-rpc-reply-struct (reply-type amqp-response-type-enum) (reply amqp-method-t) (library-errno :int))
(defctype amqp-rpc-reply-t amqp-rpc-reply-struct)
(defctype amqp-connection-state-t :pointer)
(defcfun ("amqp_login" %amqp-login) amqp-rpc-reply-t (state amqp-connection-state-t) (vhost :string) (channel-max :int) (frame-max :int) (heartbeat :int) (sasl-method amqp-sasl-method-enum) &rest) ;; varargs !
You still there ? ;-) Good. Now for my "issue":
Calling the C function amqp_login function as follows:
(defparameter *hostname* "192.168.2.121") (defparameter *port* 5672) (defparameter *user* "ccag.pib") (defparameter *password* "ccag.pib") (defparameter *vhost* "/ccag/pib")
(let* ((conn (%amqp-new-connection)) (sockfd (%amqp-open-socket *hostname* *port*)))
(%amqp-login conn *vhost* 0 131072 0 :AMQP-SASL-METHOD-PLAIN :string *user* :string *password*)
...
results in the following output from the C function amqp_login (which I instrumented):
*** AMQP_LOGIN sees: -> state = 0x64034010 -> vhost = (null) -> channel_max = 131072 -> frame_max = 0 -> heartbeat = 0 -> sasl_method = 1677934672
Hmmmmmm - let's see:
vhost .........: Not good. Should be "/ccag/pib". channel_max ...: Not good. Should be 0. frame_max .....: Not good. Should be 131072. sasl_method ...: Not good. Should be 0.
What am I doing wrong here? By now I'm trying to figure this out for more than 10 hours and I am at a loss here.... Any help/ ideas really appreciated!
TIA!!! Frank
cffi-devel mailing list cffi-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Nobody ? Really nobody ? Well, please !!
Patience. This is a mailing list, not instant chat. ;)
Am 18.01.2010 um 00:40 schrieb Frank Goenninger:
typedef struct amqp_connection_state_t_ *amqp_connection_state_t; extern amqp_rpc_reply_t amqp_login(amqp_connection_state_t state, char const *vhost, int channel_max, int frame_max, int heartbeat, amqp_sasl_method_enum sasl_method, ...);
which I hand-translated to the following CFFI statements: (defctype amqp-connection-state-t :pointer)
(defcfun ("amqp_login" %amqp-login) amqp-rpc-reply-t (state amqp-connection-state-t) (vhost :string) (channel-max :int) (frame-max :int) (heartbeat :int) (sasl-method amqp-sasl-method-enum) &rest) ;; varargs ! (let* ((conn (%amqp-new-connection)) (sockfd (%amqp-open-socket *hostname* *port*)))
(%amqp-login conn *vhost* 0 131072 0 :AMQP-SASL-METHOD-PLAIN :string *user* :string *password*)
*** AMQP_LOGIN sees: -> state = 0x64034010 -> vhost = (null) -> channel_max = 131072 -> frame_max = 0 -> heartbeat = 0 -> sasl_method = 1677934672
These appear to be shifted by one. If you print the value of CONN and the address of *VHOST*'s c string, which is appearing in STATE?
Running blind, I'd suggest changing your prototype to (defcfun ("amqp_login" %amqp-login) amqp-rpc-reply-t (state :pointer) (vhost :pointer) (channel-max :int) (frame-max :int) (heartbeat :int) (sasl-method amqp-sasl-method-enum) &rest) but that shouldn't make a difference.
Since you're apparently already recompiling amqp_login, would it help if you compiled a variant that didn't use varargs? i.e. hard-code two extra parameters that take normal username and password parameters after those listed above?
Its also sometimes instructive to attach gdb to your lisp when doing FFI work. I've found the following procedure to work best. Be sure to compile your library with debugging enabled (-g) for best results.
# ps ax | grep sbcl # identify a pid in the following list sbcl> set up the FFI call # gdb /path/to/sbcl gdb> attach $pid gdb> break amqp_login gdb> continue sbcl> start the FFI call gdb> backtrace gdb> frame N gdb> info locals etc. gdb> detach
Hope that helps, Daniel