turning a std::vector of objects in to an array of structures
I have a VS2008 C++ program where I'm wrapping a C API for use in a C++ program. The C API is expecting an array of TABLE_ENTRY values as shown below.
Other than copying the data from each of the MyClass structures in to a new TABLE_ENTRY structure in MyClassCollection::GetTable()
, is there a way to get the functionality I'm looking for?
Thanks, PaulH
struct TABLE_ENTRY {
const char* description;
DWORD value;
};
class MyClass
{
public:
MyClass( const char* desc, DWORD value ) :
description( desc ),
some_value( 1 )
{
};
TABLE_ENTRY* GetTable()
{
entry_.description = description.c_str();
entry_.va开发者_如何学JAVAlue = some_value;
return &entry_;
};
TABLE_ENTRY entry_;
std::string description;
DWORD some_value;
};
class MyClassCollection
{
public:
TABLE_ENTRY* GetTable()
{
return collection_.front()->GetTable();
};
void Add( MyClass* my_class )
{
collection_.push_back( my_class );
}
private:
std::vector< MyClass* > collection_;
};
int _tmain( int argc, _TCHAR* argv[] )
{
MyClass class1( "class1", 1 );
MyClass class2( "class2", 2 );
MyClassCollection collection;
collection.Add( &class1 );
collection.Add( &class2 );
TABLE_ENTRY* table = collection.GetTable();
// table is to be used by the C API. Therefore, these next
// calls should function as shown.
TABLE_ENTRY entry1 = table[ 0 ]; // should be class1's table (works)
TABLE_ENTRY entry2 = table[ 1 ]; // should be class2's table (full of junk)
return 0;
}
I'd go for copying to a vector<TABLE_ENTRY>
and pass &entries[0]
to the C API.
And, I would not store the TABLE_ENTRY
s in your C++ class. I'd only make them just as you call the API, and then throw them away. That's because the TABLE_ENTRY
duplicates the object you copy from, and it is storing a direct char*
pointer to a string who's memory is managed by a std::string. If you modify the source string (and cause reallocation), you have a dangling pointer.
To get an array: (this is made legal by C++03, but all C++98 implementations appear to support it too)
&vec[0]
Notice that the vector still owns the contents, so don't delete the memory or realloc it.
if your fields were identical (string != char*) you could cast your object to void* and then cast to structure with some offset (to skip VMT and other OOP stuff)
By asking for a TABLE_ENTRY array, the API lets you know that it expects data to be arranged in memory in this specific manner. There is no way of meeting the API's expectations with data arranged any differently, so you are out of luck.
精彩评论