Re: exern (C) linkage problem
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
Re: exern (C) linkage problem
Lars T. Kyllingstad: 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)); The C code has to use those string pointers with lot of care. The D type system can help you remember to use the toStringz, this is just an idea: import std.string: toStringz; typedef char* Cstring; extern(C) Cstring strcmp(Cstring s1, Cstring s2); Cstring toCString(T)(T[] s) { return cast(Cstring)toStringz(s); } void main() { auto s1 = abba; auto s2 = red; // auto r = strcmp(toCString(s1), s2); // compile error auto r = strcmp(toCString(s1), toCString(s2)); // OK } Unfortunately Andrei has killed the useful typedef. So you have to use a struct with alias this, that often doesn't work. Bye, bearophile
Is there a way to create compile-time delegates?
Yeah, what the subject says. I want to have a default delegate for a struct, and without a default constructor, this has to be a compile-time constant. Now, logically, there should be nothing wrong with storing the function pointer and a null context pointer at compile-time, but it seems there is. Any ideas? struct foo { void delegate( ) dg = () {}; // Error: non-constant expression // __dgliteral1 } -- Simen
Detecting a property setter?
Hi, Does anyone know how to detect if there is a setter for a property? The code below prints the same thing for both the setter and the getter of front: == import std.traits; class Foo { uint num; @property ref uint front() { return num; } @property void front(uint i) { num = i; } ref uint front2() { return num; } } template isProperty(alias func) if (isCallable!(func)) { enum isProperty = (functionAttributes!(func) FunctionAttribute.PROPERTY)==0 ? false : true; } template hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = (isProperty!(func) ParameterTypeTuple!(func).length 0 ReturnType!(func).stringof != void) ? true : false; } void main() { Foo foo; pragma(msg, hasSetter!(foo.front)); static if (isProperty!(foo.front)) { pragma(msg, property); } else { pragma(msg, not a property); } alias MemberFunctionsTuple!(Foo,front) fronts; foreach (s; fronts) { pragma(msg, ReturnType!(s)); // this line just prints uint for both front properties! } } Is this a compiler bug? Or am I wrong again? Thanks Rory www.neonova.co.za: http://cf.neonova.co.za/9YXp View: https://mail1.clearformat.com/vcard.php?uid=11pid=10 Beta Test Advert: http://fwd.clearformat.com/9YXn inline: logo.jpginline: ff2d54b.jpg
Re: Is there a way to create compile-time delegates?
On 19.07.2010 21:06, Simen kjaeraas wrote: Yeah, what the subject says. I want to have a default delegate for a struct, and without a default constructor, this has to be a compile-time constant. Now, logically, there should be nothing wrong with storing the function pointer and a null context pointer at compile-time, but it seems there is. Any ideas? struct foo { void delegate( ) dg = () {}; // Error: non-constant expression // __dgliteral1 } I wasn't able to make it work. The compiler probably sees delegates as something that just can't be created at compile time, since no runtime contexts exist then. Which is reasonable. Maybe one of those templates that turn functions into delegates will work? Otherwise I guess you're back to using a factory function for initializing instances. Maybe just checking for null pointers before calling those delegates ends up being the easiest solution.
Re: Detecting a property setter?
Rory McGuire rmcgu...@neonova.co.za wrote: Does anyone know how to detect if there is a setter for a property? The code below prints the same thing for both the setter and the getter of front: == import std.traits; class Foo { uint num; @property ref uint front() { return num; } @property void front(uint i) { num = i; } ref uint front2() { return num; } } template isProperty(alias func) if (isCallable!(func)) { enum isProperty = (functionAttributes!(func) FunctionAttribute.PROPERTY)==0 ? false : true; } template hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = (isProperty!(func) ParameterTypeTuple!(func).length 0 ReturnType!(func).stringof != void) ? true : false; } For what it's worth, I would simply check if the property allows assignment. i.e.: template hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = isProperty!(func) is( typeof( (){ func = ReturnType!(func).init; } ) ); } -- Simen
Re: Is there a way to create compile-time delegates?
On Mon, Jul 19, 2010 at 22:01, torhu n...@spam.invalid wrote: I wasn't able to make it work. Me too :( The compiler probably sees delegates as something that just can't be created at compile time, since no runtime contexts exist then. Which is reasonable. Can you initialize pointers in general, at compile-time? Maybe one of those templates that turn functions into delegates will work? I had the same idea and tried to use std.functional.toDelegate, but to no avail. enum moo = () {return 1;}; struct foo { int delegate( ) dg = toDelegate(moo); } Error: forward reference to inferred return type of function call toDelegate(delegate int()| int moo() { return 1;} struct foo { int delegate( ) dg = toDelegate(moo); } Error: forward reference to inferred return type of function call toDelegate(( moo))| 'auto' strikes again :( I came to hate these forward reference errors. That and the fact that auto functions do not appear in the docs, that's enough for me to avoid auto as much as possible for functions. Otherwise I guess you're back to using a factory function for initializing instances. Maybe just checking for null pointers before calling those delegates ends up being the easiest solution. Philippe
Re: Detecting a property setter?
On Monday, July 19, 2010 13:42:51 Philippe Sigaud wrote: On Mon, Jul 19, 2010 at 22:06, Simen kjaeraas simen.kja...@gmail.comwrote: template hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = isProperty!(func) is( typeof( (){ func = ReturnType!(func).init; } ) ); } In that case, for the second func, the one you call ReturnType on, how does the compiler knows it must take the ref uint one (the getter) and not the void func() one? Philippe I don't think that you're supposed to be able to have a getter property returning a ref at the same time that you have a setter property with the same name. It certainly sounds like it should be a bug in any case. - Jonathan M Davis
Re: Detecting a property setter?
On Mon, 19 Jul 2010 22:06:14 +0200, Simen kjaeraas simen.kja...@gmail.com wrote: Rory McGuire rmcgu...@neonova.co.za wrote: Does anyone know how to detect if there is a setter for a property? The code below prints the same thing for both the setter and the getter of front: == import std.traits; class Foo { uint num; @property ref uint front() { return num; } @property void front(uint i) { num = i; } ref uint front2() { return num; } } template isProperty(alias func) if (isCallable!(func)) { enum isProperty = (functionAttributes!(func) FunctionAttribute.PROPERTY)==0 ? false : true; } template hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = (isProperty!(func) ParameterTypeTuple!(func).length 0 ReturnType!(func).stringof != void) ? true : false; } For what it's worth, I would simply check if the property allows assignment. i.e.: template hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = isProperty!(func) is( typeof( (){ func = ReturnType!(func).init; } ) ); } Hehe good solution, never even crossed my mind. And it doesn't match ref return types such as the following signature. ref uint front() { return num; } My test code below: === import std.traits; class Foo { uint num; @property ref uint front() { return num; } /+@property void front(uint i) { num = i; }+/ ref uint front2() {return num;} } template isProperty(alias func) if (isCallable!(func)) { enum isProperty = (functionAttributes!(func) FunctionAttribute.PROPERTY)==0 ? false : true; } template hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = isProperty!(func) is( typeof( (){ func = ReturnType!(func).init; } ) ); } void main() { Foo foo; pragma(msg, hasSetter!(foo.front)); // is the return type null (setter) static if (isProperty!(foo.front)) { pragma(msg, property); } else { pragma(msg, not a property); } alias MemberFunctionsTuple!(Foo,front) fronts; foreach (s; fronts) { pragma(msg, hasSetter!(s)); } } Could be used in a GUI library for checking which properties of a class are editable and which are only for display. And tell you about it at compile time. Thanks!
Re: Detecting a property setter?
On Mon, 19 Jul 2010 23:25:01 +0200, Jonathan M Davis jmdavisp...@gmail.com wrote: On Monday, July 19, 2010 13:42:51 Philippe Sigaud wrote: On Mon, Jul 19, 2010 at 22:06, Simen kjaeraas simen.kja...@gmail.comwrote: template hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = isProperty!(func) is( typeof( (){ func = ReturnType!(func).init; } ) ); } In that case, for the second func, the one you call ReturnType on, how does the compiler knows it must take the ref uint one (the getter) and not the void func() one? Philippe I don't think that you're supposed to be able to have a getter property returning a ref at the same time that you have a setter property with the same name. It certainly sounds like it should be a bug in any case. - Jonathan M Davis I suppose it would be seen as a bug because it possibly circumvents the getter/setter philosophy (If you return the internal value anyway).
Re: Detecting a property setter?
On Mon, 19 Jul 2010 22:42:51 +0200, Philippe Sigaud philippe.sig...@gmail.com wrote:On Mon, Jul 19, 2010 at 22:06, Simen kjaeraas simen.kja...@gmail.com wrote: template hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = isProperty!(func) is( typeof( (){ func = ReturnType!(func).init; } ) ); }In that case, for the second func, the one you call ReturnType on, how does the compiler knows it must take the ref uint one (the getter) and not the void func() one?Philippe Simen is using the fact that the compiler already has to figure out if there is an overload that matches the requirements. So it ends uptaking the only one that works. Since it seems to ignore the ref return type property, the property that takes an uint argument must have ahigher precedence (gets checked if it works first).I wonder if its because Walter probably implemented function overloading before properties and ref return types. Hopefully its a languagefeature and not just a implementation side effect.-Rory
Re: Detecting a property setter?
On Monday, July 19, 2010 14:37:22 Rory McGuire wrote: I suppose it would be seen as a bug because it possibly circumvents the getter/setter philosophy (If you return the internal value anyway). No, the problem is that you have _both_ a getter returning a ref and a setter. So, which does the compiler use? Returning a ref isn't a problem - phobos does it with ranges. Doing that, you basically user the getter for setting the property also. However, with both a getter returning a ref and a setter, then the compiler is going to have to choose which to use if you use the property as a setter. It's an ambiguity and thus shouldn't compile. If it does, then that's a bug. - Jonathan M Davis
Re: exern (C) linkage problem
typedef char* Cstring; extern(C) Cstring strcmp(Cstring s1, Cstring s2); ... You can use just a struct too: import std.string: toStringz; struct Cstring { const(char)* ptr; } extern(C) Cstring strcmp(Cstring s1, Cstring s2); Cstring toCString(T)(T[] s) { return Cstring(toStringz(s)); } void main() { auto s1 = abba; auto s2 = red; // auto r = strcmp(toCString(s1), s2); // compile error auto r = strcmp(toCString(s1), toCString(s2)); // OK } Bye, bearophile
Re: Is there a way to create compile-time delegates?
Philippe Sigaud wrote: On Mon, Jul 19, 2010 at 22:01, torhu n...@spam.invalid wrote: I wasn't able to make it work. Me too :( The compiler probably sees delegates as something that just can't be created at compile time, since no runtime contexts exist then. Which is reasonable. Can you initialize pointers in general, at compile-time? You cannot initialize a pointer to runtime-allocated data at compile-time, and will never be able to. This particular example cannot ever work. You should be able to initialize pointers to static data at compile-time, but currently you can't. Maybe one of those templates that turn functions into delegates will work? I had the same idea and tried to use std.functional.toDelegate, but to no avail. enum moo = () {return 1;}; struct foo { int delegate( ) dg = toDelegate(moo); } Error: forward reference to inferred return type of function call toDelegate(delegate int()| int moo() { return 1;} struct foo { int delegate( ) dg = toDelegate(moo); } Error: forward reference to inferred return type of function call toDelegate(( moo))| 'auto' strikes again :( I came to hate these forward reference errors. That and the fact that auto functions do not appear in the docs, that's enough for me to avoid auto as much as possible for functions. Otherwise I guess you're back to using a factory function for initializing instances. Maybe just checking for null pointers before calling those delegates ends up being the easiest solution. Philippe