You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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.

Troubleshooting Undefined Function Errors with SBCL + CFFI

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-hello works, but clean-this triggers a CFFI:LOAD-FOREIGN-LIBRARY-ERROR with 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_this has no syntax errors in your C code.
  • Re-run the compile/archive commands to ensure the object file with clean_this is 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 (not g++) 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:

  1. Recompile your C library.
  2. Restart SBCL (to ensure the old library isn’t cached).
  3. Reload your Lisp code and test clean-this again.

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:01:14