Re: Problem with Hiredis Binding
On 1/6/2012 2:34 PM, Puming wrote: In http://dlang.org/interfaceToC.html it says in 32bit system c_long is equivalent to `long long` in C. Is this wrong? Well, either the documentation is wrong or the implementation is. Looks like one for Bugzilla.
Re: Problem with Hiredis Binding
Mike Parker wrote: On 1/6/2012 2:34 PM, Puming wrote: In http://dlang.org/interfaceToC.html it says in 32bit system c_long is equivalent to `long long` in C. Is this wrong? Well, either the documentation is wrong or the implementation is. Looks like one for Bugzilla. The documentation is wrong. c_long is meant to be used _only_ for C's long type, so it must be 32bit for 32bit architectures and 64bit for (most) 64bit architectures. See also: http://en.wikipedia.org/wiki/64-bit#64- bit_data_models No need to file a bug though, I posted a fix here: https://github.com/D- Programming-Language/d-programming-language.org/pull/55
Re: Problem with Hiredis Binding
On 01/05/2012 07:14 PM, Joshua Reusch wrote: Am 05.01.2012 17:21, schrieb Puming Zhao: Hi, I'm new in D programming, and does not have much C experience either. After reading TDPL book and playing with some sample codes, I came to decide to try something more `practical`. I began with a Redis client binding from Hiredis C code. Hiredis is a small lib, and seems very simple to bind to D. My code on github: https://github.com/zhaopuming/dredis But I went into problems that I don't know how to solve. When running example.d I went into segment fault, and can't get redisReply from a redis command. I tried to google it but got nothing. So my question is, could some one with more knowledge in redis or C/D look into my code and see what's wrong ? Or is there already a Redis binding exists? dredis.d: redisContext* redisConnectWithTimeout(const char* ip, int port, timeval tv); example.d: redisConnectWithTimeout(127.0.0.1, 6379, timeout); D strings do not end with an \0 byte ! You can use std.string.toStringz to convert them to C's const char* -- Joshua D string literals are zero-terminated.
Re: Problem with Hiredis Binding
Puming Zhao wrote: Hi, I'm new in D programming, and does not have much C experience either. After reading TDPL book and playing with some sample codes, I came to decide to try something more `practical`. I began with a Redis client binding from Hiredis C code. Hiredis is a small lib, and seems very simple to bind to D. My code on github: https://github.com/zhaopuming/dredis But I went into problems that I don't know how to solve. When running example.d I went into segment fault, and can't get redisReply from a redis command. I tried to google it but got nothing. So my question is, could some one with more knowledge in redis or C/D look into my code and see what's wrong ? Or is there already a Redis binding exists? in hiredis.d struct redisReply { int type; /* REDIS_REPLY_* */ int integer; /* The integer when type is REDIS_REPLY_INTEGER */ int len; /* Length of string */ char* str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */ size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */ redisReply** element; /* elements vector for REDIS_REPLY_ARRAY */ }; but in hiredis.h typedef struct redisReply { int type; /* REDIS_REPLY_* */ long long integer; /* The integer when type is REDIS_REPLY_INTEGER */ int len; /* Length of string */ char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */ size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */ struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */ } redisReply; So you have int integer; in D and long long integer; in C, which doesn't match. I'm not sure what size long long is in C, but I guess you need long in D?
Re: Problem with Hiredis Binding
Am 05.01.2012 19:44, schrieb Timon Gehr: On 01/05/2012 07:14 PM, Joshua Reusch wrote: Am 05.01.2012 17:21, schrieb Puming Zhao: Hi, I'm new in D programming, and does not have much C experience either. After reading TDPL book and playing with some sample codes, I came to decide to try something more `practical`. I began with a Redis client binding from Hiredis C code. Hiredis is a small lib, and seems very simple to bind to D. My code on github: https://github.com/zhaopuming/dredis But I went into problems that I don't know how to solve. When running example.d I went into segment fault, and can't get redisReply from a redis command. I tried to google it but got nothing. So my question is, could some one with more knowledge in redis or C/D look into my code and see what's wrong ? Or is there already a Redis binding exists? dredis.d: redisContext* redisConnectWithTimeout(const char* ip, int port, timeval tv); example.d: redisConnectWithTimeout(127.0.0.1, 6379, timeout); D strings do not end with an \0 byte ! You can use std.string.toStringz to convert them to C's const char* -- Joshua D string literals are zero-terminated. Sure ? dlang.org says they are not: http://www.d-programming-language.org/arrays.html#strings
Re: Problem with Hiredis Binding
Sure ? dlang.org says they are not: http://www.d-programming-language.org/arrays.html#strings Sorry, in the printf section: String literals already have a 0 appended to them, so can be used directly I missed this.
Re: Problem with Hiredis Binding
Your problem is that you're calling printf on a static char array. If you're going to use printf you have to use it on the .ptr (pointer) field of the static array. Replace this call: printf(Connection error: %s\n, c.errstr); with printf(Connection error: %s\n, c.errstr.ptr); On my end I get: Connection error: Connection refused Also I think you should replace the int integer in struct redisReply to long integer. I think `long long` in C is 8 bytes, which is the equivalent to D's long type.
Re: Problem with Hiredis Binding
Andrej Mitrovic: I think `long long` in C is 8 bytes, which is the equivalent to D's long type. I think C just requires: sizeof(long long int) = sizeof(long int). For the actual size I think you have to ask to the C compiler. Bye, bearophile
Re: Problem with Hiredis Binding
On Thursday, 5 January 2012 at 22:02:25 UTC, Andrej Mitrovic wrote: Your problem is that you're calling printf on a static char array. If you're going to use printf you have to use it on the .ptr (pointer) field of the static array. Replace this call: printf(Connection error: %s\n, c.errstr); with printf(Connection error: %s\n, c.errstr.ptr); On my end I get: Connection error: Connection refused Also I think you should replace the int integer in struct redisReply to long integer. I think `long long` in C is 8 bytes, which is the equivalent to D's long type. Thanks for the tip. I've changed code as you suggested. And for the type `long long`, I changed `int` to `c_long` (in core.stdc.config) according to http://dlang.org/interfaceToC.html But there is still problem. My code does actually connect, as I have a redis-server running on my machine, and the commands actually runned, as I use a redis-cli and found that foo : bar is actually set into redis. But --- reply = cast(redisReply*) redisCommand(c, GET foo); writefln(GET foo: %s, *reply); writefln(to!string(reply.str)); output these: --- GET foo: redisReply(1, 0, 0, 2, 152397072, 0) 80B1F42 段错误 // (which is Chinese for Segfault) --- So maybe I got it wrong when converting char* to string?
Re: Problem with Hiredis Binding
So you have int integer; in D and long long integer; in C, which doesn't match. I'm not sure what size long long is in C, but I guess you need long in D? Thanks. I've changed `int integer` to `c_long integer` according to this page http://dlang.org/interfaceToC.html c_long is in core.stdc.config But I still can not get reply.str right...
Re: Problem with Hiredis Binding
On 1/6/2012 11:38 AM, Puming wrote: On Thursday, 5 January 2012 at 22:02:25 UTC, Andrej Mitrovic wrote: Your problem is that you're calling printf on a static char array. If you're going to use printf you have to use it on the .ptr (pointer) field of the static array. Replace this call: printf(Connection error: %s\n, c.errstr); with printf(Connection error: %s\n, c.errstr.ptr); On my end I get: Connection error: Connection refused Also I think you should replace the int integer in struct redisReply to long integer. I think `long long` in C is 8 bytes, which is the equivalent to D's long type. Thanks for the tip. I've changed code as you suggested. And for the type `long long`, I changed `int` to `c_long` (in core.stdc.config) according to http://dlang.org/interfaceToC.html But there is still problem. My code does actually connect, as I have a redis-server running on my machine, and the commands actually runned, as I use a redis-cli and found that foo : bar is actually set into redis. But --- reply = cast(redisReply*) redisCommand(c, GET foo); writefln(GET foo: %s, *reply); writefln(to!string(reply.str)); output these: --- GET foo: redisReply(1, 0, 0, 2, 152397072, 0) 80B1F42 段错误 // (which is Chinese for Segfault) --- So maybe I got it wrong when converting char* to string? I think the problem still lies with your declaration of the integer field. c_long in D is supposed to be equivalent to the long type in C, *not* long long. It is declared as 32 bits on a 32-bit system and 64 bits on a 64-bit system. I believe that in practice, most C compilers implement long long as 64 bits on both 32- and 64-bit systems. I recommend you use long on the D side, rather than c_long. And, actually, it would be best to compile a test with the same C compiler used to compile redis to verify the size of long long.
Re: Problem with Hiredis Binding
Here is what I've got so far: 1. long long in C is always 64bit, so in D it's long; 2. C's char* string should be converted to!string when used in writeln; 3. String literals in D -IS- zero terminated; And now it's working fine. Thanks everybody :)