dousha7904
2016-06-18 10:10
浏览 222
已采纳

Cgo可以调用在另一个目录中声明的C函数吗?

It seems that I can't use Cgo to call a C function declared in another directory rather than current Go package.

Codes of all files :

// TestGoCallOC.go
package main
/*
#include "test.h"
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework Foundation
*/
import "C"
import (
    "fmt"
)
func main()  {
    fmt.Println(C.fortytwo())
}

// test.h
#include <stdio.h>
#include <stdlib.h>
int fortytwo();

// test.m
#include "test.h"
int fortytwo() {
    return 42;
}

If I put all the files in one directory:

|--src
   |--TestGoCallOC
      |--TestGoCallOC.go
      |--test.h
      |--test.m

and run the Go main function, these two C functions could be called.

But if I put C files (actually they are Objective-C files) in another direcory:

|--src
   |--TestGoCallOC
      |--TestGoCallOC.go
   |--SomeOCCodes
      |--test.h
      |--test.m

, change the file path of #include "test.h" in preamble to it absolute path, and run the Go main function, these two C functions could not be called.

Error message is

Undefined symbols for architecture x86_64: "_fortytwo", referenced from: __cgo_b3674ecbf56b_Cfunc_fortytwo in TestGoCallOC.cgo2.o (maybe you meant: __cgo_b3674ecbf56b_Cfunc_fortytwo) ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) exit status 2

Did I do something wrong? Or is Cgo not capable of doing this?

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • douwen3836 2016-06-18 10:59
    已采纳

    according to https://golang.org/cmd/cgo/
    All the cgo CPPFLAGS and CFLAGS directives in a package are concatenated and used to compile C files in that package. All the CPPFLAGS and CXXFLAGS directives in a package are concatenated and used to compile C++ files in that package. All the LDFLAGS directives in any package in the program are concatenated and used at link time. All the pkg-config directives are concatenated and sent to pkg-config simultaneously to add to each appropriate set of command-line flags.

    Go package boundary is src folder so you may put all c files in same folder/ or use include C file(not h file) workaround like this:

    // main.go
    package main
    
    //#include "../ctest/test.c"
    import "C"
    import "fmt"
    
    func main() {
        r := C.Add(10, 20)
        fmt.Println(r)
    }
    

    and c file in ctest dir:

    //test.c
    
    int Add(int a, int b){
        return a+b;
    }
    

    this works fine.

    已采纳该答案
    打赏 评论

相关推荐 更多相似问题