Build and Use Go Packages as C Libraries
GO의 공식기능인 CGO를 통해 C라이브러리를 참조하는 GO패키지를 만들 수 있습니다.
놀랍게도 그뿐아니라, 반대로 C에서 GO를 참조할 수 있도록 GO패키지에서 C라이브러리를 만들 수도 있습니다.
How to
Build Go package as C shared library (or shared object)
모든 GO main 패키지는 C 공유 라이브러리로 빌드될 수 있어요.
$ go build -go build -buildmode c-shared -o <c-lib>.so <go-package>
위 명령을 실행하면 대상이된 Go main 패키지의 모든 종속성을 C공유라이브러리 하나로 빌드합니다.
이 C공유 라이브러리를 참조할 수 있는 모든 어플리케이션에 배포,설치, 링크할 수도 있습니다.
주의 : C공유라이브러리의 output 이름은 lib*.so 로 표준형식으로 지정해야합니다.
Generate C header and export Go functions as C functions
Go main package를 C shared library로 빌드한다고 해서 자동으로 C헤더를 생성하거나 Go함수를 C심볼로 노출하지 않습니다. 이건 개발자가 명시적으로 어떤 Go 함수를 노출할지 지정해야합니다.
Go 함수를 C 심볼로 export 하기
- export 할 Go 함수 위에 //export FuncName 으로 주석을 추가합니다.
- 이 함수가 있는 Go 코드파일에 import "c" 를 넣어주세요
- 이 함수는 main 패키지에 포함되어 있어야합니다.
- 함수 signature 에 Go struct, interface, array나 가변인수가 포함될 수 없습니다.
package main
import "C"
import (
"math/rand"
"time"
)
//export cgoCurrentMillis
func cgoCurrentMillis() C.long {
return C.long(time.Now().Unix())
}
//export cgoSeed
func cgoSeed(m C.long) {
rand.Seed(int64(m))
}
//export cgoRandom
func cgoRandom(m C.int) C.int {
return C.int(rand.Intn(int(m)))
}
위 Go main 패키지를 빌드하면 C헤더파일 <output.h> 과 C공유객체 <output>.so가 생성됩니다.
// Other stuff.
extern long int cgoCurrentMillis();
extern void cgoSeed(long int p0);
extern int cgoRandom(int p0);
cgoCurrentMilli, cgoSeed 및 cgoRandom 도 <output>.so 에 C 심볼로 노출됩니다.
이제 모든 C어플리케이션에서 만들어진 C헤더를 include 하고 C공유라이브러를 link해서 export된 C심볼을 사용할 수 있습니다.
#include <stdio.h>
#include <cgo-random.h>
int main() {
cgoSeed(cgoCurrentMilli());
printf("Hello World from C!\n");
printf("cgoRandom() -> %d\n", cgoRandom(256));
return 0;
}
원문 :
https://medium.com/swlh/build-and-use-go-packages-as-c-libraries-889eb0c19838