Hi, I've been looking for a couple days and can't find out exactly how this is done. Goal: have cpp/h files generated that I can compile in with my c++ project to include helper functions originally written in nim. I'll try updating to development later to see if that fixes it.
What I'm doing:
$ nim cpp -c -d:release --header --noMain mylib.nim (see below for src)
$ cd nimcache
$ ls
main.cpp (see below for src)
mylib.cpp
mylib.h
<redacted usual nim cpp files>
$ g++ -o main *.cpp -I/Nim-0.18.0/lib -w
stdlib_dynlib.cpp: In function 'void* symAddr_NHfjIU1Uh0ju9azgMjiSkQA(void*, NCSTRING)':
stdlib_dynlib.cpp:45:25: error: invalid conversion from 'FARPROC' {aka 'long long int (*)()'} to 'void*' [-fpermissive]
result = GetProcAddress(LOC1.dest, name);
$ gcc --version
<...> 8.2.0
// main.cpp
#include <iostream>
#include "mylib.h"
using namespace std; // for demo
extern char** parseCSVListLine(const char*); // Seem to need this because mylib.h does not have it (?!)
int main() {
parseCSVListLine("one,two,three");
return(0);
}
import strutils, sequtils, os, parsecsv, streams, future
proc parseCSVListLine*(str: string):seq[string] =
var ss = newStringStream(str)
var p: CsvParser
p.open(ss, "parseCSVListLine()")
discard p.readRow()
return lc[ col.strip() | (col <- items(p.row)), string]
proc parseCSVListLine*(str: cstring):cstringArray {.extern: "parseCSVListLine".} =
return alloccstringArray(parseCSVListLine($str))
I don't have time right now to give a complete answer, but this link may help you. It's for c linking, but you can easily extend it to cpp.
https://nim-lang.org/docs/backends.html#backend-code-calling-nim-nim-invocation-example-from-c
@gibson, here's what seemed to work for me.
I changed mylib.nim to be like this, but I only did so to get rid of the duplicate name:
import strutils, sequtils, os, parsecsv, streams, future
proc parseCSVListLine*(str: cstring): cstringArray {.exportc.} =
var ss = newStringStream($str)
var p: CsvParser
p.open(ss, "parseCSVListLine()")
discard p.readRow()
return allocCstringArray(lc[ col.strip() | (col <- items(p.row)), string])
I changed the main.cpp as follows:
// main.cpp
#include <iostream>
#include "mylib.h"
using namespace std; // for demo
int main() {
NimMain(); // Need to add this for Nim's GC calls and other Nim related things
parseCSVListLine("one,two,three");
return 0;
}
And here's how I made it work using the latest Nim devel branch:
nim cpp --noMain --noLinking --header:mylib.h mylib.nim
And to compile the c++ code:
g++ -I/home/joey/Nim/lib -I/home/joey/.cache/nim/mylib_d/ -o main main.cpp ~/.cache/nim/mylib_d/*.cpp -w
note that in the above command, the -I calls are a bit finicky. You need to specify the full path. Also I compiled on Ubuntu, so windows mileage may vary. Let me know if this works for you.