Skip to content

Instantly share code, notes, and snippets.

@garlic0x1
Last active May 23, 2024 19:28
Show Gist options
  • Save garlic0x1/9c3e13aca11c0a103136d919030e3c5e to your computer and use it in GitHub Desktop.
Save garlic0x1/9c3e13aca11c0a103136d919030e3c5e to your computer and use it in GitHub Desktop.
CFFI passing structs by value

I am trying to return a struct by value from a C function, and then pass it by value to another C function using cffi-libffi.

Here are the relevant functions and structure with links to the definitions in the header file:

(use-foreign-library "libtree-sitter.so")

;; https://github.com/tree-sitter/tree-sitter/blob/master/lib/include/tree_sitter/api.h#L99
(defcstruct ts-node
  (context :uint32 :count 4)
  (id :pointer)
  (tree :pointer))

;; https://github.com/tree-sitter/tree-sitter/blob/master/lib/include/tree_sitter/api.h#L380
(defcfun "ts_tree_root_node" (:struct ts-node)
  (tree :pointer))

;; https://github.com/tree-sitter/tree-sitter/blob/master/lib/include/tree_sitter/api.h#L445
(defcfun "ts_node_type" :string
  (node (:struct ts-node)))

What I want to do:

(ts-node-type (ts-tree-root-node tree))

The error I get

There is no applicable method for the generic function
  #<STANDARD-GENERIC-FUNCTION CFFI::TRANSLATE-AGGREGATE-TO-FOREIGN (2)>
when called with arguments
  (#.(SB-SYS:INT-SAP #X7EF2DEBFFFD0)
   #.(SB-SYS:INT-SAP #X7EF2DEBFFFD8)
   #<CFFI::FOREIGN-TYPEDEF :UINT32>).
   [Condition of type SB-PCL::NO-APPLICABLE-METHOD-ERROR]

You can recreate the error using the system at https://github.com/garlic0x1/cl-treesitter.git

;; load the C language grammar
(use-foreign-library "libtree-sitter-c.so")
(defcfun "tree_sitter_c" :pointer)

(let* ((parser (ts-parser-new))
       (language (tree-sitter-c)))
  (ts-parser-set-language parser language)
  (let* ((parsed (ts-parser-parse-string parser (cffi:null-pointer) "1+1;" 4))
         (root (ts-tree-root-node parsed)))
    (print root)
    (ts-node-type root)))

The value printed is

(TREE #.(SB-SYS:INT-SAP #X7EF2D0009EB0) ID #.(SB-SYS:INT-SAP #X7EF2D0009EB0) CONTEXT
 #.(SB-SYS:INT-SAP #X7EF2DDFFFFD8))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment