douyingtai6662 2016-02-08 06: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 15: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 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分