C Third Party Lib CGO

148 views
Skip to first unread message

snmed

unread,
Jul 7, 2021, 1:47:44 PM7/7/21
to golang-nuts

Hi all

Once again I have a 3th party library which looks like this example: https://play.golang.org/p/Ue9yQ8s8Ymq and I need it to integrate in our go tool. The example is working but is still get the warning "possible misuse of unsafe.Pointer".

So my questions are:
  1. Can I use uintptr to hold the void pointer and pass it around go functions?
  2. Can I ignore the warning "possible misuse of unsafe.pointer"?
  3. If not, what would be the proper approach for this example?
Any help is much appreciated...
Sandro


Tamás Gulácsi

unread,
Jul 8, 2021, 10:52:01 AM7/8/21
to golang-nuts
Use *C.MyAppPtr on Go side, don't hide it behind an uintptr.

snmed

unread,
Jul 8, 2021, 1:09:20 PM7/8/21
to golang-nuts
Thanks for your reply. I came across a similar solution today, I made a struct which is visible outside the package and use a private field myApp C.MyAppPtr to hide the C type.
I still wondering why the uintptr version works but shows a warning "possible misuse of unsafe.pointer", CGO documentation is not very clear to me about the intricacies of type conversions between Go and C.

Cheers

Ian Lance Taylor

unread,
Jul 8, 2021, 11:37:16 PM7/8/21
to snmed, golang-nuts
On Thu, Jul 8, 2021 at 10:09 AM snmed <sandro....@gmail.com> wrote:
>
> Thanks for your reply. I came across a similar solution today, I made a struct which is visible outside the package and use a private field myApp C.MyAppPtr to hide the C type.
> I still wondering why the uintptr version works but shows a warning "possible misuse of unsafe.pointer", CGO documentation is not very clear to me about the intricacies of type conversions between Go and C.

There is a very limited number of cases in which it is OK to convert a
pointer to uintptr. Those cases are described at
https://golang.org/pkg/unsafe.

Ian

snmed

unread,
Jul 9, 2021, 2:21:37 AM7/9/21
to golang-nuts
Thx Ian to pointing me to the documentation I read it, but still unsure regarding my example. Probably rule number 4 could apply, so let me go through my example and correct me if I'm wrong.

1. C.CreateApp() creates memory in C code and returns it as  C void pointer
2. Go function CreateApp() returns that as MyAppHwnd (uintptr ) so MyAppHwnd contains a valid C memory address
3. app variable holds still a valid C memory address as long as it is not deleted in C code
4. So calling ShowApp() it should be legit to convert MyAppHwnd  back to an unsafe.Pointer and cast it to C.MyAppPtr. It is still a valid memory address in C and therefore should be interpreted as pointer in C, right?

So therefore the warning can be ignored or do I miss something important?

Cheers
Sandro


Tamás Gulácsi

unread,
Jul 9, 2021, 5:12:22 AM7/9/21
to golang-nuts
An uintptr *is not a pointer*, so 2. is false.
NOTHING at Go's side holds anything regarding MyAppHwnd, and it doesn't seem to be a pointer at all (just a number),
so converting that to an unsafe.Pointer is unsafe.

The rules about uintptr are there for a reason!
Only the allowed use cases are guaranteed to have the desired effect, by preventing any memory movement
int that block of code.

Tamas

snmed

unread,
Jul 9, 2021, 5:26:48 AM7/9/21
to golang-nuts
Yes uintptr is the address the C pointer is pointing to , right? So C doesn't move any memory and therefore the address is still valid until deleted in C code.
If I take the value of uintptr variable,  convert it back with unsafe.Pointer(uintptr) and pass it to a C function, does C not interpret that as a C pointer pointing to the same address as uintptr holds?
Therefore the conversion should be alright?

Sorry for not getting it...

Sandro

Tamás Gulácsi

unread,
Jul 9, 2021, 8:17:48 AM7/9/21
to golang-nuts
The runtime and checks does not know what's inside an uintptr, so converting an uintptr to a(n unsafe.)Pointer
triggers the warnings. Only the special specified cases are legal.

TL;DR; Do not use uintptr.
(More elaborate: do not use an uintptr to store and retrieve a pointer - just store the pointer directly).

Tamas

snmed

unread,
Jul 9, 2021, 8:43:47 AM7/9/21
to golang-nuts
Okay,  will store the pointer directly in a struct as a private field.

Thanks for your time and input, I greatly appreciate it.


Reply all
Reply to author
Forward
0 new messages