Hello there,
I have the following C code (this one removes adjacent duplicates in a string):
// myccode.c
const char* change(char *str) {
int i=1;
int j=1;
int k;
int d=0;
while(str[i]!='\0') {
if(str[i-1]==str[i]) {
k=i+1;
while(str[k]!='\0'&&str[k-1]==str[k]) {
k++;
}
i=k;
}
str[j]=str[i];
j++;
i++;
}
str[j]='\0';
return str;
}
I am compiling it with GCC myccode.c -C
Once I have the myccode.o ready to go, I am running the following Nim code:
{.compile: "myccode.c".}
proc change(a: cstring): cstring {.importc.}
when isMainModule:
echo change("Hellllo Thereee !!")
However, I am getting the error: SIGSEGV: Illegal storage access. (Attempt to read from nil?) Error: execution of an external program failed:...
My environment: Windows 10, mingw, nim 0.15
All the best, Alfred N
Like @Araq said. Besides that your C code implies that the string always has at least a len of 1 but will do bad things if not.
Working C code could look like this (just for demonstration!):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char* change(char *str) {
int i=1;
int j=1;
int k;
int d=0;
while(str[i]!='\0') {
if(str[i-1]==str[i]) {
k=i+1;
while(str[k]!='\0'&&str[k-1]==str[k]) {
k++;
}
i=k;
}
str[j]=str[i];
j++;
i++;
}
str[j]='\0';
return str;
}
#define STRING "test mee!"
int main() {
char *s = malloc(strlen(STRING)+1); // get some memory
strcpy(s, STRING); // put our string into it
change(s); // call our manipulator
printf("%s",s);
return 0;
}
For Nim you need to create a var for the string var s = "test mee!". You could than convert it explicit by using s[0].addr and use this as buffer. But this will mess up the Nim string! You also could use a seq[char] as buffer. But then you had to create a Nim string from that later.
Ergo: You should simply implement your function in Nim if you use Nim :)
EDIT: "SIGSEGV: Illegal storage access" does not always mean that a NIL pointer is in the mix. Your code would have worked (with questionable results) in old times before stuff like memory protection was enforced by the CPU. Here your code accesses data which is marked as read only when the executable is getting loaded. Hence the error on writing to it.
Thank you for the kindly comments.
Actually, my final goal is to migrate some of my Python codes to Nim. My knowledge with C (and Nim) is rudimentary yet.
I do have a plenty number of taylor made functions in Python, which I guess I'm gonna spend some time migrating to Nim. So, given Nim has a nice and easy integration with C, I decided to search for some counter party libs in C to help me out with my job.
For example my raw Python code to remove adjacent duplicates in a string is the following:
def remove_dupchar(istring):
return ''.join(c for c, _ in itertools.groupby(istring))
I do have several of primitives like that... I could you the wrapper https://github.com/jboy/nim-pymod to help me out, but I would prefer to don't use any Python code at this time.
So, I will follow your recommendation OderWat by simply implement my function in Nim - plain and simple. I was just looking for a short path to delivery my project.
Cheers