Assume a low-level API is provided without source code (e.g. DirectX).
The API provides a virtualization of hardware resources (GPU, CPU, audio card, etc.), which enables the user to call hardware-specific drivers through the OS. As a software developer, we do not care about the implementation details at the hardware level.
This is a proper implementation of encapsulation. That is, the API enables the client to work with a more abstract software layer. Therefore, the user is not required to think about lower-level contracts between the OS, the driver, and the CPU/GPU.
In the absence of encapsulation, it could become difficult (even unmanageable) for the user to work manually everything from the compiler, to the OS, to understanding all the intricate details of the CPU/GPU architecture. Furthermore, from a safety standpoint, accessing and modifying sensitive data may break the API's integrity. Usually, the contracts are specified between the manufacturers and the OS/software developers.
During the API implementation, developers specify which properties of the API should be exposed to the customer.
As a consumer of a low-level API, I have several general questions.
- Nothing's perfect and bugs can appear at the implementation phase. When this occurs, it is just impossible to backtrack those errors, as the source code is hidden. How far can we debug stuff in such situation?
- Is encapsulation, in this context, a drawback, as it does not give power to the user to backtrack private, encapsulated data, for debugging purposes? In the worst case, only the binary codes are supplied to the client, and nothing can be debugged at a lower level.
- Assume we have transparency at all the levels between the hardware, the OS, and the application (up to controlling every bits in the CPU registers). In this case, even though we have complete control upon all the resources of the computer, would we lose the abstraction provided by the API?
I have the impression that, at a certain point, we are stuck as we are not able to debug some low-level APIs due to the decisions of vendors and developers made upstream.