Sdílet prostřednictvím


Postupy: Rozšíření knihovny zařazování

Toto téma vysvětluje, jak rozšířit zařazovacího knihovny poskytnout další převody mezi typy dat.Uživatelům můžete rozšířit zařazovacího knihovny pro všechny převody dat není aktuálně podporován v knihovně.

Můžete rozšířit zařazovacího knihovny dvěma způsoby - s nebo bez marshal_context – třída.Recenze Přehled zařazování v jazyku C++ k určení, zda nový převod vyžaduje kontext tématu.

V obou případech je nejprve vytvořit soubor pro zařazování nových převodů.Můžete udělat pro zachování integrity standardní zařazování souborů knihoven.Pokud chcete port projektu do jiného počítače nebo jiným programátorům, musíte zkopírovat nový soubor zařazovacího spolu se zbývající částí projektu.Tímto způsobem uživatel, který obdrží projektu bude zaručen příjem nových převodů a nebudete muset změnit soubory knihovny.

Chcete-li rozšířit knihovnu zařazování v převodu, který nevyžaduje kontext

  1. Vytvořte soubor k uložení nové zařazovací funkce, například MyMarshal.h.

  2. Zahrnovat jeden nebo více souborů marshal knihovny:

    • Marshal.h pro základní typy.

    • marshal_windows.h pro typy dat systému windows.

    • marshal_cppstd.h pro datové typy STL.

    • marshal_atl.h pro ATL datové typy.

  3. Použijte kód na konci takto napsat funkci převodu.V tomto kódu je převést na typ, ze je typ převod z, a from je parametr, který má být převeden.

  4. Nahraďte komentář o logiku převodu kódu pro převod from do objektu na parametr zadejte a vrátit objekt převedený.

namespace msclr {
   namespace interop {
      template<>
      inline TO marshal_as<TO, FROM> (const FROM& from) {
         // Insert conversion logic here, and return a TO parameter.
      }
   }
}

Chcete-li rozšířit zařazovacího knihovny pomocí převodu, který vyžaduje kontext

  1. Vytvořit soubor k uložení nové zařazovací funkce, například MyMarshal.h.

  2. Zahrnovat jeden nebo více souborů marshal knihovny:

    • Marshal.h pro základní typy.

    • marshal_windows.h pro typy dat systému windows.

    • marshal_cppstd.h pro datové typy STL.

    • marshal_atl.h pro ATL datové typy.

  3. Použijte kód na konci takto napsat funkci převodu.V tomto kódu je převést na typ, typ k převodu z, je z toObject je ukazatel pro uložení výsledků, a fromObject je parametr, který má být převeden.

  4. Nahraďte komentář o inicializaci pomocí kódu inicializace toPtr na odpovídající hodnotu prázdný.Například, pokud je to ukazatel, nastavte ji na NULL.

  5. Nahraďte komentář o logiku převodu kódu pro převod from parametr do objektu TO typu.Převedený objekt bude uložen v toPtr.

  6. Nahraďte komentář o nastavení toObject s kódem nastavit toObject do převedeného objektu.

  7. Nahraďte komentář o čištění nativní prostředky s kódem uvolnit paměť přidělenou toPtr.Pokud toPtr přidělené paměti pomocí new, použít delete k uvolnění paměti.

namespace msclr {
   namespace interop {
      template<>
      ref class context_node<TO, FROM> : public context_node_base
      {
      private:
         TO toPtr;
      public:
         context_node(TO& toObject, FROM fromObject)
         {
            // (Step 4) Initialize toPtr to the appropriate empty value.
            // (Step 5) Insert conversion logic here.
            // (Step 6) Set toObject to the converted parameter.
         }
         ~context_node()
         {
            this->!context_node();
         }
      protected:
         !context_node()
         {
            // (Step 7) Clean up native resources.
         }
      };
   }
} 

Příklad

Následující příklad rozšiřuje zařazovacího knihovny pomocí převodu, který nevyžaduje kontext.Kód v tomto příkladu převede informace o zaměstnancích z nativního datového typu na spravovaný datový typ.

// MyMarshalNoContext.cpp
// compile with: /clr
#include <msclr/marshal.h>

value struct ManagedEmp {
   System::String^ name;
   System::String^ address;
   int zipCode;
};

struct NativeEmp {
   char* name;
   char* address;
   int zipCode;
};

namespace msclr {
   namespace interop {
      template<>
      inline ManagedEmp^ marshal_as<ManagedEmp^, NativeEmp> (const NativeEmp& from) {
         ManagedEmp^ toValue = gcnew ManagedEmp;
         toValue->name = marshal_as<System::String^>(from.name);
         toValue->address = marshal_as<System::String^>(from.address);
         toValue->zipCode = from.zipCode;
         return toValue;
      }
   }
}

using namespace System;
using namespace msclr::interop;

int main() { 
   NativeEmp employee;

   employee.name = "Jeff Smith";
   employee.address = "123 Main Street";
   employee.zipCode = 98111;

   ManagedEmp^ result = marshal_as<ManagedEmp^>(employee);

   Console::WriteLine("Managed name: {0}", result->name);
   Console::WriteLine("Managed address: {0}", result->address);
   Console::WriteLine("Managed zip code: {0}", result->zipCode);

   return 0;
}

V předchozím příkladu marshal_as funkce vrátí popisovač převedená data.Důvodem bylo, aby se zabránilo vytváření další kopii dat.Vrací proměnnou přímo by se náklady na zbytečné výkon přidružen.

  

Následující příklad převede informace o zaměstnancích z spravovaný datový typ k nativnímu datovému typu.Tento převod vyžaduje zařazovacího kontext.

// MyMarshalContext.cpp
// compile with: /clr
#include <stdlib.h>
#include <string.h>
#include <msclr/marshal.h>

value struct ManagedEmp {
   System::String^ name;
   System::String^ address;
   int zipCode;
};

struct NativeEmp {
   const char* name;
   const char* address;
   int zipCode;
};

namespace msclr {
   namespace interop {
      template<>
      ref class context_node<NativeEmp*, ManagedEmp^> : public context_node_base
      {
      private:
         NativeEmp* toPtr;
         marshal_context context;
      public:
         context_node(NativeEmp*& toObject, ManagedEmp^ fromObject)
         {
            // Conversion logic starts here
            toPtr = NULL;

            const char* nativeName;
            const char* nativeAddress;

            // Convert the name from String^ to const char*.
            System::String^ tempValue = fromObject->name;
            nativeName = context.marshal_as<const char*>(tempValue);

            // Convert the address from String^ to const char*.
            tempValue = fromObject->address;
            nativeAddress = context.marshal_as<const char*>(tempValue);

            toPtr = new NativeEmp();
            toPtr->name = nativeName;
            toPtr->address = nativeAddress;
            toPtr->zipCode = fromObject->zipCode;

            toObject = toPtr;
         }
         ~context_node()
         {
            this->!context_node();
         }
      protected:
         !context_node()
         {
            // When the context is deleted, it will free the memory
            // allocated for toPtr->name and toPtr->address, so toPtr
            // is the only memory that needs to be freed.
            if (toPtr != NULL) {
               delete toPtr;
               toPtr = NULL;
            }
         }
      };
   }
} 

using namespace System;
using namespace msclr::interop;

int main() {
   ManagedEmp^ employee = gcnew ManagedEmp();

   employee->name = gcnew String("Jeff Smith");
   employee->address = gcnew String("123 Main Street");
   employee->zipCode = 98111;

   marshal_context context;
   NativeEmp* result = context.marshal_as<NativeEmp*>(employee);

   if (result != NULL) {
      printf_s("Native name: %s\nNative address: %s\nNative zip code: %d\n",
         result->name, result->address, result->zipCode);
   }

   return 0;
}
  

Viz také

Koncepty

Přehled zařazování v jazyku C++