【问题标题】:FFI with dependencies in Racket?在 Racket 中具有依赖项的 FFI?
【发布时间】:2021-03-09 04:38:57
【问题描述】:

我为 Wiring PI 库开发了一个非常简单的 FFI,以便能够使用 Racket 控制 Raspberry Pi。

这很有效,但只涵盖了基本功能。我想扩展它以使用 libwiringPiDev.so 中的 lcd.h,这样我就可以创建一个 FFI 来控制 LCD。

通常,当你编译一个使用 LCD 的 C 文件时,你在编译时同时标记标准库和开发库:

-lwiringPi -lwiringPiDev

在我的 LCD FFI 中,我执行了以下操作:

(define-ffi-definer define-lcd
  (ffi-lib "usr/lib/libwiringPiDev.so"))

但是,当我尝试要求该球拍文件时,我遇到了:

; ffi-lib: couldn't open "/usr/lib/libwiringPiDev.so"
;   (/usr/lib/libwiringPiDev.so: undefined symbol: digitalRead) [,bt for
;   context]

digitalRead 函数存在于基础库中,但不存在于 dev 库中...如何执行“具有依赖关系的 FFI”,以便 Racket 可以正确管理这两个库以便能够找到必要的符号?

【问题讨论】:

    标签: raspberry-pi racket ffi wiringpi


    【解决方案1】:

    尝试先在全局模式下加载 libwiringPi.so,然后再加载 libwiringPiDev.so:

    (define-ffi-definer define-lcd
      (ffi-lib "/usr/lib/libwiringPi.so" #:global? #t))
    (define-ffi-definer define-lcd-dev
      (ffi-lib "/usr/lib/libwiringPiDev.so"))
    

    #:global? #t 参数对应于在对dlopen 的调用中设置RTLD_GLOBAL 标志,dlopen 的手册页(在我的 Linux 系统上)说

    RTLD_GLOBAL
    此共享对象定义的符号将可用 用于随后加载的共享对象的符号解析。

    【讨论】:

    • 感谢您的帮助。有趣的是,如果我首先需要 lcd.rkt,然后是wiringpi.rkt,它可以正常工作......但是如果我先需要wiringpi.rkt 然后lcd.rkt,我会收到“未定义符号”错误......可能造成这种情况?
    • 我可以想象这样一个场景,这些依赖关系变得更加复杂,需求的排序可能变得更加乏味。
    • 我认为这个库是非典型的,通常共享库只是链接到它们所依赖的库,而不是期望在全局命名空间中定义符号。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    • 2011-08-17
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    相关资源
    最近更新 更多