I'm trying to get dynlib to work, but it just segfaults, and I think it has something to do with my casting, but I wouldn't know how to do it otherwise. My code:
main.nim:
import dynlib when ismainmodule: var handle:TLibHandle = LoadLib("./libraries/libmylib.dylib") var func_ptr:ptr (proc()) = cast[ptr (proc())](handle.SymAddr("MyFunc")) func_ptr[]()
proc MyFunc() {.exportc.} =
echo "Hello, World!"
all: main libraries/libmylib.dylib
main: main.nim
nimrod c main.nim
libraries/libmylib.dylib
nimrod c --app:lib libraries/libmylib.dylib
No stack traceback available
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
import dynlib
type
TDynFunc = (proc())
when ismainmodule:
var handle:TLibHandle = LoadLib("./libraries/libmylib.dylib")
var func:TDynFunc = cast[TDynFunc](handle.SymAddr("MyFunc")) #this is what causes the error
func()
The error is quite cryptic:
Error: execution of an external program failed; rerun with --parallelBuild:1 to see the error message
***/nimcache/main.c:470:55: error: member
reference base type 'TMP159' (aka 'void (*)(void *)') is not a structure
or union
asgnRef((void**) &func_95019.ClEnv, ((TMP159) (LOC2)).ClEnv);
~~~~~~~~~~~~~~~~~^~~~~~
***/nimcache/main.c:471:38: error: member
reference base type 'TMP159' (aka 'void (*)(void *)') is not a structure
or union
func_95019.ClPrc = ((TMP159) (LOC2)).ClPrc;
EDIT 2: I assumed the problem was that C wouldn't compile function pointers to void(void) functions, So I added changed the type to proc(int), but now the compiler just segfaults itself
EDIT 3: Running the compiler with LLDB shows that the error takes place here:
#.... * thread #1: tid = 0x1cb259, 0x0000000100088bda nimrod`procparamtyperel_398589 + 58, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x8) frame #0: 0x0000000100088bda nimrod`procparamtyperel_398589 + 58 nimrod`procparamtyperel_398589 + 58: -> 0x100088bda: movq 0x8(%rax), %rcx 0x100088bde: movq %rbx, %r8 0x100088be1: callq 0x10008ff00 ; generatetypeinstance_316455 0x100088be6: movq %rax, %rbx (lldb) thread backtrace * thread #1: tid = 0x1cb259, 0x0000000100088bda nimrod`procparamtyperel_398589 + 58, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x8) * frame #0: 0x0000000100088bda nimrod`procparamtyperel_398589 + 58 frame #1: 0x0000000100088d76 nimrod`proctyperel_398672 + 246 frame #2: 0x0000000100087963 nimrod`typerel_397434 + 2515 frame #3: 0x000000010008a087 nimrod`paramtypesmatchaux_402589 + 167 frame #4: 0x000000010008acbb nimrod`paramtypesmatch_403214 + 75 frame #5: 0x00000001000a253e nimrod`fitnode_477051 + 126 frame #6: 0x00000001000ba4be nimrod`semvarorlet_504957 + 606 frame #7: 0x000000010009a07e nimrod`semexpr_477007 + 2750 frame #8: 0x00000001000b9bd4 nimrod`semstmtlist_512105 + 148 frame #9: 0x0000000100099920 nimrod`semexpr_477007 + 864 frame #10: 0x000000010009bb6b nimrod`semwhen_477867 + 251 frame #11: 0x000000010009a00d nimrod`semexpr_477007 + 2637 frame #12: 0x00000001000bfb5a nimrod`semstmtandgenerategenerics_527793 + 26 frame #13: 0x00000001000bfe42 nimrod`myprocess_527894 + 50 frame #14: 0x00000001000c94c5 nimrod`processmodule_283059 + 1333 frame #15: 0x00000001000019e6 nimrod`compilemodule_597776 + 246 frame #16: 0x00000001000f2c42 nimrod`commandcompiletoc_599268 + 82 frame #17: 0x00000001000f41cd nimrod`maincommand_600027 + 2701 frame #18: 0x000000010011e172 nimrod`handlecmdline_602607 + 882 frame #19: 0x000000010011e7d3 nimrod`nimrodInit + 19 frame #20: 0x000000010011e7b9 nimrod`NimMainInner + 9 frame #21: 0x000000010011e8a2 nimrod`main + 98 frame #22: 0x00007fff9b5245c9 libdyld.dylib`start + 1 frame #23: 0x00007fff9b5245c9 libdyld.dylib`start + 1
I need to use the dynlib module, as the name of the library or even the number of libraries to load isn't known at compile time. I indeed fixed the syntax, and used the dynlib and exportc pragma's
What do you mean by a "calling convention"?
import dynlib
type
DynFunc = proc (x: int) {.nimcall.}
var handle: LibHandle = loadLib("./libraries/libmylib.dylib")
var fun: DynFunc = cast[DynFunc](handle.symAddr("MyFunc"))
fun(2)
$ objdump main -x|grep getplugindl 0000000000401eb4 g F .text 00000000000000c3 getplugindl_136217 $ objdump modules/plugin/libplugin.so -x|grep getplugindl 000000000000b73d g F .text 00000000000000cc getplugindl_136217