英文:
Accessing field on original C struct in Go
问题
我正在尝试使用Go语言中的OpenCV。OpenCV定义了一个名为CvMat
的结构体,其中包含一个data
字段:
typedef struct CvMat
{
...
union
{
uchar* ptr;
short* s;
} data;
}
我正在使用这里找到的go-opencv绑定。它为CvMat
定义了一个类型别名:
type Mat C.CvMat
现在我有一个Mat
对象,我想访问它的data
字段。我该如何做?如果我尝试访问_data
,它不起作用。我使用reflect
包打印了Mat
对象的字段,得到了以下结果:
...
{data github.com/lazywei/go-opencv/opencv [8]uint8 24 [5] false}
...
所以它确实有一个data
字段,但它甚至不是相同的类型。它是一个包含8个uint8
的数组!我正在寻找一个比8个字符长得多的uchar*
指针。我该如何获取这个uchar
指针呢?
英文:
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
?
答案1
得分: 3
简短回答是,如果不修改go-opencv
,你无法做到这一点。这里有几个障碍:
-
当你导入一个包时,你只能使用已导出的标识符。在这种情况下,
data
不是以大写字母开头,所以它没有被导出。 -
即使它是一个已导出的标识符,你也会遇到问题,因为Go语言不支持联合类型。所以,字段被表示为与底层C联合类型大小相匹配的字节数组(在这种情况下是8个字节,与64位指针的大小相匹配)。
-
最后,强烈建议不要从包中公开
cgo
类型。所以,即使在像这样的情况下可能直接访问底层C结构的情况下,我也建议不要这样做。
理想情况下,go-opencv
应该提供一个访问你所需信息的接口(可能可以检查联合类型的哪个分支正在使用,而不是返回错误数据)。我建议你要么在该包上提交一个错误报告(可能附带一个补丁),要么如果你需要立即使用该功能,就创建一个带有所需修改的私有副本。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论