go 언어의 소스 코드에는 함수 서명만 있고 함수 본문은 없는 코드가 많이 있습니다. 예:
// src/os/proc.go 68行 func runtime_beforeExit() // implemented in runtime
여기서만 볼 수 있습니다. 함수 시그니처는 있는데 함수 본문은 안보여서 전역적으로 검색해보니 src/runtime/proc.go
// os_beforeExit is called from os.Exit(0). //go:linkname os_beforeExit os.runtime_beforeExit func os_beforeExit() { if raceenabled { racefini() } }
에 함수 본문이 정의되어 있는 것을 발견했습니다. 본문은 go:linkname을 통해 이루어집니다. 그럼 이것을 코드로 구현할 수 있을까요? 라이브러리 함수에서도 사용할 수 있는데, 우리가 만든 코드 구조에서도 사용할 수 있나요? 다음은 이러한 사용법을 단계별로 구현하는 실험적인 방법입니다
프로젝트 디렉토리 만들기
$mkdir demo && cd demo
mod 초기화 프로젝트 디렉토리
$go mod init demo
함수 시그니처 pkg 및 함수 본문 pkg 만들기
$mkdir hello $mkdir link
테스트 코드 작성
$cd hello // 函数签名 $vim hello.go package hello import ( _ "demo/link" ) func Hello() // 函数体 $vim link.go package link import _ "unsafe" //go:linkname helloWorld demo/hello.Hello func helloWorld() { println("hello world!") }
코드를 실행
$cd demo vim demo.go package main import ( "demo/hello" ) func main() { hello.Hello() }
컴파일하고 실행
go run demo.go # demo/hello hello/hello.go:7:6: missing function body
hello 폴더에 aa.s라는 어셈블리 파일 마크를 추가하면 컴파일하고 실행할 수 있습니다
$cd hello && touch aa.s $go run demo.go hello world!