How to create a nim dll and call it from c#
Asked Answered
A

2

11

I have read almost every example I could find via google, and couldn't accomplish the simplest task creating a dll (windows) from nim

Could anyone explain it step by step?

I am using the nim IDE - aporia to produce the code.

Does building a dll require the use of the command line? I guess there's a workaround.

using aporia IDE \ command line, how can one achive the same result as done by compiling code below to a dll:

extern "C" __declspec(dllexport) int __stdcall return_multiply(int num1, int num2)
{
    return num1 * num2;
}

that code as you probably know could be called from c#

Actinism answered 26/10, 2015 at 14:27 Comment(3)
Are you trying to create a DLL from the NIM IDE? Are you trying to call NUM DLL functions from C#? Are you trying to do both of these things? It's hard to tell from what you have written.Crank
@Crank thanks for the edit, you might aswell go all the way translate it : mission - >to (be able) call a nim proc entry in a dll. steps to be taken : one needs to create a dll. <---Actinism
I am no windows user. But did you check out #32839821 ? I guess avoiding the command line is possible with a config.nim file in the same folder as your source. I have no step by step intro though and would also not know how to call it from c# at all.Ansilma
K
8

Steps in a nutshell:

  1. Define your proc using the pragmas {.stdcall,exportc,dynlib.}
  2. Compile with --app:lib

Remember that you can always inspect the generated C code to see what is going on. So, let's start with a file test.nim containing:

proc return_multiply(num1, num2: int): int {.stdcall,exportc,dynlib.} =
  num1 * num2

Compiling this with nim c --app:lib -d:release test.nim produces the DLL along with this code (in the nimcache folder):

N_LIB_EXPORT N_STDCALL(NI, return_multiply)(NI num1, NI num2) {
        NI result;
        result = 0;
        result = (NI)(num1 * num2);
        return result;
}

You can lookup these macros in nimbase.h. For instance N_LIB_EXPORT is defined as follows for Windows:

#  ifdef __cplusplus
#    define N_LIB_EXPORT  extern "C" __declspec(dllexport)
#  else
#    define N_LIB_EXPORT  extern __declspec(dllexport)
#  endif
#  define N_LIB_IMPORT  extern __declspec(dllimport)

Overall, you will end up with exactly the function signature you have given.

If you do not want to compile by using the command line, you have to figure out which Aporia settings enables --app:lib.

Katydid answered 27/10, 2015 at 8:21 Comment(1)
thanks bluenot10, everything is 1=1 to what you have described above, dll found copied to the c# exe folder and... i was about to say that there's a problem as i first tried x86 but when compiled x64 every thing is fine! i guess nim default compiles to x64 And there's -switch for x86Actinism
O
1

By the way, take a look at this thread from the Nim forum for a likely reason why your 32 bit version wasn't working.

http://forum.nim-lang.org/t/1721

The short version is that MSVC does name mangling on stdcall functions on 32 bit platforms unless you take steps to override that (such as creating a .DEF file to define the function names).

Octennial answered 2/1, 2016 at 7:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.