On Sun, 18 Jul 2010 13:08:57 -0700, Charles Hixson wrote: > I'm trying to link a C routine to a D program, passing string > parameters, but I keep getting segmentation errors. As you can see, > these are simple test routines, so the names don't reflect current > status, but merely where I intend to arrive...but I've hit severe > roadblocks. > (FWIW, I've tried including -fpic in the gcc command, and it didn't > appear to make any difference.) > > Makefile: > biblio: biblio.d sqlitebase.o > dmd biblio.d sqlitebase.o -ofbiblio > > sqlitebase.o: sqlitebase.c sqlitebase.h > gcc -c sqlitebase.c > > biblio.d: > import std.stdio; > > //extern (C) void dbdefine (char[] str); extern (C) void > dbdefine (char[] inStr, ref char[255] outStr); > > void main() > { char[255] retVal; > char[] msg = cast(char[])"Hello from C\0"; dbdefine (msg, > retVal); > writeln ("Hello, World"); > } > > sqlitebase.h: > > //void dbdefine (char str[]); > void dbdefine (char inStr[], char outStr[255]); > > sqlitebase.c: > > #include "sqlitebase.h" > > //void dbdefine (char str[]) > void dbdefine (char inStr[], char outStr[255]) { //int i = 0; > //while (str[i] != 0) i++; > //printStr (i, str); > //^^--segmentation fault--^^ > // printf ("%s/n", str); > //^^--warning: incompatible implicit declaration of built-in > function ‘printf’--^^ > //int i = str[0]; > //putchar(i); > //^^--segmentation fault--^^ > int i = -1; > while (++i < 255) > { if (inStr[i] == 0) break; > outStr[i] = inStr[i]; > } > > }
Since bearophile already answered with a solution to your problem, I'll just chime in with a few small tips (of which you may already be aware): 1. D string *literals* are already zero-terminated, so you don't need to add the \0 character explicitly. Also, they cast implicitly to const (char)*, so if your function doesn't change inStr, it's perfectly fine to do extern(C) void dbdefine (const char* inStr); dbdefine("Hello from C"); 2. For D strings in general the \0 must be added, but this is very easy to forget. Therefore, when passing strings to C functions I always use the std.string.toStringz() function. It takes a D string, adds a \0 if necessary, and returns a pointer to the first character. string s = getAStringFromSomewhere(); dbdefine(toStringz(s)); -Lars