From 2314c41103a789787eed18e46ca8df75c6ee02c6 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 23 Jun 2024 16:12:01 +0800 Subject: [PATCH] cppmintf: implements multiple intefaces in c++ --- _demo/cppmintf/cpp_multi_intf.go | 50 ++++++++++++++++++++++++++++ _demo/cppmintf/foo/bar/bar.cpp | 17 ++++++++++ _demo/cppmintf/foo/foo.go | 42 +++++++++++++++++++++++ _demo/cppmintf/foo/llgo_autogen.lla | Bin 0 -> 411 bytes 4 files changed, 109 insertions(+) create mode 100644 _demo/cppmintf/cpp_multi_intf.go create mode 100644 _demo/cppmintf/foo/bar/bar.cpp create mode 100644 _demo/cppmintf/foo/foo.go create mode 100644 _demo/cppmintf/foo/llgo_autogen.lla 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 0000000000000000000000000000000000000000..86c4cc60eb1532abbabe5541c544cb0edf581145 GIT binary patch literal 411 zcmWIWW@Zs#U|`^2h-thYk(gE4`5eew!ozGh~*8$lB8eTUVmC|ix zS}tVFaj!^Q{_xVDXTR9uj%=91^VgGMOKqy4cC4pti;R9>%+&oXjK_9VY_DZs;-->e z-*7zsz18U|%Y)B~+XMoaXYF0~MRbOdd&~?=u|MYx>weY$lKcNC`ud-