Attempting to learn how to interface a nim program with a cpp module, I tried the following files:
// twonum.h
#ifndef twonum_H
#define twonum_H
class TwoNum {
int a; int b;
public:
TwoNum(int a,int b);
int area();
};
void* makeTwoNum(int a,int b);
#endif
// twonum.cxx
#include "twonum.h"
TwoNum::TwoNum(int a,int b) {
this->a = a; this->b = b;
}
int TwoNum::area() { return a*b; }
TwoNum* makeTwoNum(int a,int b) {
TwoNum *ob = new TwoNum(a,b);
return ob;
}
# usetwonum.nim
proc makeTwoNum(a:cint,b:cint):pointer {.nodecl,importcpp:"makeTwoNum(#,#)".}
proc foo() =
var obj = makeTwoNum(5,11)
echo repr(obj)
foo()
I have tried four variations of the importcpp for makeTwoNum as follows:
# 1 {.importcpp:"makeTwoNum(#,#)".}
# 2 {.importcpp:"makeTwoNum".}
# 3 {.cdecl,importcpp:"makeTwoNum(#,#)".}
# 4 {.nodecl,importcpp:"makeTwoNum(#,#)".}
Examining the resulting usetwonum.cpp file in the nimcache gave these results for the importcpp and the makeTwoNum commands:
#1 N_NIMCALL(void*, makeTwoNum(#,#))(int a, int b);
#2 N_NIMCALL(void*, makeTwoNum)(int a, int b);
#3 N_CDECL(void*, makeTwoNum(#,#))(int a, int b);
#4 <declaration is missing>
#1 void* obj = makeTwoNum(((int) 5),((int) 11));
#2 void* obj = ((int) 5).makeTwoNum(((int) 11));
#3 void* obj = ((int) 5).makeTwoNum(((int) 11));
#4 void* obj = ((int) 5).makeTwoNum(((int) 11));
I would like to have version #2 of the NIMCALL command but #1 of the void* obj command.
How do I do that?
I realize there are other problems, but I cannot get past this first one.
Thanks.
Tweaked your code and used c2nim:
gokr@yoda:~$ cat twonum.h
// twonum.h
#ifndef twonum_H
#define twonum_H
class TwoNum {
int a; int b;
public:
TwoNum(int a,int b);
int area();
};
#endif
gokr@yoda:~$ cat twonum.cpp
// twonum.cxx
#include "twonum.h"
TwoNum::TwoNum(int a,int b) {
this->a = a; this->b = b;
}
int TwoNum::area() { return a*b; }
gokr@yoda:~$ g++ -g -c twonum.cpp
gokr@yoda:~$ c2nim --cpp --header --out:twon.nim twonum.h
Hint: operation successful (14 lines compiled; 0 sec total; 516.528KB; ) [SuccessX]
gokr@yoda:~$ cat usetwonum.nim
import twon
proc foo() =
var obj = constructTwoNum(5,11)
echo repr(obj)
echo $obj.area()
foo()
gokr@yoda:~$ nim cpp --cincludes:. --passL:./twonum.o usetwonum.nim
Hint: system [Processing]
Hint: usetwonum [Processing]
Hint: twon [Processing]
Hint: [Link]
Hint: operation successful (9927 lines compiled; 0.153 sec total; 14.143MB; Debug Build) [SuccessX]
gokr@yoda:~$ ./usetwonum
[]
55
gokr@yoda:~$
The resulting twon.nim looks like:
# twonum.h
type
TwoNum* {.importcpp: "TwoNum", header: "twonum.h".} = object
proc constructTwoNum*(a: cint; b: cint): TwoNum {.constructor, importcpp: "TwoNum(@)",
header: "twonum.h".}
proc area*(this: var TwoNum): cint {.importcpp: "area", header: "twonum.h".}