I'm looking at: http://build.nimrod-lang.org/docs/manual.html#dynlib-pragma-for-import I'm attempting to get the following SDL2 tutorial working in nimrod: http://www.willusher.io/sdl2%20tutorials/2013/08/17/lesson-1-hello-world/
I've come up with the following for pulling in SDL2:
proc SDL_Init(inp:int): int {.cdecl, dynlib:"SDL2.dll",importc.}
My question is about the C value for SDL_INIT_EVERYTHING. I would like to pull that symbol into nimrod automatically if I could, in a type-safe manner if at all possible (I realize that implies C-style macro reading/expansion).
How would you typically solve this in nimrod? I'm going to guess by popping open the C source and setting up the values manually in nimrod.
Also, is it possible to dump an entire C interface into nimrod, or only a function at a time?
Extremely new to nimrod, so if any of this appears silly and naive, it probably is :) I just need to know what I'm missing.
I believe there is an importc trick you can do wrapping the define into another one which looks like a function call, but you can also use the emit pragma to generate your own C code:
proc ACCESS_FILE(): cstring =
{.emit:"""result = __FILE__;""".}
when isMainModule:
echo "Compiled from ", ACCESS_FILE()
There is no dump in nimrod, but you can use the c2nim tool to transform C code and headers into nimrod.
Also, note that there is an sdl wrapper which you can use, or install babel on your system and type babel install sdl2 to get a different wrapper. This should avoid you the pain of wrapping sdl yourself.
Babel is the nimrod version of ruby gems I take it.
I'll definitely take a look at that sdl2 wrapper, thanks for that, but I still want to keep at this for the learning experience.
It isn't clear to me what the emit solving here, can you explain?
Also, for the c2nim tool, are you able to specify what to transform? meaning, only #defines, only functions, only specific functions, etc? I've looked at the following (http://nimrod-lang.org/c2nim.html) for more details, but I'm not seeing specifics with respect to c2nim.
c2nim will typically fail to work if you just point it at some random header in /usr/include. It tries to translate #defines to nimrod consts and #ifdefs to nimrod whens. You have to go through and remove platform specific attributes, dllimport/export macros, calling convention macros, and so on.
if you replace a #define in the c header with #def it tells c2nim to treat it as text replacement.
another option (that I have not tried) is to actually run the c preprocessor on the file in question before you give it to c2nim
When wrapping a C library it is best to just translate all the user-facing data structures to nimrod objects and then import all the functions with the {.importc.} pragma.
for c2nim you usually make a local copy of the header you want to translate then remove the parts that c2nim has trouble with. If this fails you can sometimes make a copy of the manpage for the lib you want to wrap and munge it enough that c2nim can process the definitions.
Nimrod is compiled to C source which you can investigate in the nimcache generated directory. The emit pragma simply bypasses the Nimrod level and directly writes whatever you specified in the final C output. In this case I wanted to show how you would access the C level __FILE__ define: you create a proc which returns a cstring and assign the define to that, so you can grab it at the Nimrod level.
Maybe too contrived. I don't know what the macro you mention does, but I guess it's just a function like macro. You could in theory write something like this to wrap it:
proc sdl_init_everything() =
{.emit:"SDL_INIT_EVERYTHING();".}
In this case I presume the macro doesn't return anything, or you are not interested in its result, so it is not necessary to grab it. Also, try putting a spelling mistake there and run the Nimrod compiler to you get an idea of where in nimcache that proc gets exported to.
emit is dangerous since you are on your own with regards to the sanity of the generated code. These examples would definitely not work for the javascript backend.
Could you also emit assembler using the C facilities to do such? I'm just curious because doing terrible things can be fun sometimes, lol :)
Is there documentation on the specifics of c2nim, for example the #define to #def thing mentioned above?
Internally does nimrod attempt to inline the C?.
http://build.nimrod-lang.org/docs/c2nim.html <-- the docs for c2nim
I guess you could use emit to do assembly but it would be much better to just use the built in asm statement http://build.nimrod-lang.org/docs/manual.html#assembler-statement