diff --git a/_demo/cppmintf/cpp_multi_intf.go b/_demo/cppmintf/cpp_multi_intf.go new file mode 100644 index 00000000..38e5797e --- /dev/null +++ b/_demo/cppmintf/cpp_multi_intf.go @@ -0,0 +1,50 @@ +package main + +import ( + "unsafe" + + "github.com/goplus/llgo/_demo/cppmintf/foo" + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/math" +) + +type Bar struct { + foo.Callback + a int +} + +func NewBar(a int) *Bar { + return &Bar{ + Callback: foo.Callback{ + ICalc: foo.ICalc{ + Vptr: &foo.ICalcVtbl{ + Calc: c.Func((*Bar).sqrt), + }, + }, + IVal: foo.IVal{ + Vptr: &foo.IValVtbl{ + Val: c.Func(bar_IVal_getA), + }, + }, + }, + a: a, + } +} + +func (p *Bar) getA() int { + return p.a +} + +func bar_IVal_getA(this c.Pointer) int { + const delta = -int(unsafe.Offsetof(foo.Callback{}.IVal)) + return (*Bar)(c.Advance(this, delta)).getA() +} + +func (p *Bar) sqrt(v float64) float64 { + return math.Sqrt(v) +} + +func main() { + bar := NewBar(1) + foo.F(&bar.Callback) +} diff --git a/_demo/cppmintf/foo/bar/bar.cpp b/_demo/cppmintf/foo/bar/bar.cpp new file mode 100644 index 00000000..99c6e97d --- /dev/null +++ b/_demo/cppmintf/foo/bar/bar.cpp @@ -0,0 +1,17 @@ +#include +#define interface struct + +interface ICalc { + virtual double calc(double v) = 0; +}; + +interface IVal { + virtual int val() = 0; +}; + +class Callback : public ICalc, public IVal { +}; + +extern "C" void f(Callback* cb) { + printf("val: %d\ncalc(2): %lf\n", cb->val(), cb->calc(2)); +} diff --git a/_demo/cppmintf/foo/foo.go b/_demo/cppmintf/foo/foo.go new file mode 100644 index 00000000..a318db70 --- /dev/null +++ b/_demo/cppmintf/foo/foo.go @@ -0,0 +1,42 @@ +package foo + +import ( + "unsafe" +) + +const ( + LLGoFiles = "bar/bar.cpp" + LLGoPackage = "link" +) + +// ----------------------------------------------------------------------------- + +type ICalc struct { + Vptr *ICalcVtbl +} + +type ICalcVtbl struct { + Calc unsafe.Pointer +} + +// ----------------------------------------------------------------------------- + +type IVal struct { + Vptr *IValVtbl +} + +type IValVtbl struct { + Val unsafe.Pointer +} + +// ----------------------------------------------------------------------------- + +type Callback struct { + ICalc + IVal +} + +//go:linkname F C.f +func F(cb *Callback) + +// ----------------------------------------------------------------------------- diff --git a/_demo/cppmintf/foo/llgo_autogen.lla b/_demo/cppmintf/foo/llgo_autogen.lla new file mode 100644 index 00000000..86c4cc60 Binary files /dev/null and b/_demo/cppmintf/foo/llgo_autogen.lla differ