www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - C API / const char *text / std.string.toStringz pointer is always NULL on C side

reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
I have an extern(C) function in a DLL with this signature:

result* myfunc(double x, double y, const char *text, stuff *myStuff, 
bool flag);

I call it like this:

result = myfunc(0, 0, std.string.toStringz("1"), stuff, true);


The problem is, that on the DLL side *text is always NULL. I doesn't 
matter what I put as third argument. And even more strange, I have an 
other function with a const char* as first argument. There everything 
is working...

Any idea what cause this could be? This is really strange...


-- 
Robert M. Mnch
http://www.saphirion.com
smarter | better | faster
May 16 2018
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 17/05/2018 3:07 AM, Robert M. Münch wrote:
 I have an extern(C) function in a DLL with this signature:
 
 result* myfunc(double x, double y, const char *text, stuff *myStuff, 
 bool flag);
 
 I call it like this:
 
 result = myfunc(0, 0, std.string.toStringz("1"), stuff, true);
 
 
 The problem is, that on the DLL side *text is always NULL. I doesn't 
 matter what I put as third argument. And even more strange, I have an 
 other function with a const char* as first argument. There everything is 
 working...
 
 Any idea what cause this could be? This is really strange...
Please post the C function prototype.
May 16 2018
parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
On 2018-05-16 15:09:41 +0000, rikki cattermole said:

 On 17/05/2018 3:07 AM, Robert M. Mnch wrote:
 I have an extern(C) function in a DLL with this signature:
 
 result* myfunc(double x, double y, const char *text, stuff *myStuff, 
 bool flag);
 
 I call it like this:
 
 result = myfunc(0, 0, std.string.toStringz("1"), stuff, true);
 
 
 The problem is, that on the DLL side *text is always NULL. I doesn't 
 matter what I put as third argument. And even more strange, I have an 
 other function with a const char* as first argument. There everything 
 is working...
 
 Any idea what cause this could be? This is really strange...
Please post the C function prototype.
Well, for C see above on the D side: extern(C) { result myfunc(double x, double y, const char *text, stuff *myStuff, bool measureOnly); } result is a: extern (C++, class) struct result { double w; double h; } -- Robert M. Mnch http://www.saphirion.com smarter | better | faster
May 16 2018
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 5/16/18 12:53 PM, Robert M. Münch wrote:
 On 2018-05-16 15:09:41 +0000, rikki cattermole said:
 
 On 17/05/2018 3:07 AM, Robert M. Münch wrote:
 I have an extern(C) function in a DLL with this signature:

 result* myfunc(double x, double y, const char *text, stuff *myStuff, 
 bool flag);

 I call it like this:

 result = myfunc(0, 0, std.string.toStringz("1"), stuff, true);


 The problem is, that on the DLL side *text is always NULL. I doesn't 
 matter what I put as third argument. And even more strange, I have an 
 other function with a const char* as first argument. There everything 
 is working...

 Any idea what cause this could be? This is really strange...
Please post the C function prototype.
Well, for C see above on the D side:     extern(C) {           result myfunc(double x, double y, const char *text, stuff *myStuff, bool measureOnly);     }
Shouldn't the result be a pointer? -Steve
May 16 2018
parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
On 2018-05-16 17:46:59 +0000, Steven Schveighoffer said:

 Well, for C see above on the D side:
 
 extern(C) {
  result myfunc(double x, double y, const char *text, stuff 
 *myStuff, bool measureOnly);
 }
Shouldn't the result be a pointer?
Indeed. And you know what? That was causing the problem. So, having a wrong return-type here, resulted in the const char *text parameter always being NULL. Not sure I understand the relation but looks strange to me... at least not very obvious. -- Robert M. Mnch http://www.saphirion.com smarter | better | faster
May 18 2018
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Friday, 18 May 2018 at 14:06:11 UTC, Robert M. Münch wrote:
 So, having a wrong return-type here, resulted in the const char 
 *text parameter always being NULL. Not sure I understand the 
 relation but looks strange to me... at least not very obvious.
A value struct return is actually done via a hidden pointer parameter (so the function can construct it in-place for the caller, a standard optimization), so it just shifted all the other arguments to the side, causing one of those 0's to be interpreted as the string.
May 18 2018
parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
On 2018-05-18 14:42:17 +0000, Adam D. Ruppe said:

 On Friday, 18 May 2018 at 14:06:11 UTC, Robert M. Mnch wrote:
 So, having a wrong return-type here, resulted in the const char *text 
 parameter always being NULL. Not sure I understand the relation but 
 looks strange to me... at least not very obvious.
A value struct return is actually done via a hidden pointer parameter (so the function can construct it in-place for the caller, a standard optimization), so it just shifted all the other arguments to the side, causing one of those 0's to be interpreted as the string.
Wow, thanks for the clear explanation. Without very deep internal knowhow I don't think anyone is able to ever guess this. Is this somehwere documented? -- Robert M. Mnch http://www.saphirion.com smarter | better | faster
May 19 2018
parent kinke <noone nowhere.com> writes:
On Saturday, 19 May 2018 at 17:33:08 UTC, Robert M. Münch wrote:
 On 2018-05-18 14:42:17 +0000, Adam D. Ruppe said:
 A value struct return is actually done via a hidden pointer 
 parameter (so the function can construct it in-place for the 
 caller, a standard optimization), so it just shifted all the 
 other arguments to the side, causing one of those 0's to be 
 interpreted as the string.
[...] Is this somehwere documented?
https://docs.microsoft.com/en-us/cpp/build/return-values-cpp:
 Otherwise, the caller assumes the responsibility of allocating
 memory and passing a pointer for the return value as the first
 argument. Subsequent arguments are then shifted one argument
 to the right.
May 19 2018
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 5/16/18 11:07 AM, Robert M. Münch wrote:
 I have an extern(C) function in a DLL with this signature:
 
 result* myfunc(double x, double y, const char *text, stuff *myStuff, 
 bool flag);
 
 I call it like this:
 
 result = myfunc(0, 0, std.string.toStringz("1"), stuff, true);
toStringz isn't necessary, string literals always are null terminated, and implicitly cast to const char *.
 The problem is, that on the DLL side *text is always NULL. I doesn't 
 matter what I put as third argument. And even more strange, I have an 
 other function with a const char* as first argument. There everything is 
 working...
 
 Any idea what cause this could be? This is really strange...
It sounds very much like a mismatch of parameters on the prototype. Anything extern(C) has no mangling, and so you can specify the wrong parameters and it still compiles. Double check the parameter types, and if possible, reduce to a simple compilable example that can be tested by others. -Steve
May 16 2018