- 책 또는 웹사이트의 내용을 복제하여 다른 곳에 게시하는 것을 금지합니다.
- 책 또는 웹사이트의 내용을 발췌, 요약하여 강의 자료, 발표 자료, 블로그 포스팅 등으로 만드는 것을 금지합니다.
C 언어 연동하기
이재홍 http://www.pyrasis.com 2014.12.17 ~ 2015.02.07
C 언의의 구조체 및 문자열 포인터 사용하기
이번에는 C 언어의 구조체 및 문자열 포인터에 메모리를 할당한 뒤 해제해보겠습니다.
package main
/*
#include <stdlib.h>
typedef struct _PERSON {
char *name; // 문자열 포인터
int age; // 정수
} PERSON;
PERSON* create(char *name, int age) // 메모리 할당 함수 작성
{
PERSON *p = (PERSON *)malloc(sizeof(PERSON)); // PERSON 크기로 메모리 할당
p->name = name; // 값 설정
p->age = age; // 값 설정
return p; // 할당한 메모리 리턴
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func main() {
var p *C.PERSON
name := C.CString("Maria")
age := C.int(20)
p = C.create(name, age)
fmt.Println(C.GoString(p.name)) // Maria: char *는 C.GoString 함수로 변환하여 사용
fmt.Println(p.age) // 20
C.free(unsafe.Pointer(name)) // C.CString으로 만든 문자열은 반드시 해제
C.free(unsafe.Pointer(p)) // C 언어의 malloc 함수로 할당한 메모리는 반드시 해제
}
먼저 C 언어로 문자열 포인터(char *)와 정수를 필드로 갖는 구조체를 정의하고, 메모리를 할당하는 함수를 만듭니다.
/*
#include <stdlib.h>
typedef struct _PERSON {
char *name; // 문자열 포인터
int age; // 정수
} PERSON;
PERSON* create(char *name, int age) // 메모리 할당 함수 작성
{
PERSON *p = (PERSON *)malloc(sizeof(PERSON)); // PERSON 크기로 메모리 할당
p->name = name; // 값 설정
p->age = age; // 값 설정
return p; // 할당한 메모리 리턴
}
*/
import "C"
create 함수에서는 malloc 함수로 PERSON 구조체 크기의 메모리를 할당합니다. 그리고 매개변수로 받은 name 포인터와 age 변수를 대입합니다. name 포인터는 C 언어에서 할당하지 않고 Go 언어에서 할당하겠습니다.
이제 C 언어에서 정의한 PERSON 구조체와 create 함수를 Go 언어에서 사용합니다.
var p *C.PERSON
name := C.CString("Maria")
age := C.int(20)
p = C.create(name, age)
fmt.Println(C.GoString(p.name)) // Maria: char *는 C.GoString 함수로 변환하여 사용
fmt.Println(p.age) // 20
C.free(unsafe.Pointer(name)) // C.CString으로 만든 문자열은 반드시 해제
C.free(unsafe.Pointer(p)) // C 언어의 malloc 함수로 할당한 메모리는 반드시 해제
C.CString 함수는 문자열을 메모리를 할당한 뒤 C 언어의 문자열 포인터(char *)로 리턴합니다. 따라서 Go 언어에서는 바로 사용할 수 없으므로 C.GoString(p.name)과 같이 변환을 하여 사용합니다.
C.create 함수에 이름과 나이를 넣어주면 *C.PERSON 타입의 포인터가 리턴됩니다. 그리고 이 포인터를 Go 언어 변수에 대입했으므로 p.name, p.age처럼 . (점)으로 구조체 필드에 접근할 수 있습니다. 여기서 C.CString으로 만든 문자열 포인터나 C 언어의 malloc 함수로 할당한 포인터는 Go 언어의 가비지 컬렉터로 관리되지 않으므로 반드시 C 언어의 free 함수로 해제해야 합니다.
Go 언어에서는 C 언어에서 메모리를 해제할 때는 C.free(unsafe.Pointer(p))처럼 unsafe.Pointer로 변환하여 C.free 함수에 넣어줍니다.
저작권 안내
이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.- 블로그, 게시판 등에 퍼가는 것을 금지합니다.
- 비공개 포스트에 퍼가는 것을 금지합니다.
- 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
- 링크 및 SNS 공유는 허용합니다.