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 uint8
s! 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:
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.
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).
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.