Go cgo ldap_init无法确定C.ldap_init的名称类型

时间:2016-02-08 06:22:17

标签: c go ldap cgo

我正在努力学习和理解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

我在这里做错了什么?

1 个答案:

答案 0 :(得分:2)

我首先要了解Go和cgo的基础知识,然后再添加像ldap这样的库的个别特性。一些很好的起点,尤其是官方的cgo doc页面。

从顶部开始:

此处不需要CFLAGS,但链接器需要LDFLAGS,运行时需要liblber

#cgo LDFLAGS: -lldap -llber

您不能将指向Go字符串的指针作为C *char传递,它们是不同的类型。 Go中的字符串实际上根本不可寻址,因此如果构建过程到目前为止,这将是一个编译错误。如果需要创建C字符串,请使用C.CStringC.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")
}