gocpperror

package module
v0.0.0-...-ccb11a9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 30, 2021 License: MIT Imports: 2 Imported by: 2

README

gocpperror (Still working on this readme, but enough is here to get started using the package)

gocpprror is a go pacakge for easily handling C++ exceptions thrown in C++ classes that are dynamically linked to your Go application.

Note: I plan on extending this to also handle C++ exceptions thrown outside of C++ classes and in regular non class functions too.

Requirements

To use this go package you will need my cpperror library.

To install clone the repository at https://github.com/MartinSimango/cpperror

  1. git clone https://github.com/MartinSimango/cpperror && cd cpperror
  2. sudo make build install

The install command will copy the built library and the libary headers files into /usr/local/lib and /usr/local/include respectively.

How to use

Lets we say we had a c++ class Foo that we wanted to wanted to use in our go program.

Foo.hpp


//Foo.hpp

class Foo {

  int div(int a, int b) {
    if (b < 0) {
        throw new FooException("Cannot divide by 0"); //FooException has to extend the ErrorException class found in ErrorException.hpp
    }
    return a/b;
  }
}

If we wanted to use this class in Go using cgo we would need to create a wrapper interface file in C in order to wrap our c++ code.
We'd also need to wrapper a c++ class that implements our code in the C wrapper file.

For example the wrapper interface file would be called Foo.h and the implementation of the functions defined in this file will be in a class called FooWrapper.cpp.

Examples of the two classes can be seen below.

FooWrapper.h

//FooWrapper.h


#pragma once

#ifdef __cplusplus
extern "C" {
#endif

void * NewFoo();

void * div(void * foo,int a, int b);

#ifdef __cplusplus
}  // extern "C"
#endif

FooWrapper.cpp

//FooWrapper.cpp
#include "Foo.hpp"
#include "FooWrapper.h"
#include <cpperror/ErrorVoid.hpp> //imported from the https://github.com/MartinSimango/cpperror repo


Foo * asFoo(void * foo) {
   return reinterpret_cast<Foo*>(foo); 
}

void * NewFoo() {
  Foo * foo = new Foo();
  return foo;
}

void * div(void *foo, int a, int b) {
  Error<int, Foo, int, int> * error = new Error<int, Foo,int, int>(&Foo::div, AsFoo(foo));
  error->Execute(a, b);
  return dynamic_cast<ErrorBase*>(error);
}

In our Go program we could our C function like this

// #cgo LDFLAGS: -lfoo
// #include <FooWrapper.h>

import "C"

package main

import (
	"fmt"
	"os"
	"unsafe"

	cerror "github.com/MartinSimango/gocpperror"
)

type Foo struct {
  ptr unsafe.Pointer
}


func main() {
  foo := Foo{}
  foo.ptr = C.NewFoo()
  cerr := cpperror.CPPErrorImpl{}
  cerr.Ptr := C.div(foo.ptr, C.int(a), C.int(b))  // (1) a and b be will integers
  errorMessage := cerr.GetErrorMessage()
  if errorMessage != nil { // (2)
    fmt.Println(cerr) // (3) 
    cerr.Free()
    os.Exit(1)
  }
  
  div_ans := cerr.GetFuncReturnValue().(int) // (4)
  
  cerr.Free() // (5)

  
}

(1) Our C++ function that throws an exception will be called.
(2) We check to see if our C++ function threw an exception.
(3) If the C++ function threw an exception we can just print the error and exit the application.
(4) If the C++ function never threw an exception we can just get the result of the function call.
(5) Free the memory that was allocated within the C library.

Documentation

Index

Constants

View Source
const BOOL_TYPE = int(C.BOOL_TYPE)
View Source
const DOUBLE_TYPE = int(C.DOUBLE_TYPE)
View Source
const INT_TYPE = int(C.INT_TYPE)
View Source
const STRING_TYPE = int(C.STRING_TYPE)

Variables

This section is empty.

Functions

This section is empty.

Types

type CPPError

type CPPError interface {
	error
	GetFuncReturnType() int
	GetFuncReturnValue() interface{}
	GetFuncReturnStructValue(CStructTypeId uint32) unsafe.Pointer
	GetErrorMessage() *string
	Free()
}

type CPPErrorImpl

type CPPErrorImpl struct {
	// contains filtered or unexported fields
}

func NewCPPErrorImpl

func NewCPPErrorImpl(ptr unsafe.Pointer) *CPPErrorImpl

NewCPPErrorImpl is a constructor

func (*CPPErrorImpl) Error

func (cppe *CPPErrorImpl) Error() string

Error returns the error message

func (*CPPErrorImpl) Free

func (cppe *CPPErrorImpl) Free()

Free deallocates the memory allocated to cppe.Ptr.

func (*CPPErrorImpl) GetErrorMessage

func (cppe *CPPErrorImpl) GetErrorMessage() *string

GetErrorMessage returns a pointer to the error message

func (*CPPErrorImpl) GetFuncReturnStructValue

func (cppe *CPPErrorImpl) GetFuncReturnStructValue(CStructTypeId uint32) unsafe.Pointer

GetFuncReturnStructValue returns the value of the cppe's delgated function. The return type will be the type that maps to the Struct with id CStructTypeId

func (*CPPErrorImpl) GetFuncReturnType

func (cppe *CPPErrorImpl) GetFuncReturnType() int

GetFuncReturnType returns the type id of the cppe's delegated function

func (*CPPErrorImpl) GetFuncReturnValue

func (cppe *CPPErrorImpl) GetFuncReturnValue() interface{}

GetFuncReturnValue returns the value of the cppe's delegated function

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL