>백엔드 개발 >Golang >Go 언어는 C 언어와 호환됩니까?

Go 언어는 C 언어와 호환됩니까?

青灯夜游
青灯夜游원래의
2022-12-26 10:23:045629검색

go 언어는 C 언어와 호환됩니다. Go 언어는 C 언어를 호출할 수 있고 C 언어도 호출할 수 있습니다. Go 언어 툴킷에는 C를 호출하는 Go와 관련된 작업을 처리하는 데 사용되는 Cgo 명령이 있으며, Go 함수를 C로 내보낼 수 있습니다. 내보낼 함수 앞에 "//export funcname"을 추가하면 됩니다. 그런 다음 "go build -buildmode=c-shared -o libxxx.so" 명령을 사용하여 C 언어에서 사용할 동적 라이브러리 및 헤더 파일을 컴파일하고 생성할 수 있습니다.

Go 언어는 C 언어와 호환됩니까?

이 튜토리얼의 운영 환경: Windows 7 시스템, GO 버전 1.18, Dell G3 컴퓨터.

C 언어와 golang이 호환됩니다. C로 작성한 .c 파일은 golang에서 참조하여 직접 사용할 수 있습니다.

다양한 현대 고급 프로그래밍 언어 중 상당수는 C 언어 위에 구축되어 기본적으로 C 언어를 호출할 수 있으며 경우에 따라 이것도 이러한 요구 사항과 존재 의미를 갖습니다. Go 언어는 이러한 측면을 매우 잘 지원합니다. C 언어뿐만 아니라 C 언어도 호출할 수 있습니다. 이 기사에서는 관련 내용을 설명합니다.

기본 설명

Go 언어 툴킷에는 C를 호출하는 Go와 관련된 작업을 처리하는 데 사용되는 Cgo 명령이 있습니다. 이 명령을 직접 사용할 수도 있고 Go 프로그램을 실행하거나 빌드할 때 자동으로 호출할 수도 있습니다.

Cgo의 C 언어 처리 자체는 시스템의 C 언어 관련 컴파일 도구 체인에 의존하므로 설정에 주의해야 합니다. 주로 Go의 환경 변수 설정:

Go 언어는 C 언어와 호환됩니까?

특별한 주의가 필요합니다 Cgo 활성화 요구 사항은 go env -w CGO_ENABLED=1 명령을 사용하여 설정할 수 있습니다. 위 그림에서 C 컴파일 중에 일부 FLAGS 매개변수를 볼 수 있습니다. 필요한 경우 그에 따라 설정을 조정할 수 있습니다. 또한 위의 CC CXX는 컴파일 도구 체인의 설정이며 필요에 따라 조정할 수도 있습니다. go env -w CGO_ENABLED=1 命令来设置。上图中可以看到一些C编译时的FLAGS参数,如果有需要也可以进行相应设置调整。另外上面的 CC CXX 是编译工具链的设置,也可以根据需求设置调整。

Go中调用C

Go中调用C语言最终在Go中都显示为名为 C 的伪包, 在Go中 import "C" 行之上以注释 #include ... 方式来引用C语言相关的库。 这些被引用的库中公共的变量和函数等在Go中会被挂到 C 包中以供使用。下面是个简单的演示:

Go 언어는 C 언어와 호환됩니까?

在Go中调用C只要上面这样就行了,使用起来还是很方便的。

通常来说C语言程序的项目中除了C语言代码外可能还有汇编代码;或者项目也有可能是C/C++混合编程的。这些项目都可以在Go中使用,Cgo会自动识别后缀为 .c .s .S .sx .cc .cpp .cxx 的文件,并调用对应的编译器去编译。

需要注意的是C++中的重载和类方法等C不支持的语法想要在Go中使用都需要用C语言标准函数包装一层,使用方法就和C语言中调用C++一样。【相关推荐:Go视频教程编程教学

C中调用Go

下面测试中如果有问题可以尝试 go clean 重置项目后再进行。

Go的函数可以导出给C用,只要在要导出的函数前面加上 //export funcname 就行了,然后可以使用 go build -buildmode=c-shared -o libxxx.so 命令编译生成动态库和头文件供C语言中使用:

Go 언어는 C 언어와 호환됩니까?
Go 언어는 C 언어와 호환됩니까?

另外也可以使用 go build -buildmode=c-archive -o libxxx.a 编译生成可用C语言使用的静态库。

数据类型差异

两个语言间调用其实就是数据的传递处理,需要注意的是因为两者毕竟不是同一种语言所以两者之间可以交互的数据类型是有限制的。有些时候也会有强制转换数据类型的需求,比如下面这个代码:

package rand

// #include <stdlib.h>
import "C"

func Random() int {
    return int(C.random()) // C函数返回值给Go,random的返回值是long类型
}

func Seed(i int) {
    C.srandom(C.uint(i)) // Go传值给C的函数,srandom函数接收uint类型数据
}

两者间可用的基本数值类型转换有下面一些:

C.char,       C.schar (signed char),       C.uchar (unsigned char)
C.short,       C.ushort (unsigned short)
C.int,       C.uint (unsigned int)
C.long,       C.ulong (unsigned long)
C.longlong (long long),       C.ulonglong (unsigned long long)
C.float,       C.double
C.complexfloat (complex float),       C.complexdouble (complex double)

除了上面的基础类型,指针也是可以传递的。特别的C语言中的 void* 指针相当于Go中的 unsafe.Pointer

C中的 __int128_t__uint128_t 相当于Go中的 [16]byte

🎜🎜Go에서 C 호출🎜🎜🎜Go에서 C 언어 호출은 결국 Go, 🎜Go에서 C라는 의사 패키지로 표시됩니다.#include ... code>import "C" 줄 위에 C 언어 관련 라이브러리를 참조하세요. 🎜 이러한 참조 라이브러리의 공용 변수와 함수는 Go에서 사용할 수 있도록 C 패키지에 연결됩니다. 다음은 간단한 데모입니다. 🎜🎜여기에 이미지 설명 삽입 🎜 🎜Go에서 C를 호출하려면 위와 같이 하면 아주 편리하게 사용할 수 있습니다. 🎜🎜일반적으로 C 언어 프로그램 프로젝트에는 C 언어 코드 외에 어셈블리 코드가 포함될 수도 있고 C/C++ 혼합 프로그래밍일 수도 있습니다. 이러한 프로젝트는 Go에서 사용할 수 있으며 Cgo는 자동으로 접미사를 .c .s .S .sx로 인식합니다. code > <code>.cc .cpp .cxx 파일을 선택하고 해당 컴파일러를 호출하여 컴파일합니다. 🎜🎜C++의 오버로딩, 클래스 메서드 등 C에서 지원하지 않는 구문을 Go에서 사용하려면 C 언어 표준 함수 레이어로 래핑해야 한다는 점에 유의하세요. C 언어로. [관련 권장 사항: Go 동영상 튜토리얼🎜, 프로그래밍 교육🎜】🎜🎜🎜🎜C🎜🎜🎜문제가 있으면 Go로 전화하세요. 다음 테스트에서 문제가 있는 경우 go clean을 시도하여 프로젝트를 재설정하고 다시 시도할 수 있습니다. 🎜🎜Go 함수는 C로 내보낼 수 있습니다. 내보낼 함수 앞에 //export funcname을 추가하고 go build -buildmode=c -shared를 사용하세요. -o libxxx.so 명령은 C 언어에서 사용할 동적 라이브러리와 헤더 파일을 컴파일하고 생성합니다. 🎜🎜여기에 이미지 설명 삽입
여기에 그림 설명 삽입🎜🎜또한 go build -buildmode=c-archive -o libxxx.a를 사용하여 다음을 수행할 수 있는 정적 라이브러리를 컴파일하고 생성할 수도 있습니다. C 언어에서 사용됩니다. 🎜🎜
🎜🎜데이터 유형의 차이🎜🎜🎜두 언어 간의 호출은 실제로 데이터의 전송 처리라는 점에 유의해야 합니다. 두 언어는 결국 동일한 언어가 아니기 때문입니다. 서로 상호 작용할 수 있습니다. 데이터 유형은 제한되어 있습니다. 때로는 다음 코드와 같이 데이터 유형 변환을 강제해야 할 필요가 있습니다. 🎜
C.f(&C.arr[0])
🎜 둘 사이에 사용 가능한 기본 숫자 유형 변환은 다음과 같습니다. 🎜
package print

// #include <stdio.h>
// #include <stdlib.h>
import "C"
import "unsafe"

func Print(s string) {
    cs := C.CString(s) // 这个方式会将字符串拷贝一份,返回指针,注意使用完需要释放内存
    defer C.free(unsafe.Pointer(cs)) // defer修饰的语句会在该函数退出前执行
    C.fputs(cs, (*C.FILE)(C.stdout))
}
🎜위의 기본 유형 외에도 포인터도 전달할 수 있습니다. 특히 C 언어의 void* 포인터는 Go의 unsafe.Pointer와 동일합니다. C의 🎜🎜__int128_t__uint128_t는 Go의 [16]byte와 동일합니다. 🎜

C中函数传输参数为数组的话直接传递数组名就行,在Go中向这类函数传递数组需要传递数组第一个元素的地址,另外需要注意的是数组中元素也必须是C语言中支持的类型:

C.f(&C.arr[0])

C中并没有string类型,使用字符串时需要进行处理:

package print

// #include <stdio.h>
// #include <stdlib.h>
import "C"
import "unsafe"

func Print(s string) {
    cs := C.CString(s) // 这个方式会将字符串拷贝一份,返回指针,注意使用完需要释放内存
    defer C.free(unsafe.Pointer(cs)) // defer修饰的语句会在该函数退出前执行
    C.fputs(cs, (*C.FILE)(C.stdout))
}

另外C语言的字符串 *C.char 可以使用 C.GoString() 转换成Go中的字符串。

C中的 struct union enum 这些类型在Go使用需要加上对应的前缀,变成 struct_xxx union_xxx enum_xxx 。其中联合体在Go中将成为字节数组的形式。这些对象的成员名如果和Go的关键词一样的话,在Go中使用需要在成员名前面加下划线,比如 x._name

C中的 sizeof 在Go中需要使用 C.sizeof_T 方式使用,T是变量数据类型。

更多编程相关知识,请访问:编程视频!!

위 내용은 Go 언어는 C 언어와 호환됩니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.