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









Daniel =?UTF-8?B?S296w6Fr?= via Digitalmars-d-learn 