我正在尝试学习和理解 cgo。
我正在用 Go 编写一个程序,我连接到 AD 并解析输出。我在 C 中测试了代码,它按预期工作正常。 C
中的相关部分是
char *ldap_host = "x.x.x.x";
int ldap_port = 389;
ldap = ldap_init(ldap_host, ldap_port))
现在我正试图在 go 中实现与 go 相同的工作
//#cgo CFLAGS: -lldap
//#include <ldap.h>
import "C"
func main() {
var hostname *string
hostname = &os.Args[1]
ldap_port := 389
ldap := C.ldap_init(*hostname, ldap_port)
}
但我收到以下错误
could not determine kind of name for C.ldap_init
我在这里做错了什么?
最佳答案
在添加像 ldap 这样的库的个别特性之前,我会首先了解 Go 和 cgo 的基础知识。一些很好的起点,尤其是官方的 cgo 文档页面。
从顶部开始:
您在这里不需要CFLAGS
,但您需要LDFLAGS
用于链接器,以及liblber
才能运行。
#cgo LDFLAGS: -lldap -llber
您不能将指向 Go 字符串的指针作为 C *char
传递,它们是不同的类型。 Go 中的字符串实际上根本不可寻址,因此如果构建过程进行到这一步,这将是一个编译错误。如果需要创建 C 字符串,请使用 C.CString
和 C.free
。您还需要为 C.free
包含 stdlib.h
。
url := C.CString(os.Args[1])
defer C.free(unsafe.Pointer(url))
Go 的 int
大小因架构而异,不是 C 的 int
类型。 ldap_port
在您的示例中被转换为默认类型 int
,您可能需要 C.int
。
最后,您问题中的原始错误与Go或cgo无关。 ldap_init
函数已弃用,如果不设置 LDAP_DEPRECATED
则不存在。您应该使用 ldap_initialize
函数。这是一个最小的编译示例:
package main
import (
"log"
"unsafe"
)
/*
#include <stdlib.h>
#include <ldap.h>
#cgo LDFLAGS: -lldap -llber
*/
import "C"
func main() {
url := C.CString("ldap://127.0.0.1:389/")
defer C.free(unsafe.Pointer(url))
var ldap *C.LDAP
rv := C.ldap_initialize(&ldap, url)
if rv != 0 {
log.Fatalf("ldap_initialize() error %d", rv)
}
log.Println("initialized")
}
关于c - Go cgo ldap_init 无法确定 C.ldap_init 的名称类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35263506/