Передача структуры C # в C ++ / CLI для оболочки C ++ - PullRequest
1 голос
/ 06 марта 2012

После публикации вопроса вчера я подумал, что это прояснилось, но у меня все еще есть проблемы, у меня есть оболочка C ++ / CLI для класса C ++, некоторые функции класса C ++ принимают в качестве параметров буферы для recv, пакетструктуры определяются как структуры C ++, и это то, что принимается в качестве параметра.

В C # я реплицировал эти структуры C ++, используя structlayout, так что у меня есть эквивалентные структуры в C #, которые расположены в памяти так же, как и мои структуры C ++.В своем коде C ++ / CLI я попытался сделать следующее:

UINT GetValues(value class^ JPVals) // value class, as C# structs are value types
{
IntPtr ptr;
Marshal::StructureToPtr(JPVals,ptr,false);
return m_pComms->GetValues(ptr,0); // m_pComms is a wrapped unmanaged class 
    //GetValues takes a pointer to a C++ struct
}

Ошибка, которую я получаю, не может преобразовать параметр 1 из 'System :: IntPtr' в 'SJPVal *', поэтому Маршалл из значения невозможноуказатель на класс C ++ struct?И в этом случае, что я должен передать и как я должен упорядочить это?

1 Ответ

1 голос
/ 06 марта 2012

Вы не получили процесс сериализации:

// !! Note the % !!
UINT GetValues(value class% JPVals) // value class, as C# structs are value types 
{ 
    // Allocate a buffer for serialization, pointer to NULL otherwise
    IntPtr ptr = Marshal::AllocHGlobal(Marshal::SizeOf(JPVals));

    try {
        // Serialize the managed object to "static" memory (not managed by the GC)
        Marshal::StructureToPtr(JPVals, ptr, false); 

        // Pass it to unmanaged code that will modify it.
        auto ret = m_pComms->GetValues(reinterpret_cast<SJPVal*>(ptr.ToPointer()), 0);

        // Copies the modifications back
        Marshal::PtrToStructure(ptr, JPVals);

        // Free resources
        Marshal::FreeHGlobal(ptr);

        return ret;
    } catch (...) {
        // Make sure we free the memory
        Marshal.FreeHGlobal(ptr);
        throw; 
    }
} 

РЕДАКТИРОВАТЬ: показано, как скопировать обратно значение.

Как вы используете C # struct вам нужно передать его по ссылке, чтобы убедиться, что изменения скопированы обратно.Кроме того, код будет работать так же с C # class.Первый шаг (StructureToPtr), вероятно, теперь бесполезен, так как вы, вероятно, не заботитесь о том, что было там до вашего звонка на GetValues.

Кстати, ваше соглашение об именах немного плохое,Вы должны НЕ начинать имена переменных с заглавной буквы в C ++.

...