Skip to content

Commit 6e0b417

Browse files
committed
chore(nim-bindings): replace dynlib dlopen with plain importc
The dynlib pragma hard-coded a library path and resolved it via dlopen() at runtime, preventing static linking and forcing a specific load-time path. Using bare {.importc.} lets consumers choose: link liblibchat dynamically at link time (--passL:-llibchat) or link it statically into their binary.
1 parent 960bb19 commit 6e0b417

1 file changed

Lines changed: 11 additions & 35 deletions

File tree

nim-bindings/src/bindings.nim

Lines changed: 11 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,5 @@
11
# Nim FFI bindings for libchat conversations library
22

3-
import std/[os]
4-
5-
# Dynamic library path resolution
6-
# Can be overridden at compile time with -d:CONVERSATIONS_LIB:"path/to/lib"
7-
# Or at runtime via LIBCHAT_LIB environment variable
8-
when defined(macosx):
9-
const DEFAULT_LIB_NAME = "liblibchat.dylib"
10-
elif defined(linux):
11-
const DEFAULT_LIB_NAME = "liblibchat.so"
12-
elif defined(windows):
13-
const DEFAULT_LIB_NAME = "libchat.dll"
14-
else:
15-
const DEFAULT_LIB_NAME = "libchat"
16-
17-
# Try to find the library relative to the source file location at compile time
18-
const
19-
thisDir = currentSourcePath().parentDir()
20-
projectRoot = thisDir.parentDir().parentDir()
21-
releaseLibPath = projectRoot / "target" / "release" / DEFAULT_LIB_NAME
22-
debugLibPath = projectRoot / "target" / "debug" / DEFAULT_LIB_NAME
23-
24-
# Default to release path, can be overridden with -d:CONVERSATIONS_LIB:"..."
25-
const CONVERSATIONS_LIB* {.strdefine.} = releaseLibPath
26-
273
# Error codes (must match Rust ErrorCode enum)
284
const
295
ErrNone* = 0'i32
@@ -97,23 +73,23 @@ type
9773

9874
## Creates a new libchat Context
9975
## Returns: Opaque handle to the context. Must be freed with destroy_context()
100-
proc create_context*(name: ReprCString): ContextHandle {.importc, dynlib: CONVERSATIONS_LIB.}
76+
proc create_context*(name: ReprCString): ContextHandle {.importc.}
10177

10278
## Returns the friendly name of the context's identity
10379
## The result must be freed by the caller (repr_c::String ownership transfers)
104-
proc installation_name*(ctx: ContextHandle): ReprCString {.importc, dynlib: CONVERSATIONS_LIB.}
80+
proc installation_name*(ctx: ContextHandle): ReprCString {.importc.}
10581

10682
## Destroys a context and frees its memory
10783
## - handle must be a valid pointer from create_context()
10884
## - handle must not be used after this call
109-
proc destroy_context*(ctx: ContextHandle) {.importc, dynlib: CONVERSATIONS_LIB.}
85+
proc destroy_context*(ctx: ContextHandle) {.importc.}
11086

11187
## Creates an intro bundle for sharing with other users
11288
## Returns: CreateIntroResult struct - check error_code field (0 = success, negative = error)
11389
## The result must be freed with destroy_intro_result()
11490
proc create_intro_bundle*(
11591
ctx: ContextHandle,
116-
): CreateIntroResult {.importc, dynlib: CONVERSATIONS_LIB.}
92+
): CreateIntroResult {.importc.}
11793

11894
## Creates a new private conversation
11995
## Returns: NewConvoResult struct - check error_code field (0 = success, negative = error)
@@ -122,7 +98,7 @@ proc create_new_private_convo*(
12298
ctx: ContextHandle,
12399
bundle: SliceUint8,
124100
content: SliceUint8,
125-
): NewConvoResult {.importc, dynlib: CONVERSATIONS_LIB.}
101+
): NewConvoResult {.importc.}
126102

127103
## Sends content to an existing conversation
128104
## Returns: SendContentResult struct - check error_code field (0 = success, negative = error)
@@ -131,7 +107,7 @@ proc send_content*(
131107
ctx: ContextHandle,
132108
convo_id: ReprCString,
133109
content: SliceUint8,
134-
): SendContentResult {.importc, dynlib: CONVERSATIONS_LIB.}
110+
): SendContentResult {.importc.}
135111

136112
## Handles an incoming payload
137113
## Returns: HandlePayloadResult struct - check error_code field (0 = success, negative = error)
@@ -141,19 +117,19 @@ proc send_content*(
141117
proc handle_payload*(
142118
ctx: ContextHandle,
143119
payload: SliceUint8,
144-
): HandlePayloadResult {.importc, dynlib: CONVERSATIONS_LIB.}
120+
): HandlePayloadResult {.importc.}
145121

146122
## Free the result from create_intro_bundle
147-
proc destroy_intro_result*(result: CreateIntroResult) {.importc, dynlib: CONVERSATIONS_LIB.}
123+
proc destroy_intro_result*(result: CreateIntroResult) {.importc.}
148124

149125
## Free the result from create_new_private_convo
150-
proc destroy_convo_result*(result: NewConvoResult) {.importc, dynlib: CONVERSATIONS_LIB.}
126+
proc destroy_convo_result*(result: NewConvoResult) {.importc.}
151127

152128
## Free the result from send_content
153-
proc destroy_send_content_result*(result: SendContentResult) {.importc, dynlib: CONVERSATIONS_LIB.}
129+
proc destroy_send_content_result*(result: SendContentResult) {.importc.}
154130

155131
## Free the result from handle_payload
156-
proc destroy_handle_payload_result*(result: HandlePayloadResult) {.importc, dynlib: CONVERSATIONS_LIB.}
132+
proc destroy_handle_payload_result*(result: HandlePayloadResult) {.importc.}
157133

158134
# ============================================================================
159135
# Helper functions

0 commit comments

Comments
 (0)