Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
September 11, 2010 string to char* | ||||
---|---|---|---|---|
| ||||
Hello, I'm having a problem in passing a value to char* expecting function in D 2.0. Already tried: to!(char*)("my string"); but it seems like there (Phobos) is no template like this. Then, tried: cast(char*)to!(char[])("my string") which looked ok, but i think it's not a proper way to do that. Most strings converted this way works properly, but once: char* string1 = cast(char*)to!(char[])("my string 1"); char* string2 = cast(char*)to!(char[])("my string 2"); resulted: string1 = "my string 1" string2 = "my string 1my string 2" I can't manage this problem, could You hint me? |
September 11, 2010 Re: string to char* | ||||
---|---|---|---|---|
| ||||
Posted in reply to shd | shd <alienballance@gmail.com> wrote: > Hello, > I'm having a problem in passing a value to char* expecting function > in D 2.0. Why does the function expect a char*? If it is an external C function, and it might change the passed values, you should make a duplicate mutable string, or use char[] in lieu of string. If it is an external C function that will *not* change the passed values, and you have write access to the D headers to interface to C, use const char* instead. If no write access, I would use cast(char*)myString.ptr. If it is a D function, why does it not use const? Or for that matter, why does it not use char[]? -- Simen |
September 11, 2010 Re: string to char* | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen kjaeraas | On 2010-09-11 15:13, Simen kjaeraas wrote:
> Why does the function expect a char*? If it is an external C function,
> and it might change the passed values, you should make a duplicate
> mutable string, or use char[] in lieu of string.
>
> If it is an external C function that will *not* change the passed
> values, and you have write access to the D headers to interface to C,
> use const char* instead. If no write access, I would use
> cast(char*)myString.ptr.
Yes, it's external C function and I can modify bindings (just bindings, not ABI). Now I'll trace back library which is interfacing to me and possibly fix bindings.
You helped me already, thanks a lot. I can already go on (this language is so cool btw.).
|
September 11, 2010 Re: string to char* | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mariusz Gliwiński | I'm interfacing with Scintilla (C++), but it works in a different way. It uses messages, which allows it to be linked with practically any language. But I can still pass parameters to be modified by passing the address of the variable instead (the wrapper takes care of that).
Although linking with C++ is difficult, having proper C linkage is a great thing. There's a ton of libraries out there ready to be used right now in D.
2010/9/11 Mariusz Gliwiński <alienballance@gmail.com>:
> On 2010-09-11 15:13, Simen kjaeraas wrote:
>>
>> Why does the function expect a char*? If it is an external C function, and it might change the passed values, you should make a duplicate mutable string, or use char[] in lieu of string.
>>
>> If it is an external C function that will *not* change the passed values, and you have write access to the D headers to interface to C, use const char* instead. If no write access, I would use cast(char*)myString.ptr.
>
> Yes, it's external C function and I can modify bindings (just bindings, not ABI). Now I'll trace back library which is interfacing to me and possibly fix bindings.
>
> You helped me already, thanks a lot. I can already go on (this language is
> so cool btw.).
>
|
September 11, 2010 Re: string to char* | ||||
---|---|---|---|---|
| ||||
Posted in reply to shd | shd:
> I'm having a problem in passing a value to char* expecting function
> in D 2.0. Already tried:
> to!(char*)("my string");
A solution, maybe correct:
import std.string: toStringz, indexOf;
import std.c.string: strlen;
import std.stdio: writeln;
void main() {
string s = "my string";
assert(indexOf(s, '\0') == -1); // useful
char* p = cast(char*)toStringz(s);
writeln(strlen(p));
}
But keep in mind this string p is managed by the D GC.
That cast to cast(char*) is not nice.
There is no need to dup the string given to toStringz because it performs the dup internally (wasting a initialization of 'copy'), this is the cleaned up implementation of toStringz:
const(char)* toStringz(string s) {
char[] copy = new char[s.length + 1];
copy[0 .. s.length] = s;
copy[s.length] = 0;
return copy.ptr;
}
I don't know why it returns a const(char)* instead of a char*. Do you know why?
Bye,
bearophile
|
September 12, 2010 Re: string to char* | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Saturday 11 September 2010 09:07:38 bearophile wrote:
> I don't know why it returns a const(char)* instead of a char*. Do you know
> why?
>
> Bye,
> bearophile
Well, if you look at toStringz()'s implementation, you may notice that there's commented out code which would not make a copy if there's a 0 in memory one passed the end of the string. It would simply use that 0 as the end of the const char* and avoid the copy. That being the case, it avoids a copy but must be const, because the string is immutable. Now, why that code is commented out, I don't know, and if toStringz() continues to always copy the string, then char* would likely be a better choice. But it could be that whatever issue made it so that the non-copying version was commented out will be fixed at some point, and toStringz() will once again cease to make a copy if it doesn't have to, at which point it would need to return const.
- Jonathan M Davis
|
September 12, 2010 Re: string to char* | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Jonathan M Davis:
> Well, if you look at toStringz()'s implementation, you may notice that there's commented out code which would not make a copy if there's a 0 in memory one passed the end of the string. It would simply use that 0 as the end of the const char* and avoid the copy. That being the case, it avoids a copy but must be const, because the string is immutable.
I see, thank you for the answer. Generally in the C code that uses the C string I can't be certain that it doesn't modify the string. On the other hand often I need a char* and not a const char*. Ao I'd like toStringz() to always copy and return a char* (Often I need a const pointer to mutable chars).
Another possibility is to have two functions, one that always performs the copy and returns a char*, and one that sometimes doesn't copy and returns a const char*.
Or a single template function that returns a const char* if doconst is true :-)
auto toStringz(bool doconst=false)(string s) { ...
Bye,
bearophile
|
September 14, 2010 Re: string to char* | ||||
---|---|---|---|---|
| ||||
Posted in reply to shd | On 9/11/10 3:00 PM, shd wrote:
> Hello,
> I'm having a problem in passing a value to char* expecting function
> in D 2.0. Already tried:
>
> to!(char*)("my string");
>
> but it seems like there (Phobos) is no template like this. Then,
> tried:
>
> cast(char*)to!(char[])("my string")
>
> which looked ok, but i think it's not a proper way to do that. Most
> strings converted this way works properly, but once:
>
> char* string1 = cast(char*)to!(char[])("my string 1");
> char* string2 = cast(char*)to!(char[])("my string 2");
>
> resulted:
> string1 = "my string 1"
> string2 = "my string 1my string 2"
>
> I can't manage this problem, could You hint me?
>
Use std.string.toStringz to convert a D string to a C null-terminated one.
This asymmetry (no to!(char*)(string)) has been discussed once, but I can't remember the reason why it was not implemented right now.
|
Copyright © 1999-2021 by the D Language Foundation