[vbox-dev] How does the virtualbox object-orientation work ? Any documentation ?
Knut St. Osmundsen
bird at sun.com
Thu Jan 28 05:45:40 PST 2010
Christophe Devriese wrote:
> I'm new here, and I'm having trouble finding the documentation regarding
> the way object-oriented classes and interfaces are handled in
> virtualbox. I'm interested in the Storage subsystem, and I understand
> the code itself and the syscalls well enough, but I don't have a clue
> how the interfaces are defined.
> The code I'm having difficulty with is code like :
> /** Makes a PDRVHOSTBASE out of a PPDMIMOUNT. */
> #define PDMIMOUNT_2_DRVHOSTBASE(pInterface) (
> (PDRVHOSTBASE)((uintptr_t)pInterface - RT_OFFSETOF(DRVHOSTBASE, IMount)) )
> /** Makes a PDRVHOSTBASE out of a PPDMIBLOCK. */
> #define PDMIBLOCK_2_DRVHOSTBASE(pInterface) (
> (PDRVHOSTBASE)((uintptr_t)pInterface - RT_OFFSETOF(DRVHOSTBASE, IBlock)) )
> How are the objects defined ? How are the conversions handled ?
The VMMs interaction with the storage sub-system first goes through the
pluggable device and driver manager, aka PDM. The macros above are used
by DrvHostBase.cpp when implementing the PDMIMOUNT and PDMIBLOCK
interfaces. DrvHostBase.cpp is an attempt at sharing some code between
DrvHostDVD.cpp and DrvHostFloppy.cpp in a C++ish manner, unfortunately
code readability suffered.
As the name indicates, PDM concerns itself with emulated devices and
drivers that interfaces the host system. A device may have multiple
LUNs (abused SCSI term) each of which may have a chain of drivers
attached to it. The driver chain is a doubly linked list of driver
instances anchored to the LUN at the "top". (Topology: The VMM is at
the top, devices below it, drivers under there). To see how we
configure drivers for LUNs take a look at the CFGM dump in the VBox.log.
Since each kind of LUN/device have different needs from their drivers
and ditto between the drivers, a COM inspired approach was selected
where interfaces could be queried and used. Unlike COM there is no need
for reference counting. We'd already chosen not to use C++ classes
anywhere near the VMM, so there was no need to be compatible with any
C++ object layout either.
To keep life simpler and make it run slightly faster, the virtual method
tables (vtables) is embedded in the instance data instead of just being
pointed to it like (most/all) C++ implementations does. See for
instance DRVHOSTBASE::IMount and VBOXDISK::IMedia (DrvVD.cpp). The
constructor initializes the method table - check out the code about 20
lines into drvvdConstruct() (DrvVD.cpp) setting up VBOXDISK::IMedia.
Since the vtable is part of the instance data,
PDMIBASE::pfnQueryInterface will simply return a pointer to the vtable.
When making call to a method in the vtable, we pass the vtable pointer
as the first argument. Here is an example from drvNetSnifferReceive:
int rc = pThis->pPort->pfnReceive(pThis->pPort, pvBuf, cb);
pPort is a vtable of the PDMINETWORKPORT type that normally would be
pointing into the instance data of a network device like DevE1000 or
DevPCNet. In the DevPCNet.cpp case, pfnReceive == pcnetReceive() and
pThis == &PCNetState_st::INetworkPort. So, the first thing pcnetReceive
does is to convert the vtable point to a pointer to struct PCNetState_st
by means of INETWORKPORT_2_DATA().
INETWORKPORT_2_DATA does the same job as PDMIMOUNT_2_DRVHOSTBASE and
PDMIBLOCK_2_DRVHOSTBASE which you mentioned above: It subtracting the
offset of the vtable structure member from the vtable address, thus
ending up with the address of the structure.
About applying object orientation to the PDM model. I'm not sure how
helpful it really is to picture the implementation in C++-ish object
oriented or object based terms. On a conceptual level it map like this:
- A device instance is an object (PDMDEVINS).
- The LUNs are also objects, but they live inside the device object.
- A driver instance an object (PDMDRVINS).
The LUNs and drivers implements a selection of interfaces depending on
their roles and use these for communication.
I hope this was of some help...
Kind regards / Mit freundlichen Gruessen / Vennlig hilsen,
Sun Microsystems GmbH Knut St. Osmundsen
Werkstrasse 24 Senior Staff Engineer, VirtualBox
71384 Weinstadt, Germany mailto:bird at sun.com
Sitz der Gesellschaft: Sun Microsystems GmbH,
Sonnenallee 1, D-85551 Kirchheim-Heimstetten
Amtsgericht Muenchen: HRB 161028
Geschäftsführer: Thomas Schroeder, Wolfgang Engels
Vorsitzender des Aufsichtsrates: Martin Haering
More information about the vbox-dev