On Mon, Nov 6, 2017 at 10:29 AM, Chun Zhang <chunzh...@gmail.com> wrote: > Thank you Ian!! That does make sense. > > Can you please elaborate why hardcoding device = "eth1" works? What is the > difference here?
I'm sorry, I'm not sure I really understand the question. The pointer passing rules apply only when calling functions written in C rather than Go. When you write `device = "eth1"` there is no C function involved. Ian > On Mon, Nov 6, 2017 at 1:19 PM, Ian Lance Taylor <i...@golang.org> wrote: >> >> 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.