summary refs log tree commit diff stats
path: root/lib/system/dyncalls.nim
diff options
context:
space:
mode:
authorjyelon <jyelon@gmail.com>2015-11-11 21:55:33 -0500
committerjyelon <jyelon@gmail.com>2015-11-11 21:55:33 -0500
commite8bc19f79c23d3bda57e2a9d1a68e653656b80a9 (patch)
treeae2bd0ab3e94d3c75a9ad1d7d7610179a56d083d /lib/system/dyncalls.nim
parentebc3438cc22c3a65425811a474fcad8d3c261c24 (diff)
downloadNim-e8bc19f79c23d3bda57e2a9d1a68e653656b80a9.tar.gz
Add 'auto-decoration' to nimGetProcAddr
Maintainers of win32 DLLs can opt to provide libraries with
'decorated' function names (Google "stdcall name decoration").  To
pull a function pointer out of one of these DLLs, you have to pass a
decorated name to getProcAddress.  This is painful for the authors
of NIM DLL wrappers - they have to pass manually-decorated strings
to "importc", but only on win32.

This commit adds auto-decoration to nimGetProcAddress.  This function
will probe the DLL for the undecorated name, and if that fails, it
will automatically add decoration and try again.  That way, the author
of the wrapper doesn't have to deal with it.
Diffstat (limited to 'lib/system/dyncalls.nim')
-rw-r--r--lib/system/dyncalls.nim7
1 files changed, 6 insertions, 1 deletions
diff --git a/lib/system/dyncalls.nim b/lib/system/dyncalls.nim
index 908aa551b..4043c8714 100644
--- a/lib/system/dyncalls.nim
+++ b/lib/system/dyncalls.nim
@@ -105,7 +105,12 @@ elif defined(windows) or defined(dos):
 
   proc nimGetProcAddr(lib: LibHandle, name: cstring): ProcAddr =
     result = getProcAddress(cast[THINSTANCE](lib), name)
-    if result == nil: procAddrError(name)
+    if result != nil: return
+    for i in countup(0, 50):
+      var decorated = "_" & $name & "@" & $(i * 4)
+      result = getProcAddress(cast[THINSTANCE](lib), cstring(decorated))
+      if result != nil: return
+    procAddrError(name)
 
 else:
   {.error: "no implementation for dyncalls".}