I am trying to use a Golang structure in c++ code. To do so, I defined the same structure in both C++ header and in Golang, but when I try to run the project I get the following error:
./runme.go:22:32: cannot use (*Edge)(dataPtr) (value of type *Edge) as example.Edge value in argument to example.Process: *Edge does not implement example.Edge (missing method GetW)
My project has the following structure.
./go.mod
:
module simple
go 1.20
./runme.go
:
package main
import (
"unsafe"
"simple/example"
)
type Edge struct {
X, Y int64
W float64
}
func main() {
data := []Edge {
{1,2,1.0},
{1,3,4.0},
{2,3,3.0},
{2,4,0.5},
}
dataPtr := unsafe.Pointer(&data[0])
example.Process((*Edge)(dataPtr),int64(len(data)), int64(4))
}
Then I have my package that contains the c++ code:
./example/package.go
:
package example
import "C"
./example/example.i
:
%module example
// Typemaps for Edge struct
%typemap(in) Edge {
$1 = *($1_ltype*)($input);
}
%typemap(in) Edge* {
$1 = *($1_ltype*)($input);
}
%typemap(out) Edge {
$result = new $1_btype($1);
}
%{
#include "example.h"
%}
%include "example.h"
./example/example.h
:
#ifndef EXAMPLE_H
#define EXAMPLE_H
typedef struct Edge
{
long int X, Y;
double W;
} Edge;
void Process(Edge *G, long int M, long int N);
#endif
./example/example.cpp
:
#include "example.h"
#include <iostream>
void Process(Edge *G, long int M, long int N) {
// Do some work with the Edge list
std::cout << "|V| = " << N << " -- |E| = " << M << std::endl;
for(int i = 0; i < M; i++) {
std::cout << "(" << G[i].X << ", " << G[i].Y << ") = " << G[i].W << std::endl;
}
}
I tried to implement the GetW and all other methods that it asks for, but at some point it asks for methods that I do not understand what they mean. I believe the problem might be with the typemap in the swig interface that is not connecting properly both structs, but I have no clue how to fix it.
Declare the types in both languages as you have done.
Ignore the C++ type from SWIG:
%ignore Edge;
SWIG generates a Go wrapper with the Go signatures, this wrapper must have the Go Edge
type declared, import it using:
%insert(go_wrapper) %{
// import here
%}
SWIG must also know to use the right type in the wrapper, use the special gotype
typemap for this:
%typemap(gotype) Edge "root.Edge"
Remember to check the example/example.go
file - it will have something that goes as:
func Process(arg1 Edge, arg2 int64, arg3 int64) {
This is the root of your problem. The gotype
typemap should fix this.
Sorry, but I have but a very basic understanding of Go.