digitalmars.D.learn - Calling a C Function with C-style Strings
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (13/13) Nov 30 2013 I'm struggling to call mktemp in D:
- Dicebot (10/13) Nov 30 2013 AFAIR, this should work:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (5/9) Nov 30 2013 However, I doubt that .dup copies that '\0' character. Although the
- Dicebot (5/9) Nov 30 2013 Hm, yes, this also sounds like a valid concern. I thought that
- Adam D. Ruppe (26/29) Nov 30 2013 This is because mktemp needs to write to the string. From
- Dicebot (4/5) Nov 30 2013 Ah disregard my post then, I thought it is yet another C function
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (4/6) Nov 30 2013 Because char.init is not 0 in D: :)
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.
Nov 30 2013
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.
Nov 30 2013
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
Nov 30 2013
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. AliHm, 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 :)
Nov 30 2013
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)); }
Nov 30 2013
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 :)
Nov 30 2013
On 11/30/2013 07:59 AM, Adam D. Ruppe wrote:tempBuffer[name.length] = 0; // make sure it is zero terminated yourselfBecause char.init is not 0 in D: :) assert(tempBuffer[name.length + 1] == '\xff'); Ali
Nov 30 2013