Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
November 30, 2013 Calling a C Function with C-style Strings | ||||
---|---|---|---|---|
| ||||
I'm struggling to call mktemp in D: import core.sys.posix.stdlib; import std.string: toStringz; auto name = "alpha"; auto tmp = mktemp(name.toStringz); but I can't figure out how to use it so DMD complains: /home/per/Work/justd/fs.d(1042): Error: function core.sys.posix.stdlib.mktemp (char*) is not callable using argument types (immutable(char)*) How do I create a mutable zero-terminated C-style string? I think I've read somewhere that string literals (`const` or `immutable`) are implicitly convertible to zero (null)-terminated strings. |
November 30, 2013 Re: Calling a C Function with C-style Strings | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Saturday, 30 November 2013 at 15:48:28 UTC, Nordlöw wrote:
> I think I've read somewhere that string literals (`const` or `immutable`) are implicitly convertible to zero (null)-terminated strings.
AFAIR, this should work:
char[] name = "alpha".dup;
mktemp(name.ptr);
D literals are zero-terminated so toStringz is only needed if you want to pass to C function slice of literal or some runtime input.
Another option is to declare extern(C) function to take `const (char)*` argument, as far as I remember C it should not affect mangling but will allow to pass literal directly without allocating a mutable copy.
|
November 30, 2013 Re: Calling a C Function with C-style Strings | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Saturday, 30 November 2013 at 15:48:28 UTC, Nordlöw wrote:
> /home/per/Work/justd/fs.d(1042): Error: function core.sys.posix.stdlib.mktemp (char*) is not callable using argument types (immutable(char)*)
This is because mktemp needs to write to the string. From mktemp(3):
The last six characters of template must be XXXXXX and these
are replaced with a string that makes the filename unique. Since it
will be modified, template must not be a string constant, but should be
declared as a character array.
So what you want to do here is use a char[] instead of a string. I'd go with:
import std.stdio;
void main() {
import core.sys.posix.stdlib;
// we'll use a little mutable buffer defined right here
char[255] tempBuffer;
string name = "alphaXXXXXX"; // last six X's are required by mktemp
tempBuffer[0 .. name.length] = name[]; // copy the name into the mutable buffer
tempBuffer[name.length] = 0; // make sure it is zero terminated yourself
auto tmp = mktemp(tempBuffer.ptr);
import std.conv;
writeln(to!string(tmp));
}
|
November 30, 2013 Re: Calling a C Function with C-style Strings | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Saturday, 30 November 2013 at 15:59:38 UTC, Adam D. Ruppe wrote:
> This is because mktemp needs to write to the string.
Ah disregard my post then, I thought it is yet another C function that misses `const` in signature :)
|
November 30, 2013 Re: Calling a C Function with C-style Strings | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On 11/30/2013 07:59 AM, Adam D. Ruppe wrote:
> tempBuffer[name.length] = 0; // make sure it is zero terminated
> yourself
Because char.init is not 0 in D: :)
assert(tempBuffer[name.length + 1] == '\xff');
Ali
|
November 30, 2013 Re: Calling a C Function with C-style Strings | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On 11/30/2013 07:58 AM, Dicebot wrote: > char[] name = "alpha".dup; > mktemp(name.ptr); > > D literals are zero-terminated so toStringz is only needed if you want > to pass to C function slice of literal or some runtime input. However, I doubt that .dup copies that '\0' character. Although the literal has the termination, we are in slice land beyond that literal so the termination must somehow be ensured. Ali |
November 30, 2013 Re: Calling a C Function with C-style Strings | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Saturday, 30 November 2013 at 18:58:30 UTC, Ali Çehreli wrote:
> However, I doubt that .dup copies that '\0' character. Although the literal has the termination, we are in slice land beyond that literal so the termination must somehow be ensured.
>
> Ali
Hm, yes, this also sounds like a valid concern. I thought that for literals \0 is part of actual string but after making a quick check it looks "hidden" behind actual length. So yep, perfectly wrong answer from me :)
|
Copyright © 1999-2021 by the D Language Foundation