July 31, 2013 Re: Passing string from D to c++ | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Wednesday, 31 July 2013 at 07:54:00 UTC, monarch_dodra wrote: > 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. > You have to work very hard to not find it either in the stack or in a register during the function call. So as long as the C code do not keep a reference, ou should be fine. > I'd do it like this: > //---- > string lifeline = toStringz("hello"); //Preserve reference > c_function(lifeline.ptr); //Make call > lifeline = null; //Release reference > //---- > This is plain useless. dead store elimination will remove the "release reference", the variable lifeline promoted to register (its ptr part anyway, it length part is likely to be trashed right away by the function call). On X86, the string will be returned in EAX and EDX (ptr in EDX if I'm not mistaken). So the length will be erased by copying EDX to EAX (now both contains the ptr, length is lost) and the call made right away (first argument is passed in EAX). > That's assuming c_function won't preserve the string somewhere. If it does, things get more complicated. If it does, that means big trouble, even in pure C, as it is now unclear who is the owner of the string. A recipe for memory corruption/leak. |
July 31, 2013 Re: Passing string from D to c++ | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On Wednesday, 31 July 2013 at 08:20:48 UTC, deadalnix wrote: > On Wednesday, 31 July 2013 at 07:54:00 UTC, monarch_dodra wrote: >> 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. >> > > You have to work very hard to not find it either in the stack or in a register during the function call. So as long as the C code do not keep a reference, ou should be fine. > >> I'd do it like this: >> //---- >> string lifeline = toStringz("hello"); //Preserve reference >> c_function(lifeline.ptr); //Make call >> lifeline = null; //Release reference >> //---- >> > > This is plain useless. dead store elimination will remove the "release reference", the variable lifeline promoted to register (its ptr part anyway, it length part is likely to be trashed right away by the function call). > > On X86, the string will be returned in EAX and EDX (ptr in EDX if I'm not mistaken). So the length will be erased by copying EDX to EAX (now both contains the ptr, length is lost) and the call made right away (first argument is passed in EAX). I'll take your word for it then. As I said, I didn't run into this before, but I had read some other posts that mentioned this problem. I might have it confused with dynamic libs though? I don't know. Forget I said anything then. >> That's assuming c_function won't preserve the string somewhere. If it does, things get more complicated. > > If it does, that means big trouble, even in pure C, as it is now unclear who is the owner of the string. A recipe for memory corruption/leak. Most probably. |
July 31, 2013 Re: Passing string from D to c++ | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Wednesday, 31 July 2013 at 02:53:47 UTC, Walter Bright wrote: > 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. Woops, yeah that was never going to work. However, I did come across something interesting: gcc mangles std::string as "Ss", see here: https://github.com/mirrors/gcc/blob/master/gcc/cp/mangle.c#L472 It also doesn't bother mangling the length for these special case identifiers, e.g. void printString(string * s, BLAHBLAH fdsa) becomes _Z11printStringPSs8BLAHBLAH Any ideas how we can get around this? Some std c++ type instrinsics in dmd? |
July 31, 2013 Re: Passing string from D to c++ | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Wednesday, 31 July 2013 at 13:15:58 UTC, John Colvin wrote: > Any ideas how we can get around this? Some std c++ type instrinsics in dmd? Maybe http://d.puremagic.com/issues/show_bug.cgi?id=10077 can help? |
July 31, 2013 Re: Passing string from D to c++ | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On Wednesday, 31 July 2013 at 07:17:15 UTC, deadalnix wrote:
> In C++, std::string own its own copy of the string. So it is safe to pass a D const char* to the constructor.
I thought the discussion was about:
void someFun(std::string arg) { ...}
Pass D string to someFun. I do not believe const(char) * is valid.
|
July 31, 2013 Re: Passing string from D to c++ | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Wednesday, 31 July 2013 at 13:39:29 UTC, Dicebot wrote:
> On Wednesday, 31 July 2013 at 13:15:58 UTC, John Colvin wrote:
>> Any ideas how we can get around this? Some std c++ type instrinsics in dmd?
>
> Maybe http://d.puremagic.com/issues/show_bug.cgi?id=10077 can help?
Yikes that's quite a rabbit hole, it's all a bit beyond me tbh.
|
Copyright © 1999-2021 by the D Language Foundation