Thread overview | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 05, 2012 Problem with Hiredis Binding | ||||
---|---|---|---|---|
| ||||
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? |
January 05, 2012 Re: Problem with Hiredis Binding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Puming Zhao | 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 |
January 05, 2012 Re: Problem with Hiredis Binding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joshua Reusch | 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.
|
January 05, 2012 Re: Problem with Hiredis Binding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Puming Zhao | 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?
|
January 05, 2012 Re: Problem with Hiredis Binding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | 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 |
January 05, 2012 Re: Problem with Hiredis Binding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joshua Reusch |
> 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.
|
January 05, 2012 Re: Problem with Hiredis Binding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joshua Reusch | 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. |
January 05, 2012 Re: Problem with Hiredis Binding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | 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
|
January 06, 2012 Re: Problem with Hiredis Binding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | 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? |
January 06, 2012 Re: Problem with Hiredis Binding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johannes Pfau | > 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... |
Copyright © 1999-2021 by the D Language Foundation