View mode: basic / threaded / horizontal-split · Log in · Help
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
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
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
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
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
> 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
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
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
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
> 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...
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home