2016-12-20 2 views
0

Мне нужно заполнить собственные структуры из управляемых классов. Следуя методу (1. скопируйте управляемые данные в управляемый массив байтов, 2. используйте memcopy для заполнения собственной структуры). Я нашел для этого общее решение. Я предполагаю, что причина, по которой следующий код не работает, заключается в том, что я использую управляемые классы, не управляемые structs. Управление командами - это требование в моем проекте. Могу ли я заставить этот код работать с управляемыми классами или я должен переключиться на управляемые структуры?копия из управляемого класса в собственную структуру

это C# класс управляемый:

[StructLayout(LayoutKind.Sequential)] 
public class man_s 
    { 
    public man_s() 
    { 
     // (do something which i can't do in a struct!) 
    } 

    // should go into a one-byte native bool 
    [MarshalAs(UnmanagedType.I1)] 
    public bool flag1; 

    public Int32 a; 

    public Int32 b; 
    }; 

... родная касты структура:

struct nat_s 
    { 
    public: 
      bool flag1; 
      __int32 a; 
      __int32 b; 
    }; 

... код, который необходимо скопировать управляемые данные в нативную структуру:

// setup some managed data 
man_s^ mng = man_s(); 
    mng->flag1 = true; 
    mng->a = 10; 
    mng->b = 20; 

    nat_s nat; 
    int s = sizeof(nat); 

    // size check is ok! 
    System::Diagnostics::Debug::Assert(sizeof(nat) == System::Runtime::InteropServices::Marshal::SizeOf(mng)); 

    // copy into managed byte array 
    array<byte>^ byteArray = gcnew array<byte>(s); 
    System::Runtime::InteropServices::Marshal::Copy(IntPtr((void*)(&mng)), byteArray, 0, s); 

    // this doesn't bring up the expected results 
    pin_ptr<byte> start = &byteArray[0]; 
    memcpy(&nat, start, s); 

    // does not work either 
    System::Runtime::InteropServices::Marshal::Copy(byteArray, 0, IntPtr((void*)(&nat)), s);enter code here 

ответ

0

Marshal.Copy предназначен для копирования данных между управляемыми массивами и неуправляемыми массивами. Это не то, что у вас здесь: у вас есть управляемый объект и невозмущенная структура. Для этого вам нужны методы PtrToStructure и StructureToPtr. Эти методы предназначены для копирования между управляемым объектом и неуправляемой памятью.

// Despite the name, man_s is a managed class, not a managed struct. 
// This means it gets the^(which you had correct), 
// but it also means it gets gcnew (which you were missing). 
man_s^ mng = gcnew man_s(); 
nat_s nat; 

// You had this code is correct. 
Debug::Assert(sizeof(nat) == Marshal::SizeOf(mng)); 

// StructureToPtr copies to unmanaged memory. 
// An unmanaged array (i.e., allocated with `malloc` or `new byte[]`) 
// would work, but a pointer to the unmanaged struct will also work just fine. 
// The `false` means "Don't destroy the object that's already at the destination", 
// which I believe does not apply here. 
Marshal::StructureToPtr(mng, &nat, false); 

// You can go the other way as well. 
Marshal::PtrToStructure(&nat, mng); 
// or 
man_s = Marshal::PtrToStructure<man_s>(&nat); 

Примечание: Я не в компиляторе прямо сейчас. Возможно, вам понадобится наложить &nat на IntPtr.

+0

спасибо за хороший выбор – deafjeff

0

No. AFAIK вы не можете этого сделать. Вы ничего не знаете о макете памяти управляемого ref class. Вы можете выделить внутри класса value type. Вы можете привязать это и скопировать это как целый блок.

Также я не понимаю ваш код. Вы копируете управляемую память с помощью Marshal :: Copy. И вы делаете это при преобразовании управляемого класса в собственный указатель. Затем вы скопируете это в управляемую память и снова скопируете эту управляемую память в нужную память! Почему вообще? Если у вас есть пин-указатель, который работает как собственный указатель.

+0

Как было сказано выше, чтобы скопировать управляемый в native, я узнал его как: во-первых, скопируйте в управляемый массив байтов, а затем сделайте byteewise memcpy в нативную структуру. Это все. Может быть, слишком много. Я дам ему попробовать с меньшим шагом, используя тип значения. Спасибо, в любом случае! – deafjeff

+0

ах, последний маршал :: Копия в коде, прокомментированном «не работает», - это всего лишь вторая попытка, которая, как я знаю, тоже должна потерпеть неудачу. – deafjeff

+0

..протестировано, вам нужно 2 шага, так как pin_ptr требует стандартного типа (байт) для установки memcpy. – deafjeff

Смежные вопросы