July 30, 2013
I'm using toStringz() and it works fine if you're c++ function parms are const ref or by value:

void funk(const std::string& val) {}
void funk(std::string val) {}


July 30, 2013
(damn, no edit!)

I'm using toStringz() and it works fine if you're c++ function
parms are const ref or by value:

void funk(const std::string& val) {}
void funk(std::string val) {}


then use a very simple D script to auto-generated C wrapper functions from headers. All the script does is:

void funkD(const char* c) {funk(c);}

It wouldn't work for functions taking a string by ref or pointer, that would require too much effort in the generating script for my liking.

You may baulk at the idea of writing a script for auto-generating the code but really it is very simple.
July 31, 2013
On 7/30/2013 3:01 PM, John Colvin wrote:
> $ dmd -c -m64 inter.d
> $ g++ -c -m64 inter.cpp -ointercpp.o
> $ g++ inter.o intercpp.o -ointer -lphobos2
> inter.o: In function `_Dmain':
> inter.d:(.text._Dmain+0x48): undefined reference to `printString(CppString*)'
> collect2: error: ld returned 1 exit status

You might want to look at the name mangling of the D printString vs the name mangling of the C++ one.

July 31, 2013
On Tuesday, 30 July 2013 at 19:52:44 UTC, Milvakili wrote:
> I'm linking D with C++ lib.a file.  When the C++ function has compatible data types I can call them from D.  But when I changed the parameter to string I got bunch of errors.
>
> Data Type Compatibility table does not include strings.  Is there a way of passing strings?

When it come to C++, passing via C string is always an option, but kind of a waste as you'll allocate a temporary string and go through it twice.

My solution of choice it to create a function in C++ that take a const char* and a size_t length as parameter (and other C++ parameters of the function and forward to C++ .

Doing so, you only allocate the C++ string as C++ mandate and don't need to go through it. But you need a wrapper.
July 31, 2013
On Tuesday, 30 July 2013 at 20:57:55 UTC, Jesse Phillips wrote:
> On Tuesday, 30 July 2013 at 20:09:01 UTC, Milvakili wrote:
>
>> So I need to pass them as char*, I can not pass them as string?
>
> C++ doesn't have an immutable(char)[], it has char* and its own string class. To communicate with it one must choose a type both languages can understand, char* is that. D may be able to get away with providing a C++ string, but I'm not familiar with the integration layer.

const char*, char const* are equivalent to const(char)* in D.
July 31, 2013
On 07/30/2013 02:17 PM, JS wrote:

> A C++ string is null terminated while a D string is not.

I think the OP means std::string, which also is not zero-terminated. (On the other hand, C strings are zero-terminated.)

> If you pass a D string to C++ then it will not have the same length and give
> undesirable behavior.

That's an important consideration. char is not UTF-8 code unit in C and C++.

Ali

July 31, 2013
On Wednesday, 31 July 2013 at 05:44:38 UTC, deadalnix wrote:
> On Tuesday, 30 July 2013 at 20:57:55 UTC, Jesse Phillips wrote:
>> On Tuesday, 30 July 2013 at 20:09:01 UTC, Milvakili wrote:
>>
>>> So I need to pass them as char*, I can not pass them as string?
>>
>> C++ doesn't have an immutable(char)[], it has char* and its own string class. To communicate with it one must choose a type both languages can understand, char* is that. D may be able to get away with providing a C++ string, but I'm not familiar with the integration layer.
>
> const char*, char const* are equivalent to const(char)* in D.

I was referring to string types:
http://www.cplusplus.com/reference/string/string/

If his C++ functions takes a const char* he should be passing it
a const/immutable(char)* as you say, not an immutable(char)[]
July 31, 2013
On Wednesday, 31 July 2013 at 06:07:07 UTC, Jesse Phillips wrote:
> On Wednesday, 31 July 2013 at 05:44:38 UTC, deadalnix wrote:
>> On Tuesday, 30 July 2013 at 20:57:55 UTC, Jesse Phillips wrote:
>>> On Tuesday, 30 July 2013 at 20:09:01 UTC, Milvakili wrote:
>>>
>>>> So I need to pass them as char*, I can not pass them as string?
>>>
>>> C++ doesn't have an immutable(char)[], it has char* and its own string class. To communicate with it one must choose a type both languages can understand, char* is that. D may be able to get away with providing a C++ string, but I'm not familiar with the integration layer.
>>
>> const char*, char const* are equivalent to const(char)* in D.
>
> I was referring to string types:
> http://www.cplusplus.com/reference/string/string/
>
> If his C++ functions takes a const char* he should be passing it
> a const/immutable(char)* as you say, not an immutable(char)[]

In C++, std::string own its own copy of the string. So it is safe to pass a D const char* to the constructor.
July 31, 2013
On Wednesday, 31 July 2013 at 05:56:13 UTC, Ali Çehreli wrote:
> On 07/30/2013 02:17 PM, JS wrote:
>
> > A C++ string is null terminated while a D string is not.
>
> I think the OP means std::string, which also is not zero-terminated. (On the other hand, C strings are zero-terminated.)

You can obtain a 0 terminated "const char*" from an std::string in 0(1) using c_str.

While the C++98 standard doesn't mandate it, the above requirement means that 99% of string implementations are using arraysinternally. The C++11 standard *does* mandate that the implementation use arrays internally. So that means you can get a valid char* from &myString[0].

That string will not be 0 terminated, but all the major compiler providers (AFAIK) make that guarantee as an extension.
July 31, 2013
On Tuesday, 30 July 2013 at 20:53:55 UTC, Dicebot wrote:
> On Tuesday, 30 July 2013 at 20:22:46 UTC, Milvakili wrote:
>> Thanks.  Is there any work in progress related to string passing?
>> I think string passing should be solved automatically.
>>
>> Coz otherwise one need to write wrapper for each c++ function that has a string parameter.
>>
>> thanks.
>
> c_function(toStringz("hello").ptr) does not seem that bad, what is the issue here?

I want to point out that one of the dangers (as I've heard it, I haven't actually run into this), is that since the garbage collector won't scan your C function's internals, the caller *must* keep a reference in his code to preserve the allocated array. The above scheme does not do that: If the garbage collector runs after the start of the call, but before the end of the function, then you are in trouble.

I'd do it like this:
//----
string lifeline = toStringz("hello"); //Preserve reference
c_function(lifeline.ptr); //Make call
lifeline = null; //Release reference
//----

That's assuming c_function won't preserve the string somewhere. If it does, things get more complicated.