On Fri, 08 Jul 2011 07:53:20 -0400, Regan Heath <re...@netmail.co.nz>
wrote:
On Fri, 08 Jul 2011 10:49:08 +0100, Walter Bright
<newshou...@digitalmars.com> wrote:
On 7/8/2011 2:26 AM, Regan Heath wrote:
Why can't we have the
compiler call it automatically whenever we pass a string, or char[] to
an extern
"C" function, where the parameter is defined as char*?
Because char* in C does not necessarily mean "zero terminated string".
Sure, but in many (most?) cases it does. And in those cases where it
doesn't you could argue ubyte* or byte* should have been used in the D
extern "C" declaration instead. Plus, in those cases, worst case
scenario, D passes an extra \0 byte to those functions which either
ignore it because they were also passed a length, or expect a fixed
sized structure, or .. I don't know what as I can't imagine another case
where char* would be used without it being a "zero terminated string",
or passing/knowing the length ahead of time.
D is already allocating an extra \0 byte for string constants right?
And, I assume, toStringz is already clever enough to detect cases where
there is already a \0 in the correct position, or utilises the existing
preallocated space remaining in a dynamic array, making it almost a
no-op. The only case it actually does any work is a dynamic or static
array which is full. In the former case the array is resized, and I'm
not sure about the latter but I suspect it's more expensive. So, it
seems the cost of this is very low.
What about a template function that does this automatically? I'm thinking
something like opDispatch:
extern(C) foo(const(char)* c);
struct CCall
{
auto opDispatch(string call, S...)(S args) if(call is a C function (can
check this somehow?) )
{
/* determine which args of S are char[], and translate them to
zero-terminated */
...
}
}
usage:
string s;
CCall.foo(s);
I personally think, barring this idea, the best path is simply to wrap C
functions you want to call with toStringz'd versions.
-Steve