Re: Problem with Hiredis Binding

2012-01-06 Thread Mike Parker

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

2012-01-06 Thread Johannes Pfau
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

2012-01-05 Thread 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.


Re: Problem with Hiredis Binding

2012-01-05 Thread Johannes Pfau
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

2012-01-05 Thread Joshua Reusch

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

2012-01-05 Thread 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.


Re: Problem with Hiredis Binding

2012-01-05 Thread Andrej Mitrovic
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

2012-01-05 Thread bearophile
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

2012-01-05 Thread Puming
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

2012-01-05 Thread Puming
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

2012-01-05 Thread Mike Parker

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

2012-01-05 Thread Puming

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 :)