I'm still on the learning curve with Go, but I've managed to compile and run a Go program that includes a C object file. The objective is to call an existing static C++ library. The call will be a bit like a command line invocation - so a simple C wrapper function is perfectly acceptable, and arguably simpler. Unfortunately, I cannot get Go to recognize this wrapper!
I've simplified my code to the following...
package main
// #cgo CFLAGS: -I. -g -Wall
// #cgo LDFLAGS: -L. -lSMHeatmapLib
// #include <stdlib.h>
// #include "ExternalJSON.h"
import "C"
import (
"fmt"
"unsafe"
)
const MAX_RETURN_BUFFER int = 8192
func main() {
var result_str string;
in_json := "The cat sat on the mat"
in_buff := C.CString(in_json)
defer C.free(unsafe.Pointer(in_buff))
in_sz := C.int( len(in_json) )
out_buff := C.malloc( C.sizeof_char * MAX_RETURN_BUFFER )
defer C.free(unsafe.Pointer(out_buff) )
sz := C.RunWithJSON(in_buff,in_sz, (*C.char)(out_buff),MAX_RETURN_BUFFER);
b:= C.GoBytes(out_buff,sz)
result_str = string(b)
fmt.Printf("Return: >%s<\n", result_str)
}
ExternalJSON.h is as follows:
int RunWithJSON( char* in, int in_len, char* out, int max_out);
And ExternalJSON.c:
#include "ExternalJSON.h"
int RunWithJSON( char* in, int in_len, char* out, int max_out)
{
for (int i=0; i<in_len; i++)
{
out[in_len-1-i] = in[i];
}
int olen = in_len;
// and add a marker on the end
out[olen++] = '#';
out[olen++] = '\0';
return olen;
}
(ie. just a simple test at the moment: String in, String out. As you can guess we'll be working with JSON later) This is built with gcc. (the rest of the library is C++ and uses g++) For the final link I use:
ar rcs $(TARGET) $(OBJS)
To remove the potential for any path issues, I copy the static library and ExternalJSON.h to the same directory as main.go .
Building with go build, the result is:
# _/my/path/main
/usr/bin/ld: $WORK/b001/_x002.o: in function `_cgo_750343fded39_Cfunc_RunWithJSON':
/tmp/go-build/cgo-gcc-prolog:58: undefined reference to `RunWithJSON'
collect2: error: ld returned 1 exit status
Why can't go see the function definition in the library?
Yes I saw: How do you statically link a c library in go using cgo? but the suggested command line invocation of go build did not work either.
ExternalJSON.cand runar, what library are you producing? Are you placing it intoSMHeatmapLib.a? If so, doesnm SMHeatmapLib.asuccessfully showRunWithJSON?extern "C"on, but that may just cover up the fundamental issue (if you're really intending to compile as C, not C++. If your goal is to build it as C++, yes,extern "C"is what you'd want.).