annoing: runtime error: cgo argument has Go pointer to Go pointer

1,157 views
Skip to first unread message

aotto1...@gmail.com

unread,
Jan 29, 2020, 5:12:37 PM1/29/20
to golang-nuts
Hi,

I try to use a C library with GO and have a small problem passing a GO pointer through C into a GO callback.
If I set: "export GODEBUG=cgocheck=0" everything works fine but without I get the error from above

Detail: I want to pass "argv" through C back to GO, the lifetime of the argv is only the lifetime of the Send function call

// PROBLEM: [ErrorCatch] runtime error: cgo argument has Go pointer to Go pointer                                 
// SOLVE:   export GODEBUG=cgocheck=0                                                                             
func (this *MqC) Send (callSig string, argv ...interface{}) {                                                     
  hdl := this.getCTX()                                                                                            
  callSig_ptr := (C.MQ_CST)(C.CString(callSig))                                                                   
  defer C.free((unsafe.Pointer)(callSig_ptr))                                                                     
                                                                                                                  
  var errVal C.enum_MqErrorE = C.gomsgque_Send(hdl, callSig_ptr, C.MQ_INT(len(argv)), unsafe.Pointer(&argv))      
                                                                                                                  
  if (errVal > C.MQ_CONTINUE) { MqErrorC_Check(C.MQ_MNG(hdl), errVal) }                                           
}     
                                                                                                            

The callback is:

//export atomSet
func atomSet( hdl   C.MQ_MNG, objv  unsafe.Pointer, skip  C.MQ_INT, typ C.enum_MqSendE,
                inP  unsafe.Pointer) C.enum_MqErrorE {
  ifc := (*(*[]interface{})(objv))[skip]
...
}

so, what is the GO solution for pass-through problem.

thanks… mfg ao

Bruno Albuquerque

unread,
Jan 29, 2020, 5:19:34 PM1/29/20
to aotto1...@gmail.com, golang-nuts
One way to work this around is to use https://github.com/mattn/go-pointer.

--
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...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/5cfa2851-f81c-4a79-b526-619d064c0d39%40googlegroups.com.

Tamás Gulácsi

unread,
Jan 30, 2020, 12:15:28 AM1/30/20
to golang-nuts
What does "argv" hold?

Can it be a concrete type, not an interface ? That would allow passing it - or if you copy it to a C.malloc-ed array..

Andreas Otto

unread,
Jan 30, 2020, 2:27:14 AM1/30/20
to golang-nuts


Am Donnerstag, 30. Januar 2020 06:15:28 UTC+1 schrieb Tamás Gulácsi:
What does "argv" hold?

Can it be a concrete type, not an interface ? That would allow passing it - or if you copy it to a C.malloc-ed array..


Argv are the arguments of Send and many kind of types are are supported, the atomSet figure out the type and
call the internal code to handle this.

Andreas Otto

unread,
Jan 30, 2020, 2:31:59 AM1/30/20
to golang-nuts


Am Mittwoch, 29. Januar 2020 23:19:34 UTC+1 schrieb Bruno Albuquerque:
One way to work this around is to use https://github.com/mattn/go-pointer.


thanks, but also use this kind of "HASH based and export the hash handle" solution.
But I call this a "slow" solution, because of the hash and locks overhead.

Tamás Gulácsi

unread,
Jan 30, 2020, 8:25:48 AM1/30/20
to golang-nuts
How do you handle the interface types on the C side? If you call back to Go exported functions,
then you shouldn't travel the Go values - push them in a map, and travel the handle (uint64).


Jake Montgomery

unread,
Jan 30, 2020, 12:12:50 PM1/30/20
to golang-nuts
You may call it "slow", but have you actually profiled it in your real world application and found the map lookup to be an actual bottleneck? Unless you are doing something very extreme I would expect the overhead of the Go/C transitions to vastly outweigh a map lookup. Of course, if that is the case there are  clever things you could do to reduce the lookup overhead, but they would depend on the exact details of the extreme thing you are doing that makes it a problem in the first place.

Andreas Otto

unread,
Jan 31, 2020, 11:36:17 AM1/31/20
to golang-nuts

I do nothing on C with this pointer… I just give the Pointer as Argument to an GO callback.

Andreas Otto

unread,
Jan 31, 2020, 11:38:16 AM1/31/20
to golang-nuts
thanks to the Info, don't have profiled this overhead… It was just an assumtion.

Andreas Otto

unread,
Feb 1, 2020, 4:11:50 PM2/1/20
to golang-nuts
No, because this is a printf like feature and the callSig is the format and the option[] are the arguments, which support many different types…


Am Donnerstag, 30. Januar 2020 06:15:28 UTC+1 schrieb Tamás Gulácsi:
What does "argv" hold?

Can it be a concrete type, not an interface ? That would allow passing it - or if you copy it to a C.malloc-ed array..

...
Reply all
Reply to author
Forward
0 new messages