digitalmars.D.learn - Passing string literals to C
- Laeeth Isharc (5/5) Dec 31 2014 What's best practice here?
- Laeeth Isharc (24/24) Dec 31 2014 Argh - no way to edit.
- Daniel =?UTF-8?B?S296w6Fr?= via Digitalmars-d-learn (12/45) Dec 31 2014 V Wed, 31 Dec 2014 11:19:35 +0000
- Mike Parker (12/36) Dec 31 2014 String literals are always null-terminated. You can typically pass them
- John Colvin (4/41) Dec 31 2014 String literals can implicitly convert to const(char)* or
- Meta (5/8) Dec 31 2014 I believe this is a special case specifically for strings added
- Laeeth Isharc (2/2) Dec 31 2014 Thanks for the help.
- Gary Willoughby (7/31) Jan 01 2015 To call a C function you can either use string literals which are
What's best practice here? D strings are not null-terminated. char* cpling(char *s) { So toString("This i
Dec 31 2014
Argh - no way to edit. What's best practice here? D strings are not null-terminated. === cpling.c char* cpling(char *s) { s[0]='!'; return s; } === dcaller.d extern(C) char* cpling(char* s); void callC() { writefln("%s",fromStringz(cpling("hello\0"))); } or void callC() { writefln("%s",fromStringz(cpling(toStringz("hello")))); } === am I missing a better way to do this?
Dec 31 2014
V Wed, 31 Dec 2014 11:19:35 +0000 Laeeth Isharc via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> napsáno:Argh - no way to edit. What's best practice here? D strings are not null-terminated. === cpling.c char* cpling(char *s) { s[0]='!'; return s; } === dcaller.d extern(C) char* cpling(char* s); void callC() { writefln("%s",fromStringz(cpling("hello\0"))); } or void callC() { writefln("%s",fromStringz(cpling(toStringz("hello")))); } === am I missing a better way to do this?First I am not sure, but you do not need to call fromStringz in this case. Next in this example you even not need to call toStringz, because D string literals are null-terminated. But generally it is better to use toStringz when need pass D strings to C code. Important Note: When passing a char* to a C function, and the C function keeps it around for any reason, make sure that you keep a reference to it in your D code. Otherwise, it may go away during a garbage collection cycle and cause a nasty bug when the C code tries to use it.
Dec 31 2014
On 12/31/2014 8:19 PM, Laeeth Isharc wrote:Argh - no way to edit. What's best practice here? D strings are not null-terminated. === cpling.c char* cpling(char *s) { s[0]='!'; return s; } === dcaller.d extern(C) char* cpling(char* s); void callC() { writefln("%s",fromStringz(cpling("hello\0"))); } or void callC() { writefln("%s",fromStringz(cpling(toStringz("hello")))); } === am I missing a better way to do this?String literals are always null-terminated. You can typically pass them as-is and D will do the right thing (you can also pass "MyStr".ptr if you want). Use toStringz when the string came from an external source (read from a file, passed into a function and so on), since you can't be sure if it was a literal or not. toStringz will recognize if it has a null-terminator and will not do anything if it does. Also, you should make sure to consider std.conv.to on any C strings returned into D if you are going to keep them around. fromStringz only creates a slice, which is fine for how you use it here, but could get you into trouble if you aren't careful. std.conv.to will allocate a new string.
Dec 31 2014
On Wednesday, 31 December 2014 at 11:45:33 UTC, Mike Parker wrote:On 12/31/2014 8:19 PM, Laeeth Isharc wrote:String literals can implicitly convert to const(char)* or immutable(char)*. Neat. It doesn't appear to apply to array literals in general though...Argh - no way to edit. What's best practice here? D strings are not null-terminated. === cpling.c char* cpling(char *s) { s[0]='!'; return s; } === dcaller.d extern(C) char* cpling(char* s); void callC() { writefln("%s",fromStringz(cpling("hello\0"))); } or void callC() { writefln("%s",fromStringz(cpling(toStringz("hello")))); } === am I missing a better way to do this?String literals are always null-terminated. You can typically pass them as-is and D will do the right thing (you can also pass "MyStr".ptr if you want).
Dec 31 2014
On Wednesday, 31 December 2014 at 12:25:45 UTC, John Colvin wrote:String literals can implicitly convert to const(char)* or immutable(char)*. Neat. It doesn't appear to apply to array literals in general though...I believe this is a special case specifically for strings added for convenience when interfacing with C. Walter has said that he is strongly against arrays decaying to points a la C, and D generally does not support it save for this special case.
Dec 31 2014
On Wednesday, 31 December 2014 at 11:19:36 UTC, Laeeth Isharc wrote:Argh - no way to edit. What's best practice here? D strings are not null-terminated. === cpling.c char* cpling(char *s) { s[0]='!'; return s; } === dcaller.d extern(C) char* cpling(char* s); void callC() { writefln("%s",fromStringz(cpling("hello\0"))); } or void callC() { writefln("%s",fromStringz(cpling(toStringz("hello")))); } === am I missing a better way to do this?To call a C function you can either use string literals which are always null terminated or use std.string.toStringz (when using string variables) to add the null and return a char*. To convert from char* (from a C function return value) to a D string use std.conv.to!(string).
Jan 01 2015