Error - Redefinition of 'GoString' as different kind of symbol

253 views
Skip to first unread message

laszlo...@forgerock.com

unread,
Nov 30, 2016, 7:38:23 AM11/30/16
to golang-nuts
Hi, 

I'm trying to write a CGo shared library and I get a error always because I found these two definition in https://github.com/golang/go/blob/master/src/cmd/cgo/out.go

typedef struct { const char *p; GoInt n; } GoString;

_GoString_ GoString(char *p);

 
I just wrote a simple sample code to reproduce the problem. Most of the sample I found in Internet call C function from Go and that works well but my C function want to call Go code so in my C I include the Header file of other Go Shared library which contains the GO_CGO_PROLOGUE_H header definition so it defines the GoString type. Go also defines the GoString function to convert C string to Go string and due to the unfortunate name collision I don't know how to avoid the compiler error. This code is just a short example in case anyone know a solution so I can try it with my real world code. 


So far the only solution if I completely avoid using the GO_CGO_PROLOGUE_H header so from C I don't use any Goxxx types which makes impossible to do Go->C->Go calls. So if my main code is in Go and I want to use it from C I must write my project in C so do C->Go.

//go:binary-only-package
//package name: ecjni
package main

/*
#include <stdlib.h>

#ifndef GO_CGO_PROLOGUE_H
#define GO_CGO_PROLOGUE_H

typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef unsigned long long GoUint64;
typedef GoInt64 GoInt;
typedef GoUint64 GoUint;
typedef __SIZE_TYPE__ GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
typedef float _Complex GoComplex64;
typedef double _Complex GoComplex128;

typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];

typedef struct { const char *p; GoInt n; } GoString;
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;

#endif

extern void printout(GoString p0);

void doC(const char* msg) {
GoString gs;
gs.p = msg;
gs.n = strlen(msg);
printout(gs);
}

*/
import "C"

//export printout
func printout(msg string) {
println(msg)
}

func calC(msg string) {
C.doC(C.CString(msg))
}

func main() {
println("go build -buildmode=c-shared -o libjni.dylib main.go")
calC("Hello")
}

Tamás Gulácsi

unread,
Nov 30, 2016, 8:39:02 AM11/30/16
to golang-nuts
Simple: don't use GString, but pass the *char,int (pointer and length) to a Go helper which treat it as a []byte.
Reply all
Reply to author
Forward
0 new messages