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

标签 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)) 

现在我正试图在 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.CStringC.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/

相关文章:

C,我的 switch 语句在控制台上没有输出

c - 打印每个宽字符字节的字符值

ldap - 嵌套组 LDAP 搜索过滤器

c - Linux在c程序执行过程中更改pgrp(进程组)

csv - 如何将变量保存到现有CSV文件的最后一行

go - 关于从函数返回指针的问题

go - 引用本地的 Go 模块

php - 在 Docker 容器中使用 ldap

java - 无法通过 LDAP 更新 Active Directory 中的员工 ID

c - 具有链接队列输出错误的 BST