# Finding the path of a loaded module

**URL:** <https://racket.discourse.group/t/finding-the-path-of-a-loaded-module/4122>\
**Category:** General\
**Created:** [February 22, 2026, 6:55pm UTC](https://racket.discourse.group/t/finding-the-path-of-a-loaded-module/4122 "2026-02-22T18:55:37Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![hnmdijkema](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/hnmdijkema/32/2629_2.png) [@hnmdijkema](https://racket.discourse.group/u/hnmdijkema)\
**Post date:** [February 22, 2026, 6:55pm UTC](https://racket.discourse.group/t/finding-the-path-of-a-loaded-module/4122/1 "2026-02-22T18:55:37Z")

</div>

Suppose I want to load a dynamic link library, contained in a racket module. How would I determine where the loaded module can be found?

I'd want to do something like this from an FFI module

```scheme
(define-ffi-definer define-lib
  (ffi-lib "./lib/library.so"))

```

And hopefully the library.so is then loaded from "lib" subdirectory of the current module directory.

---

<div class="post-metadata">

**Author:** ![nealburns5](https://avatars.discourse-cdn.com/v4/letter/n/35a633/32.png) [@nealburns5](https://racket.discourse.group/u/nealburns5)\
**Post date:** [February 22, 2026, 8:58pm UTC](https://racket.discourse.group/t/finding-the-path-of-a-loaded-module/4122/2 "2026-02-22T20:58:55Z")

</div>

What you're looking for may be in here: [6.1 Module Basics](https://docs.racket-lang.org/guide/module-basics.html#(part._.Library_.Collections)).

([find-collects-dir](https://docs.racket-lang.org/raco/dirs.html#%28def._%28%28lib._setup%2Fdirs..rkt%29._find-collects-dir%29%29)) ; is the main collection directory

([find-user-collects-dir](https://docs.racket-lang.org/raco/dirs.html#%28def._%28%28lib._setup%2Fdirs..rkt%29._find-user-collects-dir%29%29)) ; is the user directory

(get-collects-search-dirs) ; returns a list of multiple module search paths

It's not very helpful that racket calls these "collects", which you would never think to search for.

Neal

---

<div class="post-metadata">

**Author:** ![hnmdijkema](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/hnmdijkema/32/2629_2.png) [@hnmdijkema](https://racket.discourse.group/u/hnmdijkema)\
**Post date:** [February 22, 2026, 10:20pm UTC](https://racket.discourse.group/t/finding-the-path-of-a-loaded-module/4122/3 "2026-02-22T22:20:10Z")

</div>

Actually, I found the answer:

```scheme
(define-runtime-path libao-async-path "./lib/libao-play-async")

(define-ffi-definer define-libao-async
  (ffi-lib libao-async-path '("0" #f)
           #:get-lib-dirs (λ ()
                            (let ((sp (cons (build-path ".") (get-lib-search-dirs))))
                              ;(displayln sp)
                              sp))
           #:fail (λ () (error "Cannot load libao-play-async"))
           ))

```

So 'define-runtime-path' seems to do the job.

I have a binding to libao, but `ao_play` seems to block the thread it is working in.  
I tried using the new parallel threads of racket, but it somehow still blocks, leaving drracket almost unusable and generating a lot of ticks, because the samples are fed to slow, so I eventually created an extra library (not my preference) that I can feed music samples an that are played in a different thread (using real C pthreads).

See code at: [hans/racket-sound: Racket libao FFI binding - racket-sound - GitEA bij dijkewijk](https://git.dijkewijk.nl/hans/racket-sound)

---

<div class="post-metadata">

**Author:** ![LiberalArtist](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/liberalartist/32/151_2.png) [@LiberalArtist](https://racket.discourse.group/u/LiberalArtist)\
**Post date:** [February 22, 2026, 11:44pm UTC](https://racket.discourse.group/t/finding-the-path-of-a-loaded-module/4122/4 "2026-02-22T23:44:36Z")

</div>

Using `define-runtime-path` is the right starting point. If you use it, you should not need to also use the `#:get-lib-dirs` argument (and including the current directory at runtime there can be dangerous!).

A potential enhancement can be to instead use:

```scheme
(define-runtime-path libao-async-path
  '(so "libao-play-async" ("0" #f)))

```

and add this to your existing `info.rkt` file:

```scheme
#lang info
;; ... add to existing content ...
(define install-platform #rx"^x86_64-linux(?:-natipkg)?$") ; or whatever is relevant
(define copy-foreign-libs '("libao/lib/libao-play-async.so.0"))

```

The [`copy-foreign-libs`](https://docs.racket-lang.org/raco/setup-info.html#%28idx._%28gentag._26._%28lib._scribblings%2Fraco%2Fraco..scrbl%29%29%29) directive tells `raco setup` to install the foreign library into an appropriate place, including graceful handling for system linker directives like `$ORIGIN` and `@loader_path`. The `so` variant of `define-runtime-path` finds libraries that were potentially installed that way, and also records them as dependencies for the executable builder. Altogether, the architecture prepares you for potentially building the foreign library for additional platforms in the future, at which point you may want to organize your packaging so that only code for the relevant platform has to be installed.

* * *

> [@hnmdijkema](#):
>
> I have a binding to libao, but `ao_play` seems to block the thread it is working in.  
> I tried using the new parallel threads of racket, but it somehow still blocks, leaving drracket almost unusable and generating a lot of ticks, because the samples are fed to slow, so I eventually created an extra library (not my preference) that I can feed music samples an that are played in a different thread (using real C pthreads).

This part is surprising, and it's probably worth a look by someone who is more up-to-date than I am on OS parallelism support. As I first guess, have you checked if the unsafe threads from [`ffi/unsafe/os-thread`](https://docs.racket-lang.org/foreign/Operating_System_Threads.html) have the same problems?

---

<div class="post-metadata">

**Author:** ![hnmdijkema](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/hnmdijkema/32/2629_2.png) [@hnmdijkema](https://racket.discourse.group/u/hnmdijkema)\
**Post date:** [February 23, 2026, 2:19pm UTC](https://racket.discourse.group/t/finding-the-path-of-a-loaded-module/4122/5 "2026-02-23T14:19:11Z")

</div>

Hi Philip, `ffi/unsafe/os-thread` does the trick. Tested it today in Windows. It's delicate to implement, but I got it working quite easy. This saves me a custom shared library. Thanks a lot!

---

<div class="post-metadata">

**Author:** ![hnmdijkema](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/hnmdijkema/32/2629_2.png) [@hnmdijkema](https://racket.discourse.group/u/hnmdijkema)\
**Post date:** [February 24, 2026, 3:01pm UTC](https://racket.discourse.group/t/finding-the-path-of-a-loaded-module/4122/6 "2026-02-24T15:01:33Z")

</div>

Unfortunately this way of working, although better in performance, still is too slow; still generating 'ticks' in the audio. So I had to go back to my little C shared library that processes the audio for me in a operating system thread.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [February 24, 2026, 3:32pm UTC](https://racket.discourse.group/t/finding-the-path-of-a-loaded-module/4122/7 "2026-02-24T15:32:00Z")

</div>

I wonder if it helps running your program in a terminal instead of inside DrRacket?  
DrRacket adds helpful debug instructions to your program, so potentially things could run faster in the terminal.

---

<div class="post-metadata">

**Author:** ![hnmdijkema](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/hnmdijkema/32/2629_2.png) [@hnmdijkema](https://racket.discourse.group/u/hnmdijkema)\
**Post date:** [February 26, 2026, 11:32am UTC](https://racket.discourse.group/t/finding-the-path-of-a-loaded-module/4122/8 "2026-02-26T11:32:42Z")

</div>

Looks like running it using 'racket' on the terminal instead of inside DrRacket works better. However, it seems to trigger memory corruption problems, which I don't get with DrRacket (maybe related with [this](https://racket.discourse.group/t/racket-crashes-with-invalid-memory-reference/2206))?

I also don't get this problem on Windows.

For me it feels like the 'garbage collector' kicks in every now and then. I.e. regarding the ‘audio clicks’.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [February 26, 2026, 11:45am UTC](https://racket.discourse.group/t/finding-the-path-of-a-loaded-module/4122/9 "2026-02-26T11:45:50Z")

</div>

When I experience this - it is almost always, because I have made a mistake in the FFI bindings.

---

<div class="post-metadata">

**Author:** ![hnmdijkema](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/hnmdijkema/32/2629_2.png) [@hnmdijkema](https://racket.discourse.group/u/hnmdijkema)\
**Post date:** [February 26, 2026, 12:03pm UTC](https://racket.discourse.group/t/finding-the-path-of-a-loaded-module/4122/10 "2026-02-26T12:03:05Z")

</div>

That’s 3 or 4 FFI’s 🤔 that come together in my program. Is it possible to track the problem down to an FFI call? The program doesn’t crash.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [February 26, 2026, 12:27pm UTC](https://racket.discourse.group/t/finding-the-path-of-a-loaded-module/4122/11 "2026-02-26T12:27:48Z")

</div>

I wanted to make an issue on the repo, but do to that I need to login.  
How do I create a user?

---

<div class="post-metadata">

**Author:** ![hnmdijkema](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/hnmdijkema/32/2629_2.png) [@hnmdijkema](https://racket.discourse.group/u/hnmdijkema)\
**Post date:** [February 26, 2026, 12:51pm UTC](https://racket.discourse.group/t/finding-the-path-of-a-loaded-module/4122/12 "2026-02-26T12:51:13Z")

</div>

Thanks for the message. I've enabled the possibility. It's possible to register now.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [February 26, 2026, 1:07pm UTC](https://racket.discourse.group/t/finding-the-path-of-a-loaded-module/4122/13 "2026-02-26T13:07:29Z")

</div>

I have made a new user `soegaard`.  
However, the site tells me it sends an activation email.  
Nothing appears in Gmail - I also checked the spam folder.

Oh - and important to note - login requires that the account is activated.

---

<div class="post-metadata">

**Author:** ![hnmdijkema](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/hnmdijkema/32/2629_2.png) [@hnmdijkema](https://racket.discourse.group/u/hnmdijkema)\
**Post date:** [February 26, 2026, 1:20pm UTC](https://racket.discourse.group/t/finding-the-path-of-a-loaded-module/4122/14 "2026-02-26T13:20:13Z")

</div>

Yeah. It is my local gitea repo, didn't think I needed to allow other users. I probably need to do som mail configuration. For now I've activated your account manually.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [February 26, 2026, 1:29pm UTC](https://racket.discourse.group/t/finding-the-path-of-a-loaded-module/4122/15 "2026-02-26T13:29:29Z")

</div>

Thanks. The activation worked.
