开发者

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_ENTRYs 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜