본문 바로가기

Go

cgo

[1. 개요]

cgo 는 C code 를 호출하는 go package 의 생성을 가능하게 한다.

일반적으로 cgo 를 사용하기 위해 go 소스코드를 작성하는 방법은 pseudo 패키지 "C" 를 import 하는 것이다.

=> import "C"

 

CFLAGS, CPPFLAGS, CXXFLAGS, FFLAGS, LDFLAGS 등이 #cgo directive 내에 정의 될 수 있다.

pkg-config 로 관리 할 수도 있다.

 

gcc 가 사전에 PC 에 설치되어 있어야 한다.

go env 시 CC 와 CXX 가 각각 gcc 와 g++ 로 설정되어 있다.

 

 

[2. 예제]

위와 같이 go 소스코드에서 주석에 C 코드를 작성한다.

그리고 유의사항이 한가지 있는데,

C 코드를 감싸는 주석과 import "C" 는 반드시 붙어있어야 한다는 것이다.

 

 

[3. 라이브러리 링킹]

CFLAGS 와 LDFLAGS 를 통해 각각 include 파일 경로와 라이브러리 파일 경로를 명시 할 수 있다.

이를 이용하여 외부 C 라이브러리를 import 하여 사용 할 수 있다.

 

현재 소스코드 구조는 아래와 같다.

 

그리고 각 소스 파일은 아래와 같다

 

윈도우의 경우 C 라이브러리는 가급적 msvc 로 빌드하지 말고 mingw 로 빌드하는 편이 좋다.

msvc 버전 차이일 수 있으나 Visual studio 2019 에서는 아래와 같이 출력된다.

cmake 파일 빌드 시 generator 를 MinGW Makefiles 로 명시해서 makefile 생성 후

mingw32-make 로 라이브러리 파일을 빌드하도록 한다.

 

이렇게 빌드한 라이브러리를 링킹하면 위와 같은 warning 은 출력되지 않는다.

 

 

[4. C++ 라이브러리와 링킹]

go 에서 c++ 표준 라이브러리 나 템플릿 같은 것은 직접적으로 사용 할 수 없어 보인다.

=> c 대비 cpp 만의의 feature 들 ex) namespace, template, class, ... 등을 사용하기 힘들어 보임

=> go env 등을 통해 cpp 관련 옵션등이 있는 것으로 보아 가능할 것 같으나, 방법을 따로 찾지 못함

 

그래서 보통 stl 등을 사용하는 코드를 작성하여 라이브러리로 빌드 후 go 와 링킹해서 사용하는 듯 하다.

물론 헤더파일은 C 언어스럽게 작성해야 한다.

 

 

위 예제 코드에서 cpp 코드는 cpp 만의 여러 특징들을 활용하여 작성해보았다.

auto, template, lambda 같은 것을 이용해서 작성하고

라이브러리로 빌드 후 go 와 링킹하였다.

 

여기서 중요한 점은 stdc++ 라이브러리를 함께 링킹해주어야 한다는 것이다.

주로 namespace std 를 사용하기 위해서 이며,

이 링킹 없이 go 소스 코드는 정상 동작하지 않는다.

undefined reference to `std::basic_ostream...' 같은 링킹 오류를 실제로 확인 할 수 있다,.

'Go' 카테고리의 다른 글

GO111MODULE  (0) 2022.08.10
go 패키지 설치, 관리  (0) 2022.08.10
ubuntu go version update  (0) 2022.04.06
Slice length, capacity and append, copy function  (0) 2022.02.08
Array & Slice  (0) 2022.02.07