Jump to page: 1 2
Thread overview
Problem with Hiredis Binding
Jan 05, 2012
Puming Zhao
Jan 05, 2012
Joshua Reusch
Jan 05, 2012
Timon Gehr
Jan 05, 2012
Joshua Reusch
Jan 05, 2012
Joshua Reusch
Jan 05, 2012
Andrej Mitrovic
Jan 05, 2012
bearophile
Jan 06, 2012
Puming
Jan 06, 2012
Mike Parker
Jan 06, 2012
Puming
Jan 06, 2012
Puming
Jan 06, 2012
bearophile
Jan 06, 2012
Mike Parker
Jan 06, 2012
Johannes Pfau
Jan 06, 2012
Andrej Mitrovic
Jan 05, 2012
Johannes Pfau
Jan 06, 2012
Puming
January 05, 2012
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
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
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
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
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
> 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
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
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
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
> 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