douyingtai6662 2016-02-07 22:22
浏览 74
已采纳

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

I was trying to learn and understand cgo. I am writing a program in Go where I connect to AD and parse the output. I tested the code in C, which is working fine as expected. The relevant part in C is

char *ldap_host = "x.x.x.x";
int   ldap_port     = 389;
ldap = ldap_init(ldap_host, ldap_port)) 

Now I am trying to get the same working in go as

//#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)
}

But I am getting the following error

could not determine kind of name for C.ldap_init

What am I doing wrong here?

  • 写回答

1条回答 默认 最新

  • douchilian1009 2016-02-08 07:51
    关注

    I would start by getting the basics of Go and cgo working before adding the individual peculiarities of a library like ldap. Some good starting points, especially the official cgo doc page.

    Starting from the top:

    You don't need the CFLAGS here, but you will need LDFLAGS for the linker, and liblber for this to run.

    #cgo LDFLAGS: -lldap -llber
    

    You can't pass a pointer to a Go string as a C *char, they are different types. Strings in Go actually aren't addressable at all, so this would be a compile error if the build process got that far. Use C.CString, and C.free if you need to create C strings. You will also need to include stdlib.h for C.free.

        url := C.CString(os.Args[1])
        defer C.free(unsafe.Pointer(url))
    

    Go's int size varies by architecture, and is not C's int type. ldap_port in your example is converted to the default type of int, where you would have needed C.int.

    Finally, the original error in your question has nothing to do with Go or cgo. The ldap_init function is deprecated, and does not exist without setting LDAP_DEPRECATED. You should use the ldap_initialize function. Here is a minimal example that compiles:

    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")
    }
    

    展开全部

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
编辑
预览

报告相同问题?

悬赏问题

  • ¥15 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了
  • ¥50 STM32单片机传感器读取错误
  • ¥15 (关键词-阻抗匹配,HFSS,RFID标签天线)
  • ¥15 机器人轨迹规划相关问题
  • ¥15 word样式右侧翻页键消失
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部