Skip to content

FFI undefined symbol on compile and load

I get this error when I compile and load the file (C-c C-k) in Slime:

LOAD: Could not load file #P"/home/risto/projects/cl-ffi-example/cl-ffi-example.fas" (Error: "/home/risto/projects/cl-ffi-example/cl-ffi-example.fas: undefined symbol: my_struct_string")
   [Condition of type SIMPLE-ERROR]

But when I go through and run each s-expression line by line, it works, and then compile-and-load also works fine at that point. What am I doing wrong?

My code:

cl-ffi-example.lisp

(defpackage cl-ffi-example
  (:use :cl))

(in-package :cl-ffi-example)

;; Note: First (require 'asdf), and compile file (C-c C-c), to load foreign lib

(ffi:load-foreign-library (ffi:find-foreign-library '("mylib") (uiop:getcwd)))

(ffi:def-function ("some_int" some-int) () :returning :int)
#+nil(some-int) ; 123

(ffi:def-foreign-var ("some_string" *some-string*) :cstring :default)
#+nil(progn *some-string*) ; "Hello, World!"

(ffi:def-struct my-struct (my-string :cstring) (my-int :int))

(ffi:def-foreign-var ("some_struct" *some-struct*) my-struct :default)

#+nil(ffi:get-slot-value *some-struct* 'my-struct 'my-int) ; 1234
#+nil(ffi:get-slot-value *some-struct* 'my-struct 'my-string) ; "Hello"

(ffi:def-function ("my_struct_int" my-struct-int) ((s (* my-struct))) :returning :int)

#+nil(my-struct-int *some-struct*) ; 1234

(ffi:def-function ("my_struct_string" my-struct-string) ((s (* my-struct)))
  :returning :cstring)

#+nil(my-struct-string *some-struct*) ; "Hello"

mylib.c

#include "mylib.h"

char* some_string = SOME_MACRO;
struct my_struct some_struct = { "Hello", 1234 };

const int
some_int ()
{
	return 123;
}

const int
my_struct_int (struct my_struct *s)
{
	return s->my_int;
}

const char*
my_struct_string (struct my_struct *s)
{
	return s->my_string;
}

mylib.h

#define SOME_MACRO "Hello, World!"

struct my_struct {
	char* my_string;
	int my_int;
};

extern char* some_string;
extern struct my_struct some_struct;
extern const int some_int ();
extern const int my_struct_int (struct my_struct*);
extern const char* my_struct_string (struct my_struct*);

Here's the repo.

Stats (I'm using Void Linux):

     VERSION "21.2.1"
      VCS-ID "UNKNOWN"
          OS "Linux"
  OS-VERSION "6.3.13_1"
MACHINE-TYPE "x86_64"
    FEATURES (:ASDF-PACKAGE-SYSTEM :ASDF3.1 :ASDF3 :ASDF2 :ASDF :OS-UNIX
              :NON-BASE-CHARS-EXIST-P :ASDF-UNICODE :SWANK :SERVE-EVENT :WALKER
              :CDR-1 :CDR-5 :LINUX :FORMATTER :CDR-7 :ECL-WEAK-HASH
              :LITTLE-ENDIAN :ECL-READ-WRITE-LOCK :LONG-LONG :UINT64-T
              :UINT32-T :UINT16-T :COMPLEX-FLOAT :LONG-FLOAT :UNICODE :DFFI
              :CLOS-STREAMS :CMU-FORMAT :UNIX :ECL-PDE :DLOPEN :CLOS :THREADS
              :BOEHM-GC :ANSI-CL :COMMON-LISP :FLOATING-POINT-EXCEPTIONS
              :IEEE-FLOATING-POINT :PACKAGE-LOCAL-NICKNAMES :CDR-14
              :PREFIXED-API :FFI :X86_64 :COMMON :ECL)