在SBCL中使用CFFI调用返回指针的函数时遇未定义函数错误
Hey there, let's work through those undefined function errors you're running into with SBCL and CFFI— I’ve dealt with similar headaches before, so I know how frustrating this can be! Let’s break down your scenario, diagnose the issues, and fix them step by step.
Your Scenario Recap
You started by following the CFFI manual and hit an undefined curl_easy_init error. You switched to a custom C test case, where some functions work (like your basic test function) but others (e.g., clean_this) still throw "undefined symbol" errors. Let’s start by laying out the code and setup you mentioned:
Your C Code
#include <stdio.h> // This function works in Lisp void say_hello() { printf("Hello from C!\n"); } // This function throws an undefined error void clean_this() { printf("Cleaning up resources!\n"); }
How You Compiled the C File
# Compile to object file gcc -c myutils.c -o myutils.o # Create static library ar rcs libmyutils.a myutils.o # Or shared library (if you tried this) # gcc -shared -fPIC myutils.c -o libmyutils.so
Your Common Lisp Code
(ql:quickload :cffi) (defpackage :cffi-test (:use :cl :cffi)) (in-package :cffi-test) ;; Define the foreign library (define-foreign-library myutils (:unix (:or "libmyutils.so" "libmyutils.a")) (:windows "myutils.dll") (:default "myutils")) (use-foreign-library myutils) ;; Bindings for C functions (defcfun ("say_hello" say-hello) :void) (defcfun ("clean_this" clean-this) :void) ;; Test calls (say-hello) ; Runs fine, prints the message (clean-this) ; Throws: "The function 'clean_this' is undefined."
Expected vs. Actual Results
- Expected: Both functions execute and print their messages.
- Actual:
say-helloworks, butclean-thistriggers aCFFI:LOAD-FOREIGN-LIBRARY-ERRORwith an undefined symbol message.
Common Causes & Fixes
1. Did clean_this Actually Make It Into Your Library?
First, verify that the clean_this symbol exists in your compiled library. Sometimes typos, compilation errors, or linker flags can exclude functions accidentally.
Run this command to check for the symbol:
# For shared libraries (.so) nm -D libmyutils.so | grep clean_this # For static libraries (.a) nm libmyutils.a | grep clean_this
If you don’t see a line with T clean_this (the T means the symbol is in the code/text section), recompile your C file:
- Double-check that
clean_thishas no syntax errors in your C code. - Re-run the compile/archive commands to ensure the object file with
clean_thisis included in the library.
2. Accidental C++ Name Mangling
If you used g++ instead of gcc to compile your C code, C++ will mangle the function name (e.g., clean_this becomes _Z9clean_thisv), which CFFI can’t match.
Fix:
- Use
gcc(notg++) to compile your C code. - If you must use C++, wrap your function declarations in
extern "C"to disable mangling:#ifdef __cplusplus extern "C" { #endif void clean_this() { printf("Cleaning up resources!\n"); } #ifdef __cplusplus } #endif
3. Static Library Linker Limitations
Static libraries only link symbols that are referenced at compile time. If SBCL’s linker doesn’t see a reference to clean_this when loading the library, it might skip including it.
Fix:
When defining your foreign library in CFFI, add linker flags to force including all symbols from the static library:
(define-foreign-library myutils (:unix (:or "libmyutils.so" (:default "libmyutils.a" :linkage-options '("-Wl,--whole-archive" "libmyutils.a" "-Wl,--no-whole-archive")))) (:default "myutils"))
For shared libraries, this isn’t an issue— just make sure the library is in your LD_LIBRARY_PATH (Unix) so SBCL can find it.
4. Typos in CFFI Bindings
Double-check that the string inside defcfun exactly matches your C function name (it’s case-sensitive!). For example, if your C function is clean_this, don’t write "cleanThis" in the binding.
5. Fixing the Original curl_easy_init Issue
For the libcurl problem, make sure you’re linking against the correct library and that libcurl is installed on your system:
(define-foreign-library libcurl (:unix "libcurl.so") (:windows "libcurl.dll") (:default "libcurl")) (use-foreign-library libcurl) (defcfun ("curl_easy_init" curl-easy-init) :pointer)
On Debian/Ubuntu, install libcurl with:
sudo apt install libcurl4-gnutls-dev
Test the Fix
After making these changes:
- Recompile your C library.
- Restart SBCL (to ensure the old library isn’t cached).
- Reload your Lisp code and test
clean-thisagain.
If it still fails, re-run the nm command to confirm the symbol is present, and check the full error message for additional clues— sometimes SBCL will tell you exactly which library it’s looking in.
内容的提问来源于stack exchange,提问作者Makketronix

