14

There is a very nice description about loading a shared library and calling a function with the syscall package on Windows (https://github.com/golang/go/wiki/WindowsDLLs). However, the functions LoadLibrary and GetProcAddress that are used in this description are not available in the syscall package on Linux. I could not find documentation about how to do this on Linux (or Mac OS).

Thanks for help

Michael
  • 4,722
  • 6
  • 37
  • 58
  • You may find this package useful: https://github.com/rainycape/dl –  Dec 02 '15 at 13:04
  • @TimCooper Note that "gopkgs.com" is unreachable and [is an NXDOMAIN](http://centralops.net/co/DomainDossier.aspx?addr=gopkgs.com&dom_dns=true). So it is safe to assume that site is dead. – Markus W Mahlberg Dec 02 '15 at 13:17
  • @MarkusWMahlberg: The package can still be grabbed with `go get -u github.com/rainycape/dl`. –  Dec 02 '15 at 13:21
  • 4
    The "official" (and highly recommended) way to do this is to use cgo. Windows has these in the syscall package, because windows requires loading DLLs for some functionality. Linux doesn't need to load shared libraries for any syscalls, so there's no built-in support. – JimB Dec 02 '15 at 13:58
  • @TimCooper Just wanted to inform you about the status. And one could also use `go get -u gopkg.in/rainycape/dl.v0` ;) – Markus W Mahlberg Dec 02 '15 at 14:00
  • 1
    I suggest looking in the source of the `syscall.go` and `*syscall_linux[_$GOARCH].go` files of the Go runtime. The [`golang.org/x/sys`](https://godoc.org/golang.org/x/sys) package might of of interest, too. – kostix Dec 02 '15 at 17:36

1 Answers1

9

Linux syscalls are used directly without loading a library, exactly how depends on which system call you would like to perform.

I will use the Linux syscall getpid() as an example, which returns the process ID of the calling process (our process, in this case).

package main

import (
    "fmt"
    "syscall"
)

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

I capture the result of the syscall in pid, this particular call returns no errors so I use blank identifiers for the rest of the returns. Syscall returns two uintptr and 1 error.

As you can see I can also just pass in 0 for the rest of the function arguments, as I don't need to pass arguments to this syscall.

The function signature is: func Syscall(trap uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err Errno).

For more information refer to https://golang.org/pkg/syscall/

sbrk
  • 378
  • 3
  • 10
  • 3
    In `syscall` package all available constants have already defined ( https://golang.org/pkg/syscall/#pkg-constants ) So, for @ErikBye example, `39` can be replaced by `syscall.SYS_GETPID` – Ilya Vishnevsky Oct 08 '18 at 20:49
  • Great! Not sure if they were defined at the time I wrote the answer. – sbrk Oct 20 '18 at 09:38