在Go中访问原始C结构的字段

I'm trying to use OpenCV from Go. OpenCV defines a struct CvMat that has a data field:

typedef struct CvMat
{
    ...
    union
    {
        uchar* ptr;
        short* s;
    } data;
}

I'm using the go bindings for opencv found here. This has a type alias for CvMat:

type Mat C.CvMat

Now I have a Mat object and I want to access the data field on it. How can I do this? If I try to access _data, it doesn't work. I printed out the fields on the Mat object with the reflect package and got this:

...
{data github.com/lazywei/go-opencv/opencv [8]uint8  24 [5] false}
...

So there is a data field on it, but it's not even the same type. It's an array of 8 uint8s! I'm looking for a uchar* that is much longer than 8 characters. How do I get to this uchar?

The short answer is that you can't do this without modifying go-opencv. There are a few impediments here:

  1. When you import a package, you can only use identifiers that have been exported. In this case, data does not start with an upper case letter, so is not exported.

  2. Even if it was an exported identifier, you would have trouble because Go does not support unions. So instead the field has been represented by a byte array that matches the size of the underlying C union (8 bytes in this case, which matches the size of a 64-bit pointer).

  3. Lastly, it is strongly recommended not to expose cgo types from packages. So even in cases like this where it may be possible to directly access the underlying C structure, I would recommend against it.

Ideally go-opencv would provide an accessor for the information you are after (presumably one that could check which branch of the union is in use, rather than silently returning bad data. I would suggest you either file a bug report on the package (possibly with a patch), or create a private copy with the required modifications if you need the feature right away.