Closed shenlebantongying closed 7 months ago
Here is what happens in DrRacket:
When you run the program the first time, the shared library is attached to the DrRacket process. When the program is run the second time, the attached library is reused.
It would be nice if there were a way to unload and/or reload a shared library, but as far as I know there is no support for that currently [1].
A practical solution: edit the program in DrRacket, but run it in a nearby terminal.
[1] https://groups.google.com/g/racket-users/c/KRrB8XZKNxA/m/a6SJ7ztHj6UJ
It would be nice if there were a way to unload and/or reload a shared library, but as far as I know there is no support for that currently [1].
There is (relatively new) support for this through the #:custodian
argument to ffi-lib
: if you supply (current-custodian)
, the library will be unloaded, and thus can be reloaded, when DrRacket discards an old REPL and starts a new one.
Using a custodian for unloading the library creates additional requirements referred to in the docs to manage potentially invalid library references. Even if you don't intend to take on those requirements, and thus will ultimately want to supply 'place
for #:custodian
or leave the default, it can still be useful to supply #:custodian (current-custodian)
during early development, when you're trying to get library loading working properly, or if you are actively modifying the foreign code being used.
As a general caveat, though, because the FFI uses unsafe functionality, DrRacket cannot protect itself from users' buggy unsafe programs as well as it can from buggy safe programs. For example, you can easily cause a segfault, corrupt memory, or otherwise crash DrRacket using the FFI. I still find DrRacket useful for FFI development, but it is worth being extra cautious.
Glad to know what's really going on. This is much deeper than I thought.
I will try the custodian
method. If it doesn't work, I will stick with running in a terminal.
After press the
run
button, a library loaded by ffi seems to be staying around. After modifying and recompiling the library, ffi still uses the older library when pressingrun
.To reproduce:
Compile this library
Uses it in drracket.
Modify the hello.c file, change the return string and recompile
-> Press the
run
in drracket, it will output the older return string from the older version of the library.Video to demo this https://imgur.com/a/bYipZXU (quality is pretty horrible but you can see the output string isn't changed in drracket, while the output string indeed changed confirmed by invoking the racket file directly.)
System: macOS 14 Racket/CS 8.10