digitalmars.D.learn - Problem with Hiredis Binding
- Puming Zhao (11/11) Jan 05 2012 Hi, I'm new in D programming, and does not have much C experience either...
- Joshua Reusch (7/20) Jan 05 2012 timeval tv);
- Timon Gehr (2/32) Jan 05 2012 D string literals are zero-terminated.
- Joshua Reusch (3/40) Jan 05 2012 Sure ? dlang.org says they are not:
- Joshua Reusch (3/5) Jan 05 2012 Sorry, in the printf section: "String literals already have a 0 appended...
- Andrej Mitrovic (11/11) Jan 05 2012 Your problem is that you're calling printf on a static char array. If
- bearophile (6/8) Jan 05 2012 I think C just requires:
- Puming (21/36) Jan 05 2012 Thanks for the tip. I've changed code as you suggested.
- Mike Parker (9/43) Jan 05 2012 I think the problem still lies with your declaration of the integer
- Puming (7/16) Jan 05 2012 I changed c_long to long and it actually works !!! Thanks very
- Puming (6/6) Jan 05 2012 Here is what I've got so far:
- bearophile (4/5) Jan 06 2012 In C "long long" isn't always 64 bit.
- Mike Parker (3/6) Jan 06 2012 Well, either the documentation is wrong or the implementation is. Looks
- Johannes Pfau (7/15) Jan 06 2012 The documentation is wrong. c_long is meant to be used _only_ for C's "l...
- Andrej Mitrovic (4/5) Jan 06 2012 That was my fault. I was going to fix the original docs which had no
- Johannes Pfau (26/43) Jan 05 2012 in hiredis.d
- Puming (5/8) Jan 05 2012 Thanks. I've changed `int integer` to `c_long integer` according
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?
Jan 05 2012
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
Jan 05 2012
On 01/05/2012 07:14 PM, Joshua Reusch wrote:Am 05.01.2012 17:21, schrieb Puming Zhao:D string literals are zero-terminated.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
Jan 05 2012
Am 05.01.2012 19:44, schrieb Timon Gehr:On 01/05/2012 07:14 PM, Joshua Reusch wrote:Sure ? dlang.org says they are not: http://www.d-programming-language.org/arrays.html#stringsAm 05.01.2012 17:21, schrieb Puming Zhao:D string literals are zero-terminated.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
Jan 05 2012
Sure ? dlang.org says they are not: http://www.d-programming-language.org/arrays.html#stringsSorry, in the printf section: "String literals already have a 0 appended to them, so can be used directly" I missed this.
Jan 05 2012
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.
Jan 05 2012
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
Jan 05 2012
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?
Jan 05 2012
On 1/6/2012 11:38 AM, Puming wrote:On Thursday, 5 January 2012 at 22:02:25 UTC, Andrej Mitrovic wrote: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.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?
Jan 05 2012
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.I changed c_long to long and it actually works !!! Thanks very much. Now I'm wondering should I use `long` or do some static check for the type just like what c_long does for C' long type? I'm only using 32bit Ubuntu, so not able to check this on other systems. Wonder whether there is a c_long_long type. In http://dlang.org/interfaceToC.html it says in 32bit system c_long is equivalent to `long long` in C. Is this wrong?
Jan 05 2012
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 :)
Jan 05 2012
Puming:1. "long long" in C is always 64bit, so in D it's "long";In C "long long" isn't always 64 bit. Bye, bearophile
Jan 06 2012
On 1/6/2012 2:34 PM, Puming wrote:Well, either the documentation is wrong or the implementation is. Looks like one for Bugzilla.In http://dlang.org/interfaceToC.html it says in 32bit system c_long is equivalent to `long long` in C. Is this wrong?
Jan 06 2012
Mike Parker wrote:On 1/6/2012 2:34 PM, Puming wrote: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 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/55Well, either the documentation is wrong or the implementation is. Looks like one for Bugzilla.In http://dlang.org/interfaceToC.html it says in 32bit system c_long is equivalent to `long long` in C. Is this wrong?
Jan 06 2012
On 1/6/12, Johannes Pfau <spam example.com> wrote:The documentation is wrong.That was my fault. I was going to fix the original docs which had no mention of c_long/c_ulong and I ended up screwing up the tables. Sorry!
Jan 06 2012
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?
Jan 05 2012
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...
Jan 05 2012