I have a C wrapper of C++ library that I want to use with golang. Overall path of callback that I want is golang->C->C++. I tested part C->C++, but face difficulties with golang->C part.
As said in wiki, I tried this example. It works good on linux, but when I compile it on windows it fails on "extern" keyword because I compile C library and golang separately.
I thought that it is possible to split C library on part that doesn't know about golang at all. And put this callback with "extern" keyword into golang directory. But I think this will not fit me because function that takes callback and I need looks like this:
ClipperPaths64 *
clipper_clipperoffset_execute_gocallback(void *mem, ClipperClipperOffset *c, uintptr_t h) {
auto result = new (mem) Paths64();
from_c(c)->Execute(from_c(h), *result);
return to_c(result);
}
You see that I use from_c(...)
functions and they return C++ objects, they are not exposed publicly of this library and I cannot use them.
I would share more code if it would be helpful.
Well, it is solved and as reference you may peek my repo: here
Solution: Just move function that is "extern" to directory of golang module. You will compile separately C/C++ library and alongside golang code you can place callbacks and whatever you will define in golang file.
Example of callback.c:
// define delta callback
double delta_callback(
uintptr_t h,
ClipperPath64 *path, ClipperPathD *path_normals,
size_t curr_idx, size_t prev_idx)
{
return goDeltaCallback64(h, path, path_normals, curr_idx, prev_idx);
}
callback.h:
#ifndef CLIBRARY_H
#define CLIBRARY_H
#include <stddef.h>
#include "../lib/clipper2c/clipper2c.h"
typedef double (*callbackfunc) (
uintptr_t h, ClipperPath64 *path, ClipperPathD *path_normals,
size_t curr_idx, size_t prev_idx);
double delta_callback(
uintptr_t h,
ClipperPath64 *path, ClipperPathD *path_normals,
size_t curr_idx, size_t prev_idx);
extern double goDeltaCallback64(uintptr_t h, ClipperPath64 *path,
ClipperPathD *path_normals, size_t curr_idx,
size_t prev_idx);
#endif
.go:
//export goDeltaCallback64
func goDeltaCallback64(
h C.uintptr_t,
path *C.ClipperPath64,
path_normals *C.ClipperPathD,
curr_idx C.size_t,
prev_idx C.size_t,
) C.double {
fn := cgo.Handle(h).Value().(ClipperOffsetCallback)
gopath := &Path64{
p: path,
}
gopath_normals := &PathD{
p: path_normals,
}
return C.double(fn(gopath, gopath_normals, int(curr_idx), int(prev_idx)))
}