www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What's best practice to use compound literals with structs and C-APIs?

reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
I use some C library that uses structs and many functions that use 
pointer to structs as arguments:

struct A {...};
myfunc(A *myA);

In C you can do this to get a lvalue:

myfunc(&(A){...});

In D this doesn't work and I get an "is not an lvalue and cannot be modified".

What's the correct D-ish way in such a case?

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster
May 01 2019
next sibling parent reply Alex <sascha.orlov gmail.com> writes:
On Wednesday, 1 May 2019 at 12:47:22 UTC, Robert M. Münch wrote:
 I use some C library that uses structs and many functions that 
 use pointer to structs as arguments:

 struct A {...};
 myfunc(A *myA);

 In C you can do this to get a lvalue:

 myfunc(&(A){...});

 In D this doesn't work and I get an "is not an lvalue and 
 cannot be modified".

 What's the correct D-ish way in such a case?
Look, even in C you have to workaround the case, where you want to pass a value instead of a pointer. So, the proper question would be, how to redesign, so that &(A){...} is not needed. However, to rebuild the same structure, auto ref parameters may be appropriate. https://dlang.org/spec/template.html#auto-ref-parameters or you new A(...) in place or you use the byRef-pattern as shown in d-idioms https://p0nce.github.io/d-idioms/#Rvalue-references:-Understanding-auto-ref-and-then-not-using-it Not sure, which part is under your control...
May 01 2019
parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
On 2019-05-01 14:23:37 +0000, Alex said:

 On Wednesday, 1 May 2019 at 12:47:22 UTC, Robert M. Münch wrote:
 I use some C library that uses structs and many functions that use 
 pointer to structs as arguments:
 
 struct A {...};
 myfunc(A *myA);
 
 In C you can do this to get a lvalue:
 
 myfunc(&(A){...});
 
 In D this doesn't work and I get an "is not an lvalue and cannot be modified".
 
 What's the correct D-ish way in such a case?
Look, even in C you have to workaround the case, where you want to pass a value instead of a pointer.
That's not a workaround in C, it's the way to do it.
 However, to rebuild the same structure, auto ref parameters may be appropriate.
 https://dlang.org/spec/template.html#auto-ref-parameters
That would need me to change myfunc which is not possible because the D binding is all generated from C code.
 or you new A(...) in place
Doesn't work because this seems to kick in some D releated run-time stuff which lead to unresolved externals during linking: error LNK2001: Nicht aufgelöstes externes Symbol "...__initZ". error LNK2001: Nicht aufgelöstes externes Symbol "...__xtoHashFNbNeKxSQBtQBoQBfZm". error LNK2001: Nicht aufgelöstes externes Symbol "...__xopEqualsFKxSQBsQBnQBeKxQmZb". Not sure, why this happens.
 or you use the byRef-pattern as shown in d-idioms
 https://p0nce.github.io/d-idioms/#Rvalue-references:-Understanding-auto-ref-a
d-then-not-using-it 
 
This again would need my to change the C bindings, which are generated. -- Robert M. Münch http://www.saphirion.com smarter | better | faster
May 01 2019
parent reply Alex <sascha.orlov gmail.com> writes:
On Wednesday, 1 May 2019 at 14:59:48 UTC, Robert M. Münch wrote:
 On 2019-05-01 14:23:37 +0000, Alex said:

 However, to rebuild the same structure, auto ref parameters 
 may be appropriate.
 https://dlang.org/spec/template.html#auto-ref-parameters
That would need me to change myfunc which is not possible because the D binding is all generated from C code.
Ok, I see.
 or you new A(...) in place
Doesn't work because this seems to kick in some D releated run-time stuff which lead to unresolved externals during linking: error LNK2001: Nicht aufgelöstes externes Symbol "...__initZ". error LNK2001: Nicht aufgelöstes externes Symbol "...__xtoHashFNbNeKxSQBtQBoQBfZm". error LNK2001: Nicht aufgelöstes externes Symbol "...__xopEqualsFKxSQBsQBnQBeKxQmZb". Not sure, why this happens.
Found this bug: https://issues.dlang.org/show_bug.cgi?id=12374 It is closed now, because of inactivity, if you have a current case - a reopen is welcome. However... Not sure, maybe someone else has more knowledge about this.
 or you use the byRef-pattern as shown in d-idioms
 https://p0nce.github.io/d-idioms/#Rvalue-references:-Understanding-auto-ref-and-then-not-using-it
 
This again would need my to change the C bindings, which are generated.
So, you generate D structs from C, right? If so, and if you need the byRef at any cost - you could tweak the generator, so byRef is generated for all structs.
May 01 2019
parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
On 2019-05-01 19:13:54 +0000, Alex said:

 Doesn't work because this seems to kick in some D releated run-time 
 stuff which lead to unresolved externals during linking:
 
 error LNK2001: Nicht aufgelöstes externes Symbol "...__initZ".
 error LNK2001: Nicht aufgelöstes externes Symbol 
 "...__xtoHashFNbNeKxSQBtQBoQBfZm".
 error LNK2001: Nicht aufgelöstes externes Symbol 
 "...__xopEqualsFKxSQBsQBnQBeKxQmZb".
 
 Not sure, why this happens.
Found this bug: https://issues.dlang.org/show_bug.cgi?id=12374 It is closed now, because of inactivity, if you have a current case - a reopen is welcome. However... Not sure, maybe someone else has more knowledge about this.
Thanks for the link, looks a bit related. I would need to see if I can create a small case which shows the problem...
 So, you generate D structs from C, right? If so, and if you need the 
 byRef at any cost - you could tweak the generator, so byRef is 
 generated for all structs.
Well, the generator is DStep... and I'm not sure if a general "byRef" approach would make sense. And listing affected structs manually will complicate the workflow again. What I'm irriated about is, that this works: A tmp = {x,y}; return myfunc(&tmp); But this doesn't: return myfunc(new A(x,y)); Or I haven't found a valid syntax to do it inline. -- Robert M. Münch http://www.saphirion.com smarter | better | faster
May 02 2019
parent Alex <sascha.orlov gmail.com> writes:
On Thursday, 2 May 2019 at 07:11:37 UTC, Robert M. Münch wrote:
 On 2019-05-01 19:13:54 +0000, Alex said:

 Doesn't work because this seems to kick in some D releated 
 run-time stuff which lead to unresolved externals during 
 linking:
 
 error LNK2001: Nicht aufgelöstes externes Symbol "...__initZ".
 error LNK2001: Nicht aufgelöstes externes Symbol 
 "...__xtoHashFNbNeKxSQBtQBoQBfZm".
 error LNK2001: Nicht aufgelöstes externes Symbol 
 "...__xopEqualsFKxSQBsQBnQBeKxQmZb".
 
 Not sure, why this happens.
Found this bug: https://issues.dlang.org/show_bug.cgi?id=12374 It is closed now, because of inactivity, if you have a current case - a reopen is welcome. However... Not sure, maybe someone else has more knowledge about this.
Thanks for the link, looks a bit related. I would need to see if I can create a small case which shows the problem...
 So, you generate D structs from C, right? If so, and if you 
 need the byRef at any cost - you could tweak the generator, so 
 byRef is generated for all structs.
Well, the generator is DStep... and I'm not sure if a general "byRef" approach would make sense. And listing affected structs manually will complicate the workflow again.
yeah...
 What I'm irriated about is, that this works:

 A tmp = {x,y};
 return myfunc(&tmp);

 But this doesn't:

 return myfunc(new A(x,y));

 Or I haven't found a valid syntax to do it inline.
For me, this works: ´´´ void main() { myfunc(new A(5)); } struct A{ int i; } void myfunc(A* myA){} ´´´
May 02 2019
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2019-05-01 14:47, Robert M. Münch wrote:
 I use some C library that uses structs and many functions that use 
 pointer to structs as arguments:
 
 struct A {...};
 myfunc(A *myA);
 
 In C you can do this to get a lvalue:
 
 myfunc(&(A){...});
 
 In D this doesn't work and I get an "is not an lvalue and cannot be 
 modified".
 
 What's the correct D-ish way in such a case?
struct A {...}; myfunc(A *myA); What about doing this: auto a = A(/* set any values */); myfunc(&a); -- /Jacob Carlborg
May 02 2019