From: Sam S. <sd...@gn...> - 2001-06-06 15:38:57
|
> * In message <00e701c0ee78$091f8240$4381fb18@CX417245D> > * On the subject of "Re: clisp ffi" > * Sent on Wed, 6 Jun 2001 04:01:27 -0700 > * Honorable "Eric de Groot" <er...@er...> writes: > > Ok, cool, the only problem I have at the moment is the function pointer. > For the lisp I have: > > (error_handler (c-ptr (c-function))) > > which gives me: > > void * ERROR_HANDLER (); > > but I need: > > void (*ERROR_HANDLER)(); I thought that in ANSI C void (*f) (); and void f (); were interchangeable. please try this patch and see if it helps _and_ does not break any other code. Index: foreign1.lisp =================================================================== RCS file: /cvsroot/clisp/clisp/src/foreign1.lisp,v retrieving revision 1.7 diff -u -w -b -u -b -w -i -B -r1.7 foreign1.lisp --- foreign1.lisp 2001/06/03 04:04:35 1.7 +++ foreign1.lisp 2001/06/06 15:31:03 @@ -599,7 +599,7 @@ (to-c-typedecl (svref c-type 1) (format nil "(~A)[~D]" name (svref c-type 2)))) ((c-ptr c-ptr-null c-array-ptr) - (to-c-typedecl (svref c-type 1) (format nil "* ~A" name))) + (to-c-typedecl (svref c-type 1) (format nil "(* ~A)" name))) (c-function (to-c-typedecl (svref c-type 1) (format nil "~A ()" name))) (t (error (ENGLISH "illegal foreign data type ~S") [PS. no clisp support via private e-mail - please use the lists!] -- Sam Steingold (http://www.podval.org/~sds) Support Israel's right to defend herself! <http://www.i-charity.com/go/israel> Read what the Arab leaders say to their people on <http://www.memri.org/> A poet who reads his verse in public may have other nasty habits. |
From: Eric de G. <er...@er...> - 2001-06-06 20:47:36
|
Sam- Ok, I tried the patch you sent me, but now I get parens around everything I use c-ptr with. Only function pointers need the parens. Maybee this will require a new case, like C-FUNCTIONPTR or something? I also get parens around the def of mysql_init now like: extern struct t2248 { /* ....... */ } (* (mysql_init)()); from: (def-c-call-out mysql_init (:arguments (mysql (c-ptr st_mysql))) (:return-type (c-ptr st_mysql))) Also, you can see above, it's still not doing the arguments, I just get mysql_init(). Thanks. -Eric de Groot mailto:er...@er... |
From: Sam S. <sd...@gn...> - 2001-06-06 22:14:47
|
> * In message <005c01c0eeca$1eae2e70$4381fb18@CX417245D> > * On the subject of "Re: [clisp-list] Re: clisp ffi" > * Sent on Wed, 6 Jun 2001 13:48:45 -0700 > * Honorable "Eric de Groot" <er...@er...> writes: > > Ok, I tried the patch you sent me, but now I get parens around > everything I use c-ptr with. Only function pointers need the parens. please send an example and then remove the patch. ;-) also, since in C int (*f) (); and int f() are equivalent, you can just write (error_handler (c-function)) > (def-c-call-out mysql_init (:arguments (mysql (c-ptr st_mysql))) > (:return-type (c-ptr st_mysql))) > > Also, you can see above, it's still not doing the arguments, I just > get mysql_init(). this should not be a problem as C does not require full prototypes. -- Sam Steingold (http://www.podval.org/~sds) Support Israel's right to defend herself! <http://www.i-charity.com/go/israel> Read what the Arab leaders say to their people on <http://www.memri.org/> Are you smart enough to use Lisp? |
From: Eric de G. <er...@er...> - 2001-06-07 00:25:21
|
Sam- in C, int (*f)(); and int f(); are not equivalent. I'm trying to declare a function pointer as a member of a structure, like: struct mystruct { int (*f)(); }; you cannot write: struct mystruct { int f(); } this would work in c++ if mystruct::f() {} was defined elsewhere, but even then it's still not a function pointer. Excuse me if you already know this, but just to make sure we are both clear on function pointers.. with function pointers you can do this: struct mystruct { int (*f)(); }; int a() { printf("aaaa"); } int b() { printf("bbbb"); } struct mystruct mystructinst; mystructinst.f = &a; (*mystructinst.f)(); mystructinst.f = &b; (*mystructinst.f)(); which will result in a call to a(), then b() and print out: aaaabbbb. the declation of the function pointer itself has to look like <returntype> (*<pointername>)(<args); or int (*f)(); in the above case. -Eric de Groot mailto:er...@er... > please send an example and then remove the patch. ;-) > > also, since in C > int (*f) (); > and > int f() > are equivalent, you can just write > (error_handler (c-function)) > > > (def-c-call-out mysql_init (:arguments (mysql (c-ptr st_mysql))) > > (:return-type (c-ptr st_mysql))) > > > > Also, you can see above, it's still not doing the arguments, I just > > get mysql_init(). > > this should not be a problem as C does not require full prototypes. > > -- > Sam Steingold (http://www.podval.org/~sds) > Support Israel's right to defend herself! <http://www.i-charity.com/go/israel> > Read what the Arab leaders say to their people on <http://www.memri.org/> > Are you smart enough to use Lisp? > > |
From: Sam S. <sd...@gn...> - 2001-06-07 17:55:22
|
> * In message <011401c0eee8$9312f390$4381fb18@CX417245D> > * On the subject of "Re: [clisp-list] Re: clisp ffi" > * Sent on Wed, 6 Jun 2001 17:27:02 -0700 > * Honorable "Eric de Groot" <er...@er...> writes: > > in C, int (*f)(); and int f(); are not equivalent. year - I got it mixed up with the fact that you can write, say, "sin" instead of "&sin" for the address of the functions "double sin(double)". please apply this patch to foreign1.lisp and try again. your help is greatly appreciated. @@ -601,7 +546,17 @@ ((c-ptr c-ptr-null c-array-ptr) (to-c-typedecl (svref c-type 1) (format nil "* ~A" name))) (c-function - (to-c-typedecl (svref c-type 1) (format nil "~A ()" name))) + (to-c-typedecl (svref c-type 1) + (format nil "(~A) (~{~A~^,~})" name + (do ((ii 0 (+ 2 ii)) ret + (arg (gensym "arg"))) + ((= (length (svref c-type 2)) ii) + (nreverse ret)) + (push (to-c-typedecl + (svref (svref c-type 2) ii) + (format nil "~a_~d" + arg (/ ii 2))) + ret))))) (t (error (ENGLISH "illegal foreign data type ~S") c-type)))))))) -- Sam Steingold (http://www.podval.org/~sds) Support Israel's right to defend herself! <http://www.i-charity.com/go/israel> Read what the Arab leaders say to their people on <http://www.memri.org/> God had a deadline, so He wrote it all in Lisp. |
From: Eric de G. <er...@er...> - 2001-06-07 20:00:50
|
Sam- Ok thanks, that last patch worked. I can do everything without having to manually edit any files. Excellent. Do you have any ideas about my other questions? If I define all the c structs in lisp and use them as the types in my def-c-call-outs rather than just using c-pointer, I cannot do the following: (let ((conn (MYSQL::mysql_init nil))) (MYSQL::mysql_connect conn "localhost" "root" "") (MYSQL::mysql_get_server_info conn)) NIL I have to do: (let ((conn (MYSQL::mysql_init nil))) (let ((conn (MYSQL::mysql_connect conn "localhost" "root" ""))) (MYSQL::mysql_get_server_info conn))) "3.22.32-log" Here are the def-c-callouts using the structs used in the first example: (def-c-call-out mysql_init (:arguments (mysql (c-ptr-null st_mysql))) (:return-type (c-ptr-null st_mysql))) (def-c-call-out mysql_get_server_info (:arguments (mysql (c-ptr-null st_mysql))) (:return-type c-string)) (def-c-call-out mysql_connect (:arguments (mysql (c-ptr-null st_mysql)) (host c-string) (user c-string) (passwd c-string)) (:return-type (c-ptr-null st_mysql))) and heres how I redefined them to use c-pointer, which works, as seen in the above second example: (def-c-call-out mysql_init (:arguments (mysql (c-ptr-null nil))) (:return-type c-pointer)) (def-c-call-out mysql_get_server_info (:arguments (mysql c-pointer)) (:return-type c-string)) (def-c-call-out mysql_connect (:arguments (mysql c-pointer) (host c-string) (user c-string) (passwd c-string)) (:return-type c-pointer)) How can I get the pointers to work in the second example? -Eric de Groot mailto:er...@er... |
From: Eric de G. <er...@er...> - 2001-06-08 05:17:46
|
Ok, I wrote clisp bindings for libmysqlclient. With the following test code: (let ((conn (MYSQL::mysql_init nil))) (MYSQL::mysql_connect conn "localhost" "root" "") (MYSQL::mysql_get_server_info conn) (MYSQL::mysql_select_db conn "mysql") (MYSQL::mysql_query conn "select * from user") (let ((result (MYSQL::mysql_use_result conn))) (loop (let ((row (MYSQL::mysql_fetch_row result))) (when (eq row nil) (return t)) (print row))) (MYSQL::mysql_free_result result)) (MYSQL::mysql_close conn)) I get: *** - handle_fault error2 ! address = 0xFE0000 not in [0x2027A000,0x20337404) ! SIGSEGV cannot be cured. Fault address = 0xFE0000. Segmentation fault but, if I run just this part of the code first, followed by the entire thing: [1]> (let ((conn (MYSQL::eric_mysql_init))) (MYSQL::mysql_connect conn "localhost" "root" "") (MYSQL::mysql_get_server_info conn) (MYSQL::mysql_select_db conn "mysql") (MYSQL::mysql_query conn "select * from user")) 0 [2]> (let ((conn (MYSQL::mysql_init nil))) (MYSQL::mysql_connect conn "localhost" "root" "") (MYSQL::mysql_get_server_info conn) (MYSQL::mysql_select_db conn "mysql") (MYSQL::mysql_query conn "select * from user") (let ((result (MYSQL::mysql_use_result conn))) (loop (let ((row (MYSQL::mysql_fetch_row result))) (when (eq row nil) (return t)) (print row))) (MYSQL::mysql_free_result result)) (MYSQL::mysql_close conn)) #("localhost" "root" "" "Y" "Y" "Y" "Y" "Y" "Y" "Y" "Y" "Y" "Y" "Y" "Y" "Y" "Y" "") #("cx417245-c" "root" "" "Y" "Y" "Y" "Y" "Y" "Y" "Y" "Y" "Y" "Y" "Y" "Y" "Y" "Y" "") #("localhost" "" "" "N" "N" "N" "N" "N" "N" "N" "N" "N" "N" "N" "N" "N" "N" "") #("cx417245-c" "" "" "N" "N" "N" "N" "N" "N" "N" "N" "N" "N" "N" "N" "N" "N" "Y") [3]> it works! but then if I past it a couple more times it eventually seg faults anyway. Any idea what might be causing this?? again, you can see my files at http://www.ericdegroot.com/clisp/ this is on: debian 2.2 (2.2.19pre17) GNU CLISP 2.26.1 (released 2001-06-04) (built 3200899615) (memory 3201017859) Thanks! I'm so close.. -eric |
From: Eric de G. <er...@er...> - 2001-06-07 11:13:59
|
Sam- Ok, I was having more problems with the c code in callmysql.c generated by: ./clisp-link add-module-set mysql base base+mysql It kept telling me the structs generated were incompatible with the structs in mysql.h. I checked the sizeof() of everything, and everything matched up perfectly between the structs in mysql.h and the structs clisp generated.. So i finally just deleted all the prototypes and structures clisp generates and let it use the prototypes and structs from mysql.h, works great. Why couldn't you just do this in the first place instead of having it generate duplicate prototypes and structures? Anyways, with that I was able to finally talk to mysql!! very exciting after all this;) I'm having another problem now with the following though: (let ((conn (MYSQL::mysql_init nil))) (MYSQL::mysql_connect conn "localhost" "root" "") (MYSQL::mysql_get_server_info conn)) gives me: NIL (let ((conn (MYSQL::mysql_init nil))) (let ((conn (MYSQL::mysql_connect conn "localhost" "root" ""))) (MYSQL::mysql_get_server_info conn))) gives me exactly what i want: "3.22.32-log" in the first example, why is conn not being modified by mysql_connect? The second example works because mysql_connect both modifies the st_mysql structure you pass it, and on a successful connection the the database server, also returns it, otherwise returns null on failure. In C, just doing: mysql_connect( conn, "localhost", "root", NULL ); would be fine. The only thing I would use the returned struct for was error checking: if ( mysql_connect( conn, "localhost", "root", NULL ) == NULL ) { /* error handling.. */ } With CLISP, when you pass a var to a c-ptr argument, do you have to do something special to allow it to be modified by the function you passed it to? Thanks. -Eric de Groot mailto:er...@er... |
From: Eric de G. <er...@er...> - 2001-06-07 11:42:16
|
Sam- Ok, I was just studying the lisp from the postgresql bindings in the modules directory some more and it just clicked. Through the entire they whoever wrote just used c-pointer, rather than defining all the structs and everything. This will work for my mysql bindings aswell because mysql has accessor functions for all the data needed from the structures. I don't need the details. Damn, I wish I noticed this earlier! Anyways, changing everything to either c-pointer or (c-ptr-null nil) works!! so far atleast;) -Eric de Groot mailto:er...@er... |
From: Eric de G. <er...@er...> - 2001-06-07 12:31:21
|
More questions! I'm having a problem with number type conversions, I have the following two C functions: int myintfun() { return 11; } unsigned long long myulonglongfun() { return 11; } For the FFI lisp I have, respectively: (def-c-call-out myintfun (:return-type int)) (def-c-call-out myulonglongfun (:return-type uint64)) 'unsigned long long' is 8 bytes unsigned. uint64 is the only unsigned 8 byte type you have listed in the FFI docs. Anyways, after loading clisp up with bindings for these, calling them gives me: (MYSTUFF::myintfun) 11 (MYSTUFF::myulonglongfun) 52 (MYSTUFF::myulonglongfun) 0 it just gives a trash random number. Any ideas why?? Thanks. -Eric de Groot mailto:er...@er... |