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.

Reply via email to