Jump to page: 1 2
Thread overview
C++ binding issues with C++ function returning a simple POD struct.
May 21, 2017
ParticlePeter
May 21, 2017
Stefan Koch
May 21, 2017
ParticlePeter
May 22, 2017
Jerry
May 22, 2017
Mike Parker
May 22, 2017
Nicholas Wilson
May 22, 2017
evilrat
May 22, 2017
ParticlePeter
May 22, 2017
evilrat
May 22, 2017
ParticlePeter
May 22, 2017
evilrat
May 22, 2017
ParticlePeter
May 22, 2017
evilrat
May 22, 2017
ParticlePeter
May 22, 2017
ParticlePeter
May 22, 2017
Jerry
May 22, 2017
ParticlePeter
May 23, 2017
evilrat
May 22, 2017
Jerry
May 21, 2017
I am statically linking to ImGui [1] on Win 10 x64, quite successfully till this issue came up. The noticed error so far comes when an ImGui function returns an ImVec2, a simple POD struct of two float members. I can use this struct as argument to functions but when it is returned from a function I get a 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF. I can even debug the process with Visual Studion, mixed d and c++ sources. The functions I tested return data from some internal global ImGui data, which I can fully examine, the crash happens on the return statement. Moreover, some functions have variations which return only one component from that ImVec2 POD, which do work as expected, e.g.:

    ImVec2          GetCursorPos();   // crash
    float           GetCursorPosX();  // works
    float           GetCursorPosY();  // works

The latter do basically the same as the first one, but return ImVec.x or .y respectively.

How could I further debug this?
If somebody would be willing to look at the source, the binding is here [2].


[1] https://github.com/ocornut/imgui
[2] https://github.com/ParticlePeter/imgui_lib





May 21, 2017
On Sunday, 21 May 2017 at 19:33:06 UTC, ParticlePeter wrote:
> I am statically linking to ImGui [1] on Win 10 x64, quite successfully till this issue came up. The noticed error so far comes when an ImGui function returns an ImVec2, a simple POD struct of two float members. I can use this struct as argument to functions but when it is returned from a function I get a 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF. I can even debug the process with Visual Studion, mixed d and c++ sources. The functions I tested return data from some internal global ImGui data, which I can fully examine, the crash happens on the return statement. Moreover, some functions have variations which return only one component from that ImVec2 POD, which do work as expected, e.g.:
>
> [...]

are you aware of https://github.com/Extrawurst/DerelictImgui ?
May 21, 2017
On Sunday, 21 May 2017 at 19:58:32 UTC, Stefan Koch wrote:
> On Sunday, 21 May 2017 at 19:33:06 UTC, ParticlePeter wrote:
>> I am statically linking to ImGui [1] on Win 10 x64, quite successfully till this issue came up. The noticed error so far comes when an ImGui function returns an ImVec2, a simple POD struct of two float members. I can use this struct as argument to functions but when it is returned from a function I get a 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF. I can even debug the process with Visual Studion, mixed d and c++ sources. The functions I tested return data from some internal global ImGui data, which I can fully examine, the crash happens on the return statement. Moreover, some functions have variations which return only one component from that ImVec2 POD, which do work as expected, e.g.:
>>
>> [...]
>
> are you aware of https://github.com/Extrawurst/DerelictImgui ?

Yes I am, its (understandably) not being updated too regularly, it goes the route of creating a C binding, and a D binding on top, lot of work. We should be able to bind the C++ variant directly by now I think.
May 22, 2017
On Sunday, 21 May 2017 at 19:33:06 UTC, ParticlePeter wrote:
> I am statically linking to ImGui [1] on Win 10 x64, quite successfully till this issue came up. The noticed error so far comes when an ImGui function returns an ImVec2, a simple POD struct of two float members. I can use this struct as argument to functions but when it is returned from a function I get a 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF. I can even debug the process with Visual Studion, mixed d and c++ sources. The functions I tested return data from some internal global ImGui data, which I can fully examine, the crash happens on the return statement. Moreover, some functions have variations which return only one component from that ImVec2 POD, which do work as expected, e.g.:
>
>     ImVec2          GetCursorPos();   // crash
>     float           GetCursorPosX();  // works
>     float           GetCursorPosY();  // works
>
> The latter do basically the same as the first one, but return ImVec.x or .y respectively.
>
> How could I further debug this?
> If somebody would be willing to look at the source, the binding is here [2].
>
>
> [1] https://github.com/ocornut/imgui
> [2] https://github.com/ParticlePeter/imgui_lib

Probably because the D side is expecting to have the struct returned in a pointer allocated by the callee and then the C++ puts it in regs and BOOM.

If you wrap the C++ side to return the struct by a pointer then use that in D, then it should work.

May 22, 2017
On Monday, 22 May 2017 at 01:27:22 UTC, Nicholas Wilson wrote:
> On Sunday, 21 May 2017 at 19:33:06 UTC, ParticlePeter wrote:
>> I am statically linking to ImGui [1] on Win 10 x64, quite successfully till this issue came up. The noticed error so far comes when an ImGui function returns an ImVec2, a simple POD struct of two float members. I can use this struct as argument to functions but when it is returned from a function I get a 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF. I can even debug the process with Visual Studion, mixed d and c++ sources. The functions I tested return data from some internal global ImGui data, which I can fully examine, the crash happens on the return statement. Moreover, some functions have variations which return only one component from that ImVec2 POD, which do work as expected, e.g.:
>>
>>     ImVec2          GetCursorPos();   // crash
>>     float           GetCursorPosX();  // works
>>     float           GetCursorPosY();  // works
>>
>> The latter do basically the same as the first one, but return ImVec.x or .y respectively.
>>
>> How could I further debug this?
>> If somebody would be willing to look at the source, the binding is here [2].
>>
>>
>> [1] https://github.com/ocornut/imgui
>> [2] https://github.com/ParticlePeter/imgui_lib
>
> Probably because the D side is expecting to have the struct returned in a pointer allocated by the callee and then the C++ puts it in regs and BOOM.
>
> If you wrap the C++ side to return the struct by a pointer then use that in D, then it should work.

And this is actually D problem. In fact first bug report on this thing was dated back to  2014. Still not fixed.


There is possible hacky workaround to try - put struct as pointer arg instead of return and make helper method to use it, like this

-------- HACK -------------------
// extern(C++) of course
void GetCursorPos(ImVec2* v);

// helper
ImVec2 GetCursorPos()
{
 ImVec2 temp;
 GetCursorPos(&temp);
 return temp;
}
----------------------------------


May 22, 2017
On Monday, 22 May 2017 at 01:27:22 UTC, Nicholas Wilson wrote:
> On Sunday, 21 May 2017 at 19:33:06 UTC, ParticlePeter wrote:
>> I am statically linking to ImGui [1] on Win 10 x64, quite successfully till this issue came up. The noticed error so far comes when an ImGui function returns an ImVec2, a simple POD struct of two float members. I can use this struct as argument to functions but when it is returned from a function I get a 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF. I can even debug the process with Visual Studion, mixed d and c++ sources. The functions I tested return data from some internal global ImGui data, which I can fully examine, the crash happens on the return statement. Moreover, some functions have variations which return only one component from that ImVec2 POD, which do work as expected, e.g.:
>>
>>     ImVec2          GetCursorPos();   // crash
>>     float           GetCursorPosX();  // works
>>     float           GetCursorPosY();  // works
>>
>> The latter do basically the same as the first one, but return ImVec.x or .y respectively.
>>
>> How could I further debug this?
>> If somebody would be willing to look at the source, the binding is here [2].
>>
>>
>> [1] https://github.com/ocornut/imgui
>> [2] https://github.com/ParticlePeter/imgui_lib
>
> Probably because the D side is expecting to have the struct returned in a pointer allocated by the callee and then the C++ puts it in regs and BOOM.

Thanks for your reply, but that would be wired. The function signature clearly tells me: I am returning a (copy of a) ImVec2 on the stack. How could D expect any kind of pointer in that case? And should that not be true for the variants returning float as well? Almost same signature.
But I agree with enhanced fishiness happening in the interface.

> If you wrap the C++ side to return the struct by a pointer then use that in D, then it should work.

I've hoped to avoid extra work other then translating the header, but now I fear it won't. I'll give it a try.


May 22, 2017
On Monday, 22 May 2017 at 01:39:04 UTC, evilrat wrote:
> On Monday, 22 May 2017 at 01:27:22 UTC, Nicholas Wilson wrote:
>>
>> Probably because the D side is expecting to have the struct returned in a pointer allocated by the callee and then the C++ puts it in regs and BOOM.
>>
>> If you wrap the C++ side to return the struct by a pointer then use that in D, then it should work.
>
> And this is actually D problem. In fact first bug report on this thing was dated back to  2014. Still not fixed.

Thanks for your reply, do you have any links to some bug report of that issue?

> There is possible hacky workaround to try - put struct as pointer arg instead of return and make helper method to use it, like this
>
> -------- HACK -------------------
> // extern(C++) of course
> void GetCursorPos(ImVec2* v);
>
> // helper
> ImVec2 GetCursorPos()
> {
>  ImVec2 temp;
>  GetCursorPos(&temp);
>  return temp;
> }
> ----------------------------------

Actually, your example would work just fine, my problem and possible solution is the other way around :-). First I'll try to force a copy with a wrapper func and same sig.

May 22, 2017
On Monday, 22 May 2017 at 06:33:37 UTC, ParticlePeter wrote:
> On Monday, 22 May 2017 at 01:39:04 UTC, evilrat wrote:
>>
>> And this is actually D problem. In fact first bug report on this thing was dated back to  2014. Still not fixed.
>
> Thanks for your reply, do you have any links to some bug report of that issue?
>

Just search for "c++ struct"
https://issues.dlang.org/buglist.cgi?quicksearch=c%2B%2B%20struct

https://issues.dlang.org/show_bug.cgi?id=13207
https://issues.dlang.org/show_bug.cgi?id=16527

>
> Actually, your example would work just fine, my problem and possible solution is the other way around :-). First I'll try to force a copy with a wrapper func and same sig.

You mean from D to C++? Well, that sucks.
May 22, 2017
On Monday, 22 May 2017 at 07:24:20 UTC, evilrat wrote:
> On Monday, 22 May 2017 at 06:33:37 UTC, ParticlePeter wrote:
>> On Monday, 22 May 2017 at 01:39:04 UTC, evilrat wrote:
>>>
>>> And this is actually D problem. In fact first bug report on this thing was dated back to  2014. Still not fixed.
>>
>> Thanks for your reply, do you have any links to some bug report of that issue?
>>
>
> Just search for "c++ struct"
> https://issues.dlang.org/buglist.cgi?quicksearch=c%2B%2B%20struct
>
> https://issues.dlang.org/show_bug.cgi?id=13207
> https://issues.dlang.org/show_bug.cgi?id=16527

That's really old, and of essential requirement I would assume. Thanks, I will comment the bug.

>>
>> Actually, your example would work just fine, my problem and possible solution is the other way around :-). First I'll try to force a copy with a wrapper func and same sig.
>
> You mean from D to C++? Well, that sucks.

No, no, this (other) way around :-), still C++ to D. It actually works btw:

-------- HACK -------------------
// original C++
ImVec2 GetCursorPos();

// C++ helper
void GetCursorPos(ImVec2& result) {
  result = GetCursorPos();
}

// bind with
extern(C++)
void GetCursorPos(ref ImVec2 result);
----------------------------------
May 22, 2017
On Monday, 22 May 2017 at 08:03:07 UTC, ParticlePeter wrote:
>
> No, no, this (other) way around :-), still C++ to D. It actually works btw:
>
> -------- HACK -------------------
> // original C++
> ImVec2 GetCursorPos();
>
> // C++ helper
> void GetCursorPos(ImVec2& result) {
>   result = GetCursorPos();
> }
>
> // bind with
> extern(C++)
> void GetCursorPos(ref ImVec2 result);
> ----------------------------------

My proposed hack is purely D side though O_-
« First   ‹ Prev
1 2