digitalmars.D.learn - C++ binding issues with C++ function returning a simple POD struct.
- ParticlePeter (22/22) May 21 2017 I am statically linking to ImGui [1] on Win 10 x64, quite
- Stefan Koch (2/15) May 21 2017 are you aware of https://github.com/Extrawurst/DerelictImgui ?
- ParticlePeter (5/22) May 21 2017 Yes I am, its (understandably) not being updated too regularly,
- Jerry (3/20) May 22 2017 Not everyone likes the set of 'derelict' libraries. Especially if
- Mike Parker (6/9) May 22 2017 Some of the Derelict packages in the DerelictOrg repo (the SDL2,
- Nicholas Wilson (6/28) May 21 2017 Probably because the D side is expecting to have the struct
- evilrat (16/50) May 21 2017 And this is actually D problem. In fact first bug report on this
- ParticlePeter (6/30) May 21 2017 Thanks for your reply, do you have any links to some bug report
- evilrat (6/15) May 22 2017 Just search for "c++ struct"
- ParticlePeter (16/34) May 22 2017 That's really old, and of essential requirement I would assume.
- evilrat (2/15) May 22 2017 My proposed hack is purely D side though O_-
- ParticlePeter (7/26) May 22 2017 Then I am not getting your hack, this function here, does not
- evilrat (15/21) May 22 2017 you "forge" this signature insted of correct one, I suggest also
- ParticlePeter (5/30) May 22 2017 Never stop learning, that actually works! But only with the
- ParticlePeter (9/43) May 21 2017 Thanks for your reply, but that would be wired. The function
- Jerry (9/31) May 22 2017 IIRC the problem is that it isn't a POD type. ImVec2 has its own
- ParticlePeter (7/16) May 22 2017 Thanks, with any of them, ~this or this(this) (both can be
- evilrat (6/22) May 22 2017 Better check if empty postblit('this(this)' ctor) works well when
- Jerry (2/2) May 22 2017 Note that you also probably need extern(C++) on the struct ImVec2.
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: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.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:Not everyone likes the set of 'derelict' libraries. Especially if you need to statically link to a library.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 22 2017
On Monday, 22 May 2017 at 14:11:35 UTC, Jerry wrote:Some of the Derelict packages in the DerelictOrg repo (the SDL2, GLFW3, and OpenAL bindings off the top of my head -- maybe DerelictPQ as well) support static linking now by either specifying a dub configuration or a -version on the command line. That number will eventually increase.are you aware of https://github.com/Extrawurst/DerelictImgui ?Not everyone likes the set of 'derelict' libraries. Especially if you need to statically link to a library.
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_libProbably 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 21 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: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; } ----------------------------------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_libProbably 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 21 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:Thanks for your reply, do you have any links to some bug report of that issue?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; } ----------------------------------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 21 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: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=16527And 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?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:That's really old, and of essential requirement I would assume. Thanks, I will comment the bug.On Monday, 22 May 2017 at 01:39:04 UTC, evilrat wrote: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=16527And 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?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); ----------------------------------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 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_-
May 22 2017
On Monday, 22 May 2017 at 08:25:45 UTC, evilrat wrote:On Monday, 22 May 2017 at 08:03:07 UTC, ParticlePeter wrote:Then I am not getting your hack, this function here, does not exist on the C++ side. -------- HACK ------------------- // extern(C++) of course void GetCursorPos(ImVec2* v); How is it supposed to work then if there is no definition?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_-
May 22 2017
On Monday, 22 May 2017 at 11:25:31 UTC, ParticlePeter wrote:Then I am not getting your hack, this function here, does not exist on the C++ side. -------- HACK ------------------- // extern(C++) of course void GetCursorPos(ImVec2* v); How is it supposed to work then if there is no definition?you "forge" this signature insted of correct one, I suggest also wrap it some handy version in case this is "suddenly got working" version (PROPER_ABI) { extern(C++) ImVec2 GetCursorPos(); } else // hacky one { extern(C++) void GetCursorPos(ImVec2* v); ... put helper here to match excepted API, in case of C++ class add it to the end as 'final'... } This works because it matches name mangling on this one. And even if its not it is possible to hammer it in with pragma mangle.
May 22 2017
On Monday, 22 May 2017 at 13:03:17 UTC, evilrat wrote:On Monday, 22 May 2017 at 11:25:31 UTC, ParticlePeter wrote:Never stop learning, that actually works! But only with the pragma mangle hammer. Nice, but again some more mangle pragmas. The better way seems to be Jerry's suggestion, works as well, see bellow.Then I am not getting your hack, this function here, does not exist on the C++ side. -------- HACK ------------------- // extern(C++) of course void GetCursorPos(ImVec2* v); How is it supposed to work then if there is no definition?you "forge" this signature insted of correct one, I suggest also wrap it some handy version in case this is "suddenly got working" version (PROPER_ABI) { extern(C++) ImVec2 GetCursorPos(); } else // hacky one { extern(C++) void GetCursorPos(ImVec2* v); ... put helper here to match excepted API, in case of C++ class add it to the end as 'final'... } This works because it matches name mangling on this one. And even if its not it is possible to hammer it in with pragma mangle.
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: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.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_libProbably 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.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 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.: 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_libIIRC the problem is that it isn't a POD type. ImVec2 has its own default constructor. The problem now is that because it no longer is POD, Window's ABI handles it different and doesn't put the value in a register. Now with D is that you aren't allowed to specify your own default constructor, so there's no equivalent way for it to know that it isn't a POD. A way around this is to specify your own destructor or copy constructor in the D ImVec2. I forget what the rules are for it, but I think that should do it.
May 22 2017
On Monday, 22 May 2017 at 14:01:56 UTC, Jerry wrote:IIRC the problem is that it isn't a POD type. ImVec2 has its own default constructor. The problem now is that because it no longer is POD, Window's ABI handles it different and doesn't put the value in a register. Now with D is that you aren't allowed to specify your own default constructor, so there's no equivalent way for it to know that it isn't a POD. A way around this is to specify your own destructor or copy constructor in the D ImVec2. I forget what the rules are for it, but I think that should do it.Thanks, with any of them, ~this or this(this) (both can be empty), the functions work as expected, nice. Also replying your next post, extern(C++) is on for the whole module: https://github.com/ParticlePeter/imgui_lib/blob/master/source/imgui/types.d#L39 but I learned how to link to github lines from your post :-)
May 22 2017
On Monday, 22 May 2017 at 18:51:43 UTC, ParticlePeter wrote:On Monday, 22 May 2017 at 14:01:56 UTC, Jerry wrote:Better check if empty postblit('this(this)' ctor) works well when assign structs though. It would be annoying if passing and assigning structs on D side would do something weird. And, if it works I should probably do this for DirectX bindings as well instead of hack.IIRC the problem is that it isn't a POD type. ImVec2 has its own default constructor. The problem now is that because it no longer is POD, Window's ABI handles it different and doesn't put the value in a register. Now with D is that you aren't allowed to specify your own default constructor, so there's no equivalent way for it to know that it isn't a POD. A way around this is to specify your own destructor or copy constructor in the D ImVec2. I forget what the rules are for it, but I think that should do it.Thanks, with any of them, ~this or this(this) (both can be empty), the functions work as expected, nice. Also replying your next post, extern(C++) is on for the whole module: https://github.com/ParticlePeter/imgui_lib/blob/master/source/imgui/types.d#L39 but I learned how to link to github lines from your post :-)
May 22 2017
Note that you also probably need extern(C++) on the struct ImVec2. https://github.com/ParticlePeter/imgui_lib/blob/master/source/imgui/types.d#L84
May 22 2017