u_int32_t CarSize(const Car &car) // (3) { return sizeof(length) * 3 + model.length() + 1 + sizeof(*engine); // (4) } void CopyCar(void *dest, const Car&car) // (5) { // Copy all bytes of the car object into memory chunk M // referenced by dest. // M is preallocated and just big enough because our CarSize is used // to measure the object size. Note the bytes // of the Engine object E referenced by car.engine should be copied // into this M, rather than the car.engine pointer value, // in order to deep copy E. char *p = (char *)dest; memcpy(p, car.length, sizeof(size_t)); p += sizeof(size_t); memcpy(p, car.width, sizeof(size_t)); p += sizeof(size_t); memcpy(p, car.height, sizeof(size_t)); p += sizeof(size_t); memcpy(p, car.model.c_str(), car.model.length() + 1); // (6) p += car.model.length() + 1; // (6) memcpy(p, car.engine, sizeof(*car.engine); // (7) } void RestoreCar(Car &car, const void* src) // (8) { // src references the memory chunk M which contains the bytes of a Car // object previously marshalled by CopyCar function, so we know // the data structure and composition of M. Thus here we can // un-marshal bytes stored in M to assign to each member of car. // Since we have data of the Engine member in M, we should create an // Engine object E using 'new' operator, and assign to its members // using bytes in M, and assign E's pointer to car.engine. char *p = src; memcpy(car.length, p, sizeof(size_t)); p += sizeof(size_t); memcpy(car.width, p, sizeof(size_t)); p += sizeof(size_t); memcpy(car.height, p, sizeof(size_t)); p += sizeof(size_t); car.model = p; // (9) p += car.model.length() + 1; // (9) memcpy(car.engine, p, sizeof(*car.engine); } dbstl::DbstlElemTraits *pCarTraits = dbstl::DbstlElemTraits::instance(); // (10) pCarTraits->set_size_function(CarSize); // (11) pCarTraits->set_copy_function(CopyCar); // (12) pCarTraits->set_restore_function(RestoreCar); // (13)