www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Calling C++ code with pointer** argument

reply abad <abad.flt gmail.com> writes:
D source:

extern(C++) void thisWorks(const char* test);
extern(C++) void doesNotLink(const char** test);

void main() {
     char* baz1;
     char** baz2;
     thisWorks(baz1);
     doesNotLink(baz2);
}

CPP source:

#include <stdio.h>

void thisWorks(const char* test) {
     printf("hi\n");
}

void DoesNotLink(const char** test) {
     // not reached
}

The error given by the linker:
test.d:(.text._Dmain+0x21): undefined reference to 
`doesNotLink(char const* const*)'

What's happening? I know there are differences in const behavior 
between D and C++, but can't figure a way around it. Any sort of 
casting trick I tried doesn't seem to help.
Jun 01 2016
parent reply Mike Parker <aldacron gmail.com> writes:
On Wednesday, 1 June 2016 at 07:09:16 UTC, abad wrote:
 D source:

 extern(C++) void thisWorks(const char* test);
 extern(C++) void doesNotLink(const char** test);

 void main() {
     char* baz1;
     char** baz2;
     thisWorks(baz1);
     doesNotLink(baz2);
 }

 CPP source:

 #include <stdio.h>

 void thisWorks(const char* test) {
     printf("hi\n");
 }

 void DoesNotLink(const char** test) {
     // not reached
 }

 The error given by the linker:
 test.d:(.text._Dmain+0x21): undefined reference to 
 `doesNotLink(char const* const*)'

 What's happening? I know there are differences in const 
 behavior between D and C++, but can't figure a way around it. 
 Any sort of casting trick I tried doesn't seem to help.
Try this: extern(C++) void DoesNotLink(const(char)**);
Jun 01 2016
next sibling parent Mike Parker <aldacron gmail.com> writes:
On Wednesday, 1 June 2016 at 07:17:04 UTC, Mike Parker wrote:
 On Wednesday, 1 June 2016 at 07:09:16 UTC, abad wrote:
 What's happening? I know there are differences in const 
 behavior between D and C++, but can't figure a way around it. 
 Any sort of casting trick I tried doesn't seem to help.
Try this: extern(C++) void DoesNotLink(const(char)**);
And I don't know if this was just a typo in your post, but also note that you 'D'oesNotLink in the CPP source you pasted and 'd'oesNotLink in the D code.
Jun 01 2016
prev sibling parent reply abad <abad.flt gmail.com> writes:
On Wednesday, 1 June 2016 at 07:17:04 UTC, Mike Parker wrote:
 On Wednesday, 1 June 2016 at 07:09:16 UTC, abad wrote:

 Try this:

 extern(C++) void DoesNotLink(const(char)**);
That does work, though I have to explicitly cast it in my caller as well. Like this: doesNotLink(cast(const(char)**)baz2); It's a bit troublesome as my code will include quite a lot of calls like this. Casting is not necessary with the method call with the single pointer argument, as it seems to get const'ed automatically.
 And I don't know if this was just a typo in your post,  but 
 also note that you 'D'oesNotLink in the CPP source you pasted 
 and 'd'oesNotLink in the D code.
That was just a typo.
Jun 01 2016
parent reply Kagamin <spam here.lot> writes:
On Wednesday, 1 June 2016 at 07:29:56 UTC, abad wrote:
 That does work, though I have to explicitly cast it in my 
 caller as well.
 Like this:

 doesNotLink(cast(const(char)**)baz2);

 It's a bit troublesome as my code will include quite a lot of 
 calls like this.

 Casting is not necessary with the method call with the single 
 pointer argument, as it seems to get const'ed automatically.
Can you declare it as const char*const* one the C++ side?
Jun 01 2016
parent Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Wednesday, 1 June 2016 at 16:16:26 UTC, Kagamin wrote:
 Can you declare it as const char*const* one the C++ side?
Just to state the problem clearly, D's const is transitive, C++ it is not. C linkage doesn't care about const, so you can specify it however you want. In C++ the const is included in the mangling, so it must match the declaration between C++ and D. Transitive meaning that const will apply to all elements pointed to. This is why you see linker complain about not being able to find char const * const *
Jun 01 2016