如何在Go包之间传递C对象?

huangapple go评论94阅读模式
英文:

How do I pass C objects between go packages?

问题

当我尝试将main包中的C.int传递给名为common的辅助包中的函数时,我收到以下错误信息:

main.go:24: cannot use argc (type C.int) as type common.C.int in argument to common.GoStrings

common.go中:

/* 
    ...
*/
import "C"

...

func GoStrings(argc C.int, argv **C.char) (args []string) {
    // do stuff
}

main.go中:

/*
#cgo LDFLAGS: -lpam -fPIC
#define PAM_SM_AUTH

#include <security/pam_appl.h>
*/
import "C"

...

func pam_sm_authenticate(pamh *C.pam_handle_t, flags, argc C.int, argv **C.char) C.int {
    args := common.GoStrings(argc, argv)
    ...
}

有没有办法在这些对象之间进行传递?我尝试过将其类型转换为common.C.int,但似乎这不是有效的语法。我希望能够从多个不同的主程序调用GoStrings,这似乎是允许的。

英文:

When I try to pass a C.int from package main to a function in a helper package called common, I get the following error:

main.go:24: cannot use argc (type C.int) as type common.C.int in argument to common.GoStrings

From common.go:

<!-- language: go -->

/* 
    ...
*/
import &quot;C&quot;

...

func GoStrings(argc C.int, argv **C.char) (args []string) {
	// do stuff
}

From main.go:

<!-- language: go -->

/*
#cgo LDFLAGS: -lpam -fPIC
#define PAM_SM_AUTH

#include &lt;security/pam_appl.h&gt;
*/
import &quot;C&quot;

...

func pam_sm_authenticate(pamh *C.pam_handle_t, flags, argc C.int, argv **C.char) C.int {
    args := common.GoStrings(argc, argv)
    ...
}

Is there any way to pass these objects back and forth? I've tried type casting to e.g. common.C.int, but that doesn't seem to be valid syntax. I'd like to be able to call GoStrings from multiple different main programs, and it seems like that should be allowable.

答案1

得分: 3

很抱歉,你不能在不同的包之间传递C类型。你需要在导入C类型的包内执行任何必要的类型转换。根据文档的说明:

Cgo将C类型转换为等效的未导出的Go类型。由于这些转换是未导出的,一个Go包不应该在其导出的API中暴露C类型:在一个Go包中使用的C类型与在另一个Go包中使用的相同C类型是不同的。

如果你有常用的C转换方法,可以考虑使用go generate和一个辅助脚本,在每个需要从主源文件中引用的包中创建这些方法。虽然不如拥有一个公共库那样好,但比手动更新多个包中的文件要好得多。

英文:

Unfortunately you can't pass C types between packages. You'll need to perform any necessary type conversions within the package that is importing the C types. As per the documentation:

> Cgo translates C types into equivalent unexported Go types. Because
> the translations are unexported, a Go package should not expose C
> types in its exported API: a C type used in one Go package is
> different from the same C type used in another.

If you have common C translation methods that you use, consider using go generate with a helper script to create these in each package where it is required from a master source file. Not as nice as solution as having a common library but much better than manually updating files in multiple packages.

huangapple
  • 本文由 发表于 2017年7月24日 21:50:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/45282409.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定