[Go] CGO FFI: C 코드 import해서 사용하기

cgo는 go에서 FFI(Foreign Function interface)를 사용하는 대표적인 수단이다.
쉽게 말해, C 코드를 땡겨와서 쓰는 것이다.

사실 그리 편리한 편은 아니다.
컴파일러도 gcc, clang이 있어야만 컴파일이 가능하다. msvc도 링커 설정을 바꾸면 어떻게 되긴 된다는데.. 그래도 문제가 있다고 한다.

기본사용법은 이렇다.
"C"라는 이름의 cgo 모듈을 임포트함과 동시에, 그 위에 주석으로 가져올 헤더 등의 전처리 명령이나 소스코드를 삽입하는 것이다.

그럼 해당 영역에서 노출되는 함수들을 모듈에서 꺼내오는 형태로 사용할 수가 있다.
아래 코드는 stdio.h헤더의 표준함수 puts를 바로 사용하는 예제다.

C의 함수는 C만의 char 배열 타입으로 문자열을 받으므로 CString 함수를 통해 캐스팅하도록 했다.
그리고, Go는 가변인자 함수를 지원하지 않아서 printf 같은건 써먹을 수가 없다.
만약 이런걸 쓰고 싶다면

이런식으로 직접 함수를 작성해서 간접적으로 호출을 해야 한다.




수동 링킹

표준 라이브러리만 쓰면 필요하지 않겠지만, 실제로 쓸때는 대부분 서드파티 라이브러리를 땡겨쓰는 형태로 활용이 될 것이다.

테스트에 쓸 라이브러리가 필요하다면 아래 포스트를 참조해서 직접 만들어보면 좋겠다.
https://blog.naver.com/sssang97/222901296890

링크는 주석에 특수한 전처리문을 집어넣는 것으로 처리할 수 있다.
cgo 매크로에 gcc의 링크 옵션을 구겨넣는 형태다...

보기에 썩 아름답지는 않지만 동작은 한다.




메모리 관리

Go는 마법처럼 메모리를 책임지고 관리해주지만, c가 개입되는 순간부터는 당연히 말이 달라진다.

예를 들면, 위에서 puts를 호출해 문자열을 출력했던 간단한 경우에도 사실 누수가 있었다.

CString을 사용하면서 동적할당을 했기 때문이다.
그래서 뭔가 배열데이터같은걸 넘긴 후에는 호출자가 알아서 free를 잘 해줘야 한다.



참조
https://pkg.go.dev/cmd/cgo