How are libraries implemented that add non-C C functionality?

Can someone explain to me how to add extra functionality in C?

For example, C does not have an output function, so you can use printf (), including stdio.h, C does not know how to open a MessageBox, so you enable and use MessageBox (), etc.

But how is this functionality implemented?

Do you need to use assembler in some way and access the video memory for output or something like that?

I know that MessageBox (), for example, is part of WinAPI, but how is it implemented (although WinAPI is implemented in C)?

+4
source share
5 answers

Any functionality that interacts with the system is performed through a system call mechanism. Essentially, it provides an interface between your code and the operating system. The library features you mention include some handy features around various system calls to make it easier for your code to interact with the system at a higher level. However, you can write code to do this directly. Find syscall and ioctl for more information. Windows has more system calls, and they are scattered across various libraries in the Windows API . This is Dr. Dobb 's article on Windows system calls more ...

+7
source

Understand that pretty much everything you do will result in reading CPU numbers from some memory address, doing some calculations on them, or writing them to some memory address.

Thus, most communications with the outside world are devices such as your video card, network card, etc. - basically come down to reading or writing to magic memory cells.

(This is a slight simplification, there is something else the processor can do - I / O ports that it can read / write, etc., they are not directly accessible from standard C and usually C libraries that expose such functionality will have the appropriate code written in assembler, but let it roll with it for now).

Hardware drivers written in C usually declare a struct that describes the layout of memory-mapped regions using familiar C types, obtains the addresses of the corresponding regions, performs appropriate drops, and then simply uses the resulting pointers, like any others.

The OS usually wraps this type of hardware-specific code in some kind of mechanism that provides virtualization (so your code may pretend to be talking to some standard idealized device, and the OS translates between what is actually located in your machine) and privilege sharing (so your code cannot execute what it shouldn't and / or other people's code crashes). Thus, the libraries you refer to will not directly talk to the equipment; they will call the OS (usually using some kind of syscall / interrupt / exception mechanism) that will do this for them. But the OS itself will do something like what I described above.

+3
source

For the printf part, this is part of the C standard library, which is part of C. Thus, implementing your C compiler or C Standard library can use all kinds of tricks to make it work.

Let's look at a simple example of how such a function can be implemented on Unix. Take putchar (simplified here - returning nothing). It prints one character to standard output, which has file descriptor number 1. The operating system provides a "write" function. A program can be written to a file descriptor. So putchar can use this function:

 void putchar(int c) { unsigned char cc = c; write(1, &cc, 1); } 

Will write 1 byte to file descriptor 1. The write function will inform the operating system about this desire:

 void write(int fd, void * ptr, size_t size) { asm("....." "int 0x80"); } 

Usually it just contains a small block of assembly lines that causes a software interrupt (in the example above, this is the interrupt number 0x80). The CPU will switch to kernel mode and go to some fixed address from which the operating system can handle this interrupt. write will write the number of the system call to write to some register and put the arguments in any memory location or registers so that the operating system knows what to do at this point. Then, the operating system will send bytes that should be written to the specified file / device (in the case of stdout, this may be the terminal driver that is connected to the file descriptor), and will return from the interrupt by putting the CPU switch in user mode.

This is a rough plan. That is not all (the putschar can buffer the output before making a system call ...). But basically it works like that.

The MessageBox function will also call some system call at the end, which transfers control to the Windows kernel in one way or another, similar to the explanation above.

+2
source

First you have a C compiler that conforms to the ANSI C standard. This is the language itself, without libraries.

Then you have a standard library in which the printf function you mentioned will be found. It is built using C and ASM and is platform specific. For example, in the embedded platform, printf will print characters on the serial port or on the lcd display. Therefore, you must use the specific platform code. However, the interface is common to all platforms.

Something similar happens with third-party libraries such as WinAPI.

+1
source

Often libraries are written in "C". Most Win32 api are written in C. There are several things that you cannot express directly in C, such as "syscall", "int", and reading / writing to io ports.

Take a look at K & R ; they actually implement some of the system libraries in the book.

0
source

All Articles