Hi,
If everything that runs on the system is written in C++, for example, it would be better to give a C++ object interface for system functions in the base system.
In this case I would say that you would have a C++ "Native Interface" through which applications use your kernel's interface via C++ objects, and a C-style "POSIX Subsystem" that uses a more conventional method of POSIX-compatible C functions. That way you get POSIX compatibility and your own native interface without requiring a compromise (if designed well).
Either way, the user program isn't directly requesting from objects in the kernel - everything has to go through a system call at some point.
Very true. Even if the userspace API is C++, at some point it will still be converted into a C-style system call (ie, 'write', 'read', C functions that call kernel system calls) in order to jump the gap between userspace and the kernel. In my opinion, what your goal as a developer of a C++ API should be is to reduce the number of C-style system calls made to an absolute minimum.
My project, when we implement our native interface, will approach this in a unique way by actually serialising all the important data in userspace and transmitting a single buffer to the kernel, where the data is unserialised and an action is performed (all this using our asynchronous event system). Whilst it isn't perfect it's far better than having a C-style system call interface (or building hte native API upon the POSIX API). Ideally this means we would have one C function that
all objects use in order to execute an action.
As an
example (not real code, and definitely not how I'd implement this), you might want to read a file in the VFS:
Code: Select all
size_t VFS::read(File &file, uintptr_t location, uintptr_t buffer, size_t len)
{
// Some form of locking would go here
m_AdditionalMetaData = file.serialize();
// Store paramaters for serialisation
m_p1 = location;
m_p2 = buffer;
m_p3 = len;
// Run system call - calls serialise on the given object
return ret = syscall(this);
}
If you were merely building on top of a C API without a method to serialise and transmit objects, it'd look more like this:
Code: Select all
size_t VFS::read(File &file, uintptr_t location, uintptr_t buffer, size_t len)
{
int n = open(file.getName(), O_RDWR);
lseek(n, location, SEEK_SET);
size_t ret = read(n, buffer, len);
close(n);
return ret;
}
(Note that a File class would be more appropriate in this case as it could store important file metadata as part of the class. Again, this is just an example).
The point is, unless you have a decent method to serialise object data and then unserialise it on the other side, you're going to lose the appeal of a C++ API pretty quick: it'll just be a layer on top of a C API.
Cheers,
Matt