Currently, I have this in a init.nim file :
var CreateNS*: proc(name: cstring):cint{.cdecl.}
type Ts = object
t_CreateNS*: proc(name: cstring):cint{.cdecl.}
var tPtr{.importc: "t_Ptr", header: "my1.h".} : ptr Ts
proc tInitS(v: cstring): cstring{.cdecl, importc: "t_InitS", header: "my2.h".}
proc InitS*(v: cstring): cstring{.cdecl.} =
let init = tInitS(v)
CreateNS = tPtr.t_CreateNS
return init
My main.nim file :
proc Init(): cint {.exportc, dynlib.} =
if InitS("1.0") == nil:
return 0
# Call function declared in init.nim
let ns = CreateNS("foo")
# do something ...
return 1
To declare CreateNS in nim.init file, do I have to use a global variable ?
How can I avoid rewriting the arguments a second time, one in my global variable CreateNS and the other in the properties of my type Ts ?
Not sure whether I fully understand the problem, but if you are trying to define a proc (method), which operates on Ts object instances, you don't do that within the type but just define a proc, which takes a Ts as the first argument.
https://nim-lang.org/docs/tut2.html#object-oriented-programming-method-call-syntax
ok if you didn't understand it was because my question wasn't clear.
proc InitS*(v: cstring): cstring{.cdecl.} =
let init = tInitS(v)
CreateNS = tPtr.t_CreateNS
# ^^^
return init
To call this tPtr.t_CreateNS , I have to declare this global variable CreateNS ? is there another solution ?my1.h:54:7: error: expected ';' before 'int'
my1.h:58:7: error: expected ';' before 'const'
I've also tried to create a type, I like the idea (I don't know if it's possible) like this :
type myproc = proc(name: cstring):cint{.cdecl.}
var CreateNS*: myproc
type Ts = object
t_CreateNS*: myproc
No compilation problems, but I have a seg fault when I load my xxx.dll. Now that I've made a little more progress, I'd like to know if I can simplify it further, still with the aim of avoiding using a global variable and code duplication.
Finally, I've managed to make my code work by declaring a type :
type myproc = proc(name: cstring):cint{.cdecl.}
var CreateNS*: myproc
type Ts = object
t_CreateNS: myproc
proc InitS*(v: cstring): cstring{.cdecl.} =
CreateNS = tPtr.t_CreateNS
return "do something"
Instead of using this var CreateNS, I want to create a template or a procedure so that I can call it up later in my code, instead of setting it in my procedure InitS. I'd like to create a template like this :
# I'm not sure if we can create a template like this...
template CreateNS*: myproc = tPtr.t_CreateNS
But I have this error when I call it :
Error: type mismatch
Expression: CreateNS("foo")
[1] "foo": string
Expected one of (first mismatch at [position]):
[1] template CreateNS(): myproc
extra argument given
I need a little help to find out if this is possible.You could either do:
template CreateNS(x: cstring)*: myproc = tPtr.t_CreateNS(x)
Or you have to first call the template to get the function and then call it:
CreateNs()("foo")
Thanks @PMunch, I had an error in your template :
Error: invalid indentation; an export marker '*' follows the declared identifier
I think it was a typo. I've rewritten it like this :
template CreateNS*(x: cstring): myproc = tPtr.t_CreateNS(x)
Now I have errors, but from my header file :C:\dev\include\my1.h:54:7: error: expected ';' before 'int'
C:\dev\include\my1.h:58:7: error: expected ';' before 'const'
I called my template as you would call a procedure, I hope it's like that (I'm not too familiar with templates ).
Except for my header file errors.
Do I also have to declare argument(s) in my template CreateNS ?
I'd like to avoid it (removed this (x: cstring)) because I've already declared it in my type myproc , but I don't know if it's possible.