On linux (for example), we can directly make system calls using the api provided by OS (open/close/read/write) or we can use functions provided by libc (fopen etc) in C.
How is it achieved in other languages?
On linux (for example), we can directly make system calls using the api provided by OS (open/close/read/write) or we can use functions provided by libc (fopen etc) in C.
How is it achieved in other languages?
Your initial premises are wrong: on Linux, when you call, say,
open(2)
in your C code, you're not making the syscall but rather calling the function provided byglibc
(or whatever implementation of the C standard library your program happens to be using—there are others, such as μLibc, dietlibc etc), and the implementation of that function actually makes the syscall—properly doing the necessary setup to conform to the target architecture's ABI conventions.You can make a syscall directly in C but it will look much different from just calling
open()
; some pointers are this and this.To recap: the POSIX standard (that one specifying how
open(2)
and friends should looks like and behave) does only specify a rather high-level interface (in terms of the C programming language) but concrete kernels implementing this standard have their own sets of system calls and conventions on how to call them (which differ between H/W architectures for the same kernel), and it's the C standard library which "knows" how to call out to a concrete kernel which makes sure C programs calling POSIX API end up using appropriate system calls with proper set up. In other words, in a typical C application running on Linux you're not dealing with syscalls directly—you just have an impression you do.Other languages/runtimes basically have two alternatives:
libc
and rely on it to mediate between them and the kernel.Most of languages/runtimes I'm aware of take the first route (Python, Java to name a few) while some of them take the other route—for instance, the reference implementation of Go, Free Pascal.
Update 2014-10-13 answering the question from
@tan
's comment:Basically, the approach is similar to that of the syscalls: calling into C is, again, sort-of standardized for each combination of hardware architecture and the C compiler. See this discussion for more info and further pointers.
Note that in reality, most software which is able to interface with C code uses one of these two approaches:
It is itself written in C, and hence implementing calling out to dynamically or statically linked in external C code is handled by the compiler which compiled the calling software.
That is, the only thing your software must be concerned of is properly arranging for its data to be manipulated by the C side. One example is making sure a block of memory passed to the C side won't get garbage-collected until the C side is done with it.
The
cgo
subsystem of the Go programming language is one example of this approach.The calling software uses a library (typically written in C to leverage what the C compiler can do for it) which is able to load C dynamic libraries and properly call out to their functions performing all the required data setup. See this for more info.
Python's
ctypes
module implements exactly this approach.It's harder for me to classify Java's
JNI
and .NET'sP/Invoke
into these two categories. May be they sit somewhere in the middle.In other languages this is usually (always?) achieved with a wrapper around the native function calls. In reality, it looks something like this. LanguageX -> Wrapper -> Native Code(C/C++)
Sometimes this wrapper takes the form of an entire framework, such as in JNI for java. which also works great for Groovy scripts.
With some languages you can load native DLLs directly into your application in a way similar to C/C++. This is true in the the case of Python using ctypes.
Other times, native calls aren't needed at all and the same result can be produced directly using your language of choice. Cross-platform GUI toolkits are one small example where native OS calls can be replaced completely. Such as with GTK or QT
Hope that clears things up a bit :) Let me know if you'd like any other language-specific details.