On Mon, Nov 6, 2017 at 4:25 AM, Chun Zhang <chunzh...@gmail.com> wrote: > > Thank you for the reply! > > The C libi.PI_init_global_config has the interface of > PI_init_global_config(int argc, char *argv[]); > so Swig converts it to PI_init_global_config(arg1 int, arg2 *string) > > The code was expecting to a *string. Viper.GetString returns a string as far > as I can see, is that right? So device is a string, not a *string. (verified > with reflect.TypeOf). Everything matches except for the crash :( > > What really puzzles me is that why when passing the parameter using flag is > fine, as well as when hard-coding the value. In both cases, device is still > a string, nothing changed. But whenever trying to read the value from a > config file using viper or just simple json.decoder, the code complains it > is a pointer to a pointer. I mean, I literally did a comparison between the > read-in value and a variable hard-coded as "eth1", it says they are equal.
A Go string contains an internal pointer. Passing a *string to cgo means that you are passing a pointer to a string that contains a pointer, so you are passing a pointer to a pointer. That is invalid according to the cgo pointer passing rules. A Go string is definitely not a C or C++ string. You can not pass a pointer to a Go string to C code that expects a char**. Even if cgo permitted it, it would not work. If SWIG is converting a C char** (or char*[]) to Go *string, then SWIG is getting it wrong. Ian > On Monday, November 6, 2017 at 1:07:46 AM UTC-5, Tamás Gulácsi wrote: >> >> >> 2017. november 6., hétfő 2:11:48 UTC+1 időpontban Chun Zhang a következőt >> írta: >>> >>> Hi, All, >>> >>> I am trying to read a configuration file using Viper, the config file is >>> a very simple json file with one line >>> { >>> "device" : "eth1" >>> } >>> >>> I use the following line to read it >>> >>> device := viper.GetString("device") >>> >>> >>> then passing this var further into a C library with swig generated api as >>> arg2 >>> >>> itc := device //Need to update if there is more devices >>> libpi.PI_init_global_config(1, &itc) >>> >>> func PI_init_global_config(arg1 int, arg2 *string) { >>> >>> >>> >>> I can retrieve the correct value, and can verify that var device does >>> have eth1 as the value when printf it. I even did the compare of device == >>> "eth1", and the result is true. >>> >>> However, when passing this device var to the PI_init_gloable_config API, >>> I got code crashed with the following error >>> >>> panic: runtime error: cgo argument has Go pointer to Go pointer >>> >> >> >> The value you pass to C must not have a pointer which points to a Go >> pointer. >> What are you passing to libpi.PI_init_global_config ? >> I think "device" is already a *string, so &itc is a **string - try >> libpi.PI_init_global_config(device). >> >> (I assume libpi does some conversion, as the proper way to pass a string >> ot C (*char) is to convert the string to *char with cs:=C.CString(*device) >> and later C.free(unsafe.Pointer(cs)) it). >>> >>> >>> If instead of reading this file from configuration json, I hardcode it in >>> the code as >>> >>> device := "eth1" >>> >>> then there is no issue at all. If I read this variable using Flag from >>> command line, like >>> >>> flag.StringVar(&device, "Device", "eth1", "NIC to Listen") >>> >>> >>> there was no problem either. >>> >>> >>> >>> Can anybody please enlighten me what's the difference? Why this error is >>> triggered? I googled quite a bit, but it does not seem to help. I have go >>> 1.8.3 installed. >>> >>> Thanks, >>> Chun > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.