Closed fionalde closed 9 months ago
Can you attach minimal reproduction code please?
import core.stdc.stdio; import cppd.betterc; extern(C++) {
interface L{
void testLFunc();
}
class Base:L{
this(){
puts("base constract");
}
override void testLFunc(){
puts("call override function");
}
void testBaseFunc(){
puts("call Base function");
}
~this(){
puts("base close");
}
}
class Test:Base{
int i;
int y;
this(int i,int y){
this.i= i;
this.y = y;
}
~this(){
puts("hello world");
}
}
}
void test(L base){ base.testLFunc(); }
extern(C) int main() {
Test t = _new!Test(20,40);
printf("t.i is => %d \n",t.i);
test(t);
_free(t);
return 0;
}
When running to printf, it will get stuck there and then I got this Error Program exited with code -1073741819 Runs normally when I use abstract classes
Thanks for reporting, I'll look into it today
Hmm, when I run this it gives me segfault when calling L.testLFunc
==3880== Memcheck, a memory error detector
==3880== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==3880== Using Valgrind-3.21.0 and LibVEX; rerun with -h for copyright info
==3880== Command: ./bin/cppd_test
==3880==
Starting tests
Testing extern(C++) class
Hello world, 2, 1, 2
base construct
t.i is => 20
==3880== Invalid read of size 8
==3880== at 0x10E31B: test.testLFunc(test.L) (test.d:64)
==3880== by 0x10E438: main (test.d:82)
==3880== Address 0x0 is not stack'd, malloc'd or (recently) free'd
Gotta look deeper into that
I did not try to determine whether the pointer address is consistent if the parameter type is a parent or a subclass, at that time I tried custom object.d, in the self-implemented destroy In the function, the parameter type is the parent class and the subclass in the case of the parameter pointer address is different, I suspect that is this problem, want to solve and at least understand how to deal with the offset, before probably looked at object.d seems to be calculated by the type system, but I can not find this information, I am not a professional c++ Development, which is still not understood, stopped looking at it at that time
Ok, so, the problem is
(cast(L) t).testLFunc();
Which is a known problem with dynamic casting (https://issues.dlang.org/show_bug.cgi?id=21690), to work around it you can use static casting instead
(cast(L) cast(void*) t).testLFunc();
Which works as intended, but a bit ugly, so I've added new function (to now renamed module betterc
->classes
) _cast
which does exactly that (commit 9b68957) and also added a readme segment dedicated to how to use cppd.classes
_cast!L(t).testLFunc();
And that's all that I can do with it as it is a "compiler bug" over of which I have no power.
Thanks again for bringing up this bug and I hope now it won't cause any problems
Crashes when function arguments use interface types