From: N. R. <ra...@mr...> - 2009-06-15 06:14:22
|
I am trying to convert a libxml2 tutorial from C to the CLISP FFI. There is a basic libxml2 function called "xmlParseFile" which parses an XML file, and returns a pointer to a C-struct representing the document tree. I am able to use the FFI to construct the struct from an XML file, but all the slots of the structure have value NIL. I was wondering if people have seen this type of problem earlier, and would appreciate any suggestions. To avoid a long message to the mailing list, I've put up the Lisp file at http://www.retrotexts.net/tmp/foreign.lisp Most of the libxml2 objects used there are defined in <libxml2/libxml/tree.h>, http://www.xmlsoft.org/html/libxml-tree.html Thanks, Raghavendra. -- N. Raghavendra <ra...@mr...> | http://www.retrotexts.net/ Harish-Chandra Research Institute | http://www.mri.ernet.in/ See message headers for contact and OpenPGP information. |
From: Sam S. <sd...@gn...> - 2009-06-15 14:46:14
|
N. Raghavendra wrote: > I am trying to convert a libxml2 tutorial from C to the CLISP FFI. > There is a basic libxml2 function called "xmlParseFile" which parses an > XML file, and returns a pointer to a C-struct representing the document > tree. I am able to use the FFI to construct the struct from an XML > file, but all the slots of the structure have value NIL. I was > wondering if people have seen this type of problem earlier, and would > appreciate any suggestions. I get this error: [1]> (foo "foo.xml") *** - FFI::%SLOT: foreign variable #<FOREIGN-VARIABLE #x0000000001065640> of type #(C-STRUCT -XML-NODE NIL #() #<COMPILED-FUNCTION MAKE--XML-NODE>) has no component with name NAME this is because you have (c-pointer (c-struct -xml-node)) before defining -xml-node and it is interpreted to mean a struct without fields (not #() in the type descriptor in the error message above). note that the CL idiom for a "very internal symbol" (if that's what you mean) is to start the name with "$", not "-". > To avoid a long message to the mailing list, I've put up the Lisp file > at http://www.retrotexts.net/tmp/foreign.lisp thanks. Do you plan to interface to all of libxml2? |
From: N. R. <ra...@mr...> - 2009-06-15 21:05:10
|
At 2009-06-15T10:45:55-04:00, Sam Steingold wrote: > I get this error: > > [1]> (foo "foo.xml") > > *** - FFI::%SLOT: foreign variable #<FOREIGN-VARIABLE #x0000000001065640> of > type #(C-STRUCT -XML-NODE NIL #() #<COMPILED-FUNCTION MAKE--XML-NODE>) > has no component with name NAME Actually, I sent that message after trying the following, which is even more basic than that function: CL-USER> (asdf:operate 'asdf:load-op 'libxml-clisp) ; loading system definition from /home/raghu... into #<PACKAGE ASDF0> ; [snip] 0 errors, 0 warnings NIL CL-USER> (in-package "NET.RETROTEXTS.LIBXML-CLISP.FOREIGN") #<PACKAGE NET.RETROTEXTS.LIBXML-CLISP.FOREIGN> FOREIGN> (defvar *doc* (foreign-value (xml-parse-file "foo.xml"))) *DOC* FOREIGN> *doc* #S($XML-DOC :$PRIVATE NIL :TYPE NIL :NAME NIL :CHILDREN NIL :LAST NIL :PARENT NIL :NEXT NIL :PREV NIL :DOC NIL :COMPRESSION NIL :STANDALONE NIL :INT-SUBSET NIL :EXT-SUBSET NIL :OLD-NS NIL :VERSION NIL :ENCODING NIL :IDS NIL :REFS NIL :URL NIL :CHARSET NIL :DICT NIL :PSVI NIL) FOREIGN> (slot-value *doc* 'name) NIL FOREIGN> > this is because you have (c-pointer (c-struct -xml-node)) before > defining -xml-node and it is interpreted to mean a struct without > fields (not #() in the type descriptor in the error message above). -xml-node is my attempt at a direct translation of _xmlNode in <libxml2/libxml/tree.h>, which is defined there as a self-referential structure: typedef struct _xmlNode xmlNode; typedef xmlNode *xmlNodePtr; struct _xmlNode { void *_private; xmlElementType type; const xmlChar *name; struct _xmlNode *children; struct _xmlNode *last; /* [snip] */ unsigned short extra; }; I translated this to (def-c-type xml-node (c-struct -xml-node)) (def-c-type xml-node-ptr (c-pointer xml-node)) (def-c-struct -xmlNode (-private c-pointer) (type xml-element-type) (name (c-pointer xml-char)) (children (c-pointer (c-struct -xml-node))) (last (c-pointer (c-struct -xml-node))) ;; [snip] (extra ushort)) Since `(c-pointer (c-struct -xml-node))' in the above seems to be the problem, what should I use in its place? > note that the CL idiom for a "very internal symbol" (if that's what you mean) > is to start the name with "$", not "-". Thanks, I have substituted "$" for the initial "-" in internal names. > Do you plan to interface to all of libxml2? Because of my inexperience, I was planning to make an interface only to the parts of libxml2 that I wanted to use. However, with teachers like you and Kaz Kylheku to point out the right direction when I am stuck, I can certainly try making a more general FFI to the library. Regards, -- N. Raghavendra <ra...@mr...> | http://www.retrotexts.net/ Harish-Chandra Research Institute | http://www.mri.ernet.in/ See message headers for contact and OpenPGP information. |
From: Sam S. <sd...@gn...> - 2009-06-15 21:15:46
|
N. Raghavendra wrote: > > -xml-node is my attempt at a direct translation of _xmlNode in > <libxml2/libxml/tree.h>, which is defined there as a self-referential > structure: > > typedef struct _xmlNode xmlNode; > typedef xmlNode *xmlNodePtr; > struct _xmlNode { > void *_private; > xmlElementType type; > const xmlChar *name; > struct _xmlNode *children; > struct _xmlNode *last; > /* [snip] */ > unsigned short extra; > }; > > I translated this to > > (def-c-type xml-node (c-struct -xml-node)) > (def-c-type xml-node-ptr (c-pointer xml-node)) > (def-c-struct -xmlNode > (-private c-pointer) > (type xml-element-type) > (name (c-pointer xml-char)) > (children (c-pointer (c-struct -xml-node))) > (last (c-pointer (c-struct -xml-node))) > ;; [snip] > (extra ushort)) you do realize that you have both -xmlNode and -xml-node which _are_ different symbols, right? > Since `(c-pointer (c-struct -xml-node))' in the above seems to be the > problem, what should I use in its place? just plain c-pointer. you can cast it later. I hope Joerg will explain why you are getting all NILs |
From: N. R. <ra...@mr...> - 2009-06-17 06:59:07
|
At 2009-06-15T17:14:38-04:00, Sam Steingold wrote: > you do realize that you have both -xmlNode and -xml-node which _are_ > different symbols, right? Thanks, that was a silly mistake, which happened while cutting and yanking. I have made some minor progress, and the structure is getting filled now. What I did was to remove all references to structures not yet defined, and to replace `(c-pointer (c-struct -xml-node)))' with `(c-pointer -xml-node)'. I also removed the `-xml-*' private structures, so typedef struct _xmlNode xmlNode; typedef xmlNode *xmlNodePtr; struct _xmlNode { void *_private; xmlElementType type; const xmlChar *name; struct _xmlNode *children; struct _xmlNode *last; /* [snip] */ unsigned short extra; }; is translated to (def-c-struct xml-node (private c-pointer) (type xml-element-type) (name (c-pointer xml-char)) (children (c-pointer xml-node)) (last (c-pointer xml-node)) ;; [snip] (extra ushort)) (def-c-type xml-node-ptr (c-pointer xml-node)) It seems to be working now, although I have to still figure out how to manipulate the components of the structures. I have kept the new file at the same URL, http://www.retrotexts.net/tmp/foreign.lisp Unfortunately, I am going away somewhere for two weeks, and won't have any computer access in that period. I hope to take this up after my return. Thanks and regards, Raghavendra. |
From: Sam S. <sd...@gn...> - 2009-06-17 13:25:57
|
N. Raghavendra wrote: > > typedef struct _xmlNode xmlNode; > typedef xmlNode *xmlNodePtr; > struct _xmlNode { > void *_private; > xmlElementType type; > const xmlChar *name; > struct _xmlNode *children; > struct _xmlNode *last; > /* [snip] */ > unsigned short extra; > }; > > is translated to > > (def-c-struct xml-node > (private c-pointer) > (type xml-element-type) > (name (c-pointer xml-char)) > (children (c-pointer xml-node)) > (last (c-pointer xml-node)) > ;; [snip] > (extra ushort)) > > (def-c-type xml-node-ptr (c-pointer xml-node)) looks good. > It seems to be working now, although I have to still figure out how to > manipulate the components of the structures. I have kept the new file > at the same URL, http://www.retrotexts.net/tmp/foreign.lisp > > Unfortunately, I am going away somewhere for two weeks, and won't have > any computer access in that period. I hope to take this up after my > return. have a nice trip. |