Голанг: Как использовать syscall.Syscall в Linux?

Есть очень хорошее описание загрузки общей библиотеки и вызова функции с помощью пакета syscall в Windows (https://github.com/golang/go/wiki/WindowsDLLs). Однако функции LoadLibrary и GetProcAddress, которые используются в этом описании, недоступны в пакете syscall в Linux. Мне не удалось найти документацию о том, как это сделать в Linux (или Mac OS).

Спасибо за помощь


person Michael    schedule 02.12.2015    source источник
comment
Вы можете найти этот пакет полезным: github.com/rainycape/dl   -  person Tim Cooper    schedule 02.12.2015
comment
@TimCooper Обратите внимание, что gopkgs.com недоступен, а является NXDOMAIN. Так что можно с уверенностью предположить, что этот сайт мертв.   -  person Markus W Mahlberg    schedule 02.12.2015
comment
@MarkusWMahlberg: Пакет все еще можно получить с помощью go get -u github.com/rainycape/dl.   -  person Tim Cooper    schedule 02.12.2015
comment
Официальный (и настоятельно рекомендуемый) способ сделать это - использовать cgo. Windows имеет их в пакете syscall, потому что Windows требует загрузки DLL для некоторых функций. Linux не нужно загружать разделяемые библиотеки для каких-либо системных вызовов, поэтому встроенной поддержки нет.   -  person JimB    schedule 02.12.2015
comment
@TimCooper Просто хотел проинформировать вас о статусе. И еще можно было использовать go get -u gopkg.in/rainycape/dl.v0;)   -  person Markus W Mahlberg    schedule 02.12.2015
comment
Я предлагаю поискать исходники файлов syscall.go и *syscall_linux[_$GOARCH].go среды выполнения Go. Также может быть интересен пакет golang.org/x/sys.   -  person kostix    schedule 02.12.2015


Ответы (1)


Системные вызовы Linux используются напрямую, без загрузки библиотеки, как именно зависит от того, какой системный вызов вы хотите выполнить.

В качестве примера я буду использовать системный вызов Linux getpid (), который возвращает идентификатор процесса вызывающего процесса (в данном случае нашего процесса).

package main

import (
    "fmt"
    "syscall"
)

func main() {
    pid, _, _ := syscall.Syscall(syscall.SYS_GETPID, 0, 0, 0)
    fmt.Println("process id: ", pid)
}

Я фиксирую результат системного вызова в pid, этот конкретный вызов не возвращает ошибок, поэтому я использую пустые идентификаторы для остальных возвратов. Системный вызов возвращает два uintptr и 1 ошибку.

Как видите, я также могу просто передать 0 для остальных аргументов функции, поскольку мне не нужно передавать аргументы этому системному вызову.

Сигнатура функции: func Syscall (trap uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err Errno).

Для получения дополнительной информации см. https://golang.org/pkg/syscall/.

person sbrk    schedule 03.04.2017
comment
В пакете syscall уже определены все доступные константы (golang.org/pkg/syscall/#pkg- константы) Итак, в примере @ErikBye 39 можно заменить на syscall.SYS_GETPID - person Ilya Vishnevsky; 08.10.2018
comment
Большой! Не уверен, были ли они определены в то время, когда я писал ответ. - person sbrk; 20.10.2018