2016-06-18 7 views
2

私はCgoを使用して、現在のGoパッケージではなく別のディレクトリで宣言されたC関数を呼び出すことができないようです。私は1つのディレクトリ内のすべてのファイルを置く場合は他のディレクトリでC関数のC関数を宣言できますか?

// 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; 
} 

:すべてのファイルの

コードが

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

とゴー主な機能を実行し、これら2つのC関数を呼び出すことができます。

しかし、私は別のdirecoryでCファイル(実際には、彼らはObjective-Cのファイルである)を置く場合:

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

、その絶対パスに前文で#include "test.h"のファイルパスを変更し、ゴー主な機能を実行しますこれらの2つのC関数を呼び出すことができませんでした。 "_fortytwo"、から参照: TestGoCallOC.cgo2.o で__cgo_b3674ecbf56b_Cfunc_fortytwo(多分あなたは意味:__cgo_b3674ecbf56b_Cfunc_fortytwo)を LD:シンボル(s)が見つからない

エラーメッセージは、アーキテクチャx86_64のため

未定義のシンボルでありますfor architecture x86_64 clang:エラー:リンカーコマンドが終了コード1で失敗しました(呼び出しを見るために-vを使います) 終了ステータス2

私は間違っていますか?それともCgoはこれを行うことができませんか?

答えて

2

https://golang.org/cmd/cgo/
に係るパッケージのすべてのCGO CPPFLAGSとCFLAGS指令はに連結して使用されるパッケージにCファイルをコンパイル。パッケージ内のすべてのCPPFLAGSおよびCXXFLAGSディレクティブが連結され、そのパッケージ内のC++ファイルをコンパイルするために使用されます。プログラム内のすべてのパッケージのすべてのLDFLAGSディレクティブはリンク時に連結され、使用されます。すべてのpkg-configディレクティブが連結され、pkg-configに同時に送られて、それぞれの適切なコマンドラインフラグセットに追加されます。あなたが同じフォルダ内のすべてのCファイルを置く/またはを使用することができますので、

ゴーパッケージの境界は、srcフォルダであるCファイル(ない時間ファイル)は、このような回避策は、次のとおりですcTEST収録ディレクトリ内

// main.go 
package main 

//#include "../ctest/test.c" 
import "C" 
import "fmt" 

func main() { 
    r := C.Add(10, 20) 
    fmt.Println(r) 
} 

とCファイルを:

//test.c 

int Add(int a, int b){ 
    return a+b; 
} 

これは問題なく動作します。

+0

多くのありがとうございます。私は '#include" ../../ test.m "'を試してから、私はこれらのC関数を呼び出すことができます。しかし、なぜ '#include'ヘッダが動かないのですか? –

+0

ソースファイルを含める:プリプロセッサが#include指示文を見つけたら、指定されたファイルの内容全体で置き換えます。 –