[Go] CGO FFI: C 코드 내보내기
관련 포스트
https://blog.naver.com/sssang97?Redirect=Log&logNo=222901300093&from=postView
Go 프로그램을 C/C++에서 사용할 수 있도록 export하는 방법에 대해서 간단히 정리해보겠다.
Go 프로젝트 구성
우선 디렉터리 파고, mod를 초기화해준다.

그다음에 메인 패키지에 소스코드를 때려박는다.
package main
import "C"
import (
"fmt"
"strconv"
)
//export Add
func Add(a int, b int) int { return a + b }
//export Sub
func Sub(a int, b int) int { return a - b }
//export Mul
func Mul(a int, b int) int { return a * b }
//export Div
func Div(a int, b int) int { return a / b }
//export PrintToConsole
func PrintToConsole(msg string) {
fmt.Println(msg)
}
func main() {
result := Sub(Add(1, 2), 10)
PrintToConsole(strconv.Itoa(result))
}
소스코드가 통짜인 것은 이유가 있다.
원래는 나도 저 함수 구현들을 서브패키지로 빼려고 했는데, 그러면 그걸 export할 수가 없다.
cgo는 main 패키지에서만 export를 할 줄 알고, go에는 import를 다시 export를 하는 기능이 없기 때문이다.
환장할 노릇이다.
아무튼 하나씩 짚어보자.
일단 main 패키지여야 하고, C 모듈을 포함시켜야 한다.
그래야먄 헤더파일을 생성해준다.
그리고 내보낼 함수들을 정의해준다.
당연히 대문자로 시작해야 하고, 주석으로 export될 함수임을 명시해줘야 한다.
그래서 일단
실행은 된다.
C로 내보내기
도는건 확인했으니 C 포맷으로 export를 해보자.
다음 처럼 옵션을 줘서 컴파일을 하면 된다.
go build -o libgoffi.so -buildmode=c-shared go/main.go // Linux

그럼 외부에서 갖다쓸 수 있는 공유 라이브러리(.so)와 헤더파일을 던져줄 것이다.
이걸 주워가서 쓰면 된다.
다만 문제는... dll로 내보내는 기능이 없다는 것이다.
그래서 windows에서는 활용하기 어렵다.
C에서 연동해보기
제대로 만들어진 것이 맞는지 C 코드와 함께 컴파일을 해보자.
#include <stdio.h>
#include "./libgoffi.h"
int main() {
int foo = Sub(10, 20);
printf("foo %d", foo);
char text[] = "Hello!!";
GoString gostring = {
p: text,
n: sizeof(text)
};
PrintToConsole(gostring);
}
계산하고 출력해주는 단순한 코드다.
다만 문자열 처리가 좀 번거로운 것이 흠이다.
저걸 컴파일해서 실행해보자.
gcc를 썼다.
gcc -c main.c
gcc main.o -L. -l goffi
export LD_LIBRARY_PATH=. # LD_LIBRARY_PATH에 현재 경로가 없다면 설정
./a.out
그럼 이렇게 실행이 될 것이다.
뭔가 나중에 나와야 할 Hello 출력이 먼저 나와서 이상해보이는데, 그건 C의 표준 출력과 Go의 표준 출력을 동기화하지 않아서 그럴 것이다.
참조
https://medium.com/learning-the-go-programming-language/calling-go-functions-from-other-languages-4c7d8bcc69bf
https://stackoverflow.com/questions/58433624/cgo-doesnt-export-functions-in-imported-packages