Question

J'ai une collection tierce de fichiers .h avec les fichiers .lib qui vont avec. J'emballe ces fichiers C ++ natifs avec un wrapper C ++ / CLI et passe les derniers appels à partir de C #. J'ai un problème lorsque j'appelle des méthodes qui supposent qu'une référence soit transmise et que la valeur ne soit pas modifiée dans mon wrapper, sauf si je la modifie explicitement.

Mon code wrapper C ++ / CLI ressemble actuellement à ceci:

bool get_testInt16(int16% testInt16)
{
   int16* t = static_cast<int16*>(GCHandle::ToIntPtr(GCHandle::Alloc(testInt16)).ToPointer());
   bool b = m_NativeCMTY_TestData->get_testInt16(*t);
   testInt16 = *t;
   return b;
};

Et le code C ++ natif correspondant ressemble à:

bool get_testInt16(int16 &testInt16);

Je pense qu'il doit y avoir une meilleure solution, mais peut-être pas? Laissez juste dire que je l'espère, il y a une meilleure façon!

Était-ce utile?

La solution

Une option serait de faire:

bool get_testInt16(int16% testInt16)
{
   int16 t = testInt16;
   bool b = m_NativeCMTY_TestData->get_testInt16(t);
   testInt16 = t;
   return b;
};

Vous créez donc simplement une variable native locale et vous évitez les énormes transtypages et les pointeurs .NET.

Autres conseils

pour toute raison que vous n'utilisiez pas d'épingler des pointeurs au lieu de GCHandle :: ToIntPtr (GCHandle :: Alloc (testInt16)). ToPointer () ?

Épingler également la valeur référencée comme ceci est trop tard.

Si la référence se rapporte à une valeur de pile, elle est inutile. S'il s'agit d'une référence à un champ d'instance, le code appelant doit alors épingler l'objet (bien qu'il s'agisse d'une fuite désordonnée de semi-optiques non gérées dans le code managé, le comportement de la méthode clear.

Le paramètre ref étant si petit, il serait logique d'éviter tout épinglage et d'en créer un temporaire sur la pile, de le transmettre à la fonction non gérée, puis de l'écrire à nouveau dans l'original.

bool get_testInt16(int16% testInt16)
{
   int16 temp = testInt16;
   bool b = m_NativeCMTY_TestData->get_testInt16(temp);
   testInt16 = temp;
   return b;
};
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top