Передача структуры C++/CLI в IronPython PythonFunction

Я начинаю с C++/CLI в сочетании с IronPython :) У меня возникла проблема с управляемыми структурами в коде Python. Моя структура выглядит так

[System::Runtime::InteropServices::StructLayout(
    System::Runtime::InteropServices::LayoutKind::Sequential)]
public value struct VersionInfo
{
    [System::Runtime::InteropServices::MarshalAsAttribute(
        System::Runtime::InteropServices::UnmanagedType::U4)]
    DWORD Major;
};

Передача этой структуры в Python выглядит следующим образом

VersionInfo^ vi = gcnew VersionInfo();
vi->Major = 12345;

IronPython::Runtime::PythonFunction^ function = 
    (IronPython::Runtime::PythonFunction^)
        m_PluginScope->GetVariable("GetGlobalInfo");

array<VersionInfo^>^ args = gcnew array<VersionInfo^>(1)
{
    vi
};

auto result = m_Engine->Operations->Invoke(function, args);

И, наконец, код Python:

def GetGlobalInfo(info):
    info.Major = 55
    return info.Major

Возвращаемое значение в result равно не 55, как ожидалось, а 12345. Может ли кто-нибудь помочь мне выяснить, почему значение не изменилось из кода Python? Спасибо


person Patrik Polakovic    schedule 19.05.2017    source источник


Ответы (1)


Я не знаю, является ли это причиной вашей проблемы, но:

public value struct VersionInfo

vs

VersionInfo^ vi
array<VersionInfo^>^

Эти две вещи конфликтуют: value struct в C++/CLI определяет тип значения, а не ссылочный тип, поэтому вы не хотите использовать для него ^. законно определять подобную переменную в C++/CLI, но это очень нестандартно, и вы даже не можете иметь подобную переменную в C#.

Попробуйте без ^ и посмотрите, какой у вас результат. Однако будьте осторожны, потому что теперь вставка vi в массив создаст дубликат vi, который будет изменен независимо.

В качестве альтернативы вы можете изменить VersionInfo на public ref class, и тогда остальная часть вашего кода будет правильной и стандартной.

person David Yaw    schedule 19.05.2017
comment
Спасибо. Я заменил value на ref в определении структуры, и теперь это работает. - person Patrik Polakovic; 19.05.2017