diff --git a/basic-class/Makefile b/basic-class/Makefile new file mode 100644 index 0000000..1454eb9 --- /dev/null +++ b/basic-class/Makefile @@ -0,0 +1,9 @@ +.PHONY: all + +all: main + +bridge.so: + /usr/bin/clang++ -o libbridge.so *.cpp -std=c++20 -O3 -Wall -Wextra -fPIC -shared + +main: bridge.so + go build main.go diff --git a/basic-class/README.md b/basic-class/README.md new file mode 100644 index 0000000..e0623e7 --- /dev/null +++ b/basic-class/README.md @@ -0,0 +1,11 @@ +## Basic Class Example + +Basic class example that shows the bare minimum to work with a couple of classes. + +## Usage: +``` +$ make +$ ./main +2022/03/10 16:32:49 circ.Area() = 5.5417694409323949e+03 +2022/03/10 16:32:49 cyl.Volume() = 1.1083538881864790e+05 +``` diff --git a/basic-class/bridge.cpp b/basic-class/bridge.cpp new file mode 100644 index 0000000..86816f7 --- /dev/null +++ b/basic-class/bridge.cpp @@ -0,0 +1,27 @@ +#include "bridge.h" +#include "circle.hpp" +#include "cylinder.hpp" + +void* DEMO_CircleNew(double radius) { return new Circle(radius); } + +void DEMO_CircleDestroy(void* circle) { + auto ptr = reinterpret_cast(circle); + delete ptr; +} + +double DEMO_CircleArea(const void* circle) { + return reinterpret_cast(circle)->area(); +}; + +void* DEMO_CylinderNew(double radius, double height) { + return new Cylinder(radius, height); +} + +void DEMO_CylinderDestroy(void* cylinder) { + auto ptr = reinterpret_cast(cylinder); + delete ptr; +} + +double DEMO_CylinderVolume(const void* cylinder) { + return reinterpret_cast(cylinder)->volume(); +} diff --git a/basic-class/bridge.h b/basic-class/bridge.h new file mode 100644 index 0000000..b1f8f7b --- /dev/null +++ b/basic-class/bridge.h @@ -0,0 +1,16 @@ +#pragma once +#ifdef __cplusplus +extern "C" { +#endif + +void* DEMO_CircleNew(double radius); +void DEMO_CircleDestroy(void* circle); +double DEMO_CircleArea(const void* circle); + +void* DEMO_CylinderNew(double radius, double height); +void DEMO_CylinderDestroy(void* cylinder); +double DEMO_CylinderVolume(const void* cylinder); + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/basic-class/circle.hpp b/basic-class/circle.hpp new file mode 100644 index 0000000..f5a5795 --- /dev/null +++ b/basic-class/circle.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include + +class Circle { + public: + Circle(double radius) : m_radius{radius} {} + + double area() const { return M_PI * std::pow(m_radius, 2); } + + private: + double m_radius = {}; +}; diff --git a/basic-class/cylinder.hpp b/basic-class/cylinder.hpp new file mode 100644 index 0000000..4e9c32b --- /dev/null +++ b/basic-class/cylinder.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "circle.hpp" + +class Cylinder { + public: + Cylinder(double radius, double height) : m_base{radius}, m_height{height} {} + + double volume() const { return m_base.area() * m_height; } + + private: + Circle m_base = {1}; + double m_height = {}; +}; diff --git a/basic-class/main.go b/basic-class/main.go new file mode 100644 index 0000000..a43422f --- /dev/null +++ b/basic-class/main.go @@ -0,0 +1,58 @@ +package main + +// #cgo LDFLAGS: -L. -lbridge +// #include "bridge.h" +import "C" + +import ( + "log" + "unsafe" +) + +type Circle struct { + ptr unsafe.Pointer +} + +func NewCircle(radius float64) Circle { + return Circle{ + ptr: C.DEMO_CircleNew(C.double(radius)), + } +} + +func (circle Circle) Destroy() { + C.DEMO_CircleDestroy(circle.ptr) +} + +func (circle Circle) Area() float64 { + return float64(C.DEMO_CircleArea(circle.ptr)) +} + +type Cylinder struct { + ptr unsafe.Pointer +} + +func NewCylinder(radius float64, height float64) Cylinder { + return Cylinder{ + ptr: C.DEMO_CylinderNew(C.double(radius), C.double(height)), + } +} + +func (cylinder Cylinder) Destroy() { + C.DEMO_CylinderDestroy(cylinder.ptr) +} + +func (cylinder Cylinder) Volume() float64 { + return float64(C.DEMO_CylinderVolume(cylinder.ptr)) +} + +func main() { + circ := NewCircle(42.0) + defer circ.Destroy() + + log.Printf("circ.Area() = %23.16e", circ.Area()) + + cyl := NewCylinder(42.0, 20) + defer cyl.Destroy() + + log.Printf("cyl.Volume() = %23.16e", cyl.Volume()) +}