我正在努力学习和理解cgo。
我正在Go中编写一个程序,我连接到AD并解析输出。我在C中测试了代码,它正如预期的那样正常工作。 C
中的相关部分是
char *ldap_host = "x.x.x.x";
int ldap_port = 389;
ldap = ldap_init(ldap_host, ldap_port))
现在我正试图在
中继续工作//#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
我在这里做错了什么?
答案 0 :(得分:2)
我首先要了解Go和cgo的基础知识,然后再添加像ldap这样的库的个别特性。一些很好的起点,尤其是官方的cgo doc页面。
从顶部开始:
此处不需要CFLAGS
,但链接器需要LDFLAGS
,运行时需要liblber
。
#cgo LDFLAGS: -lldap -llber
您不能将指向Go字符串的指针作为C *char
传递,它们是不同的类型。 Go中的字符串实际上根本不可寻址,因此如果构建过程到目前为止,这将是一个编译错误。如果需要创建C字符串,请使用C.CString
和C.free
。您还需要为stdlib.h
添加C.free
。
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")
}