J'ai essayé de passer un pointeur de classe d'une DLL native à CLR. Je n'ai pas tellement de succès avec ça. J'arrive au point où il retourne le pointeur en utilisant void * et plus tard, il le convertit en ClassType * en utilisant IntrPtr et ToPointer(). Mais la minute où j'essaie d'accéder à ses méthodes membres, ce n'est pas en mesure d'obtenir les anciennes valeurs de propriété. Je reçois à la place 0 et quelques valeurs aléatoires.Les pointeurs d'objet peuvent-ils être transmis entre CLR et C++ natif?
J'ai même essayé d'utiliser VC100 comme jeu d'outils pour le CLR et la DLL native. Pourtant, j'ai la valeur "Erreur de lecture des caractères de chaîne".
J'ai essayé de google et ne peux pas trouver beaucoup d'information sur passer des pointeurs d'objet d'indigène à CLR. J'ai mentionné même le step-by-step disponible dans le projet de code.
Edité ajouter ceci:
J'ai un dll natif où une fonction qui renvoie un pointeur d'objet
Native.dll:
#if defined EXPORTDLL // inside DLL
#define DLL_EXPORT __declspec(dllexport)
#else // outside DLL
#define DLL_EXPORT __declspec(dllimport)
#endif
.....
DLL_EXPORT void* SomeMethod(uint16_t num1, const char * str1, const char * str2)
{
Obj1 obj(...);
...
return (void*)&obj; // <- at this point it is still correct
}
....
class DLL_EXPORT Obj1{
....
const std::string var1;
const std::string var2;
const std::string var3;
....
DLL_EXPORT strct1 memberFunction1()
{
// do something with the variables
// here when its called by managed code, the var1, var2, var3 shows random values and bad ptr..
}
...
}
Et plus tard dans le code managé clr I appelez memberFunct1 en utilisant le pointeur de retour.
[DllImport("Native.dll", EntryPoint = "[email protected]@[email protected]@@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]", CallingConvention = CallingConvention::Cdecl)]
IntPtr * SomeMethod(uint16_t num1, [In, MarshalAs(UnmanagedType::LPStr)]String^ str1, [In, MarshalAs(UnmanagedType::LPStr)] String^ str2);
.....
String^ str1 = gcnew String("1223568");
String^ str2 = gcnew String("1.2.3.5");
Obj1 *objptr = (Obj1*)(SomeMethod(1,str1, str2)).ToPointer();
// <- at this point the objptr properties are showing garbage
objptr->memberFunction1();
J'utilise ce pointeur obj1 pour appeler une méthode membre, mais dans la méthode membre des valeurs membres font preuve aussi mauvais ptr.
Quelqu'un peut-il me diriger dans la bonne direction s'il vous plaît?
Merci d'avance.
J'ai ajouté une méthode supplémentaire dans ma DLL native.
void DLL_EXPORT SomeMethod2(int i1, const char* var1, const char* var2, Obj1* retval);
et l'a appelé de mon projet CLR
[DllImport("Native.dll", EntryPoint = "[email protected]@[email protected]@@Z", CallingConvention = CallingConvention::Cdecl)]
void SomeMethod2(int i1, [MarshalAs(UnmanagedType::LPStr)]String^ var1, [MarshalAs(UnmanagedType::LPStr)]String^ var2, Obj1* retval);
....
Obj1 * testPtr3;
SomeMethod2(1, (char*)(void*)Marshal::StringToHGlobalAnsi(str1), (char*)(void*)Marshal::StringToHGlobalAnsi(str2), testPtr3);
SomeMethod2(1, str1, str2, testPtr3);
Obj1 testPtr2 = Obj1(1, (char*)(void*)Marshal::StringToHGlobalAnsi(str1), (char*)(void*)Marshal::StringToHGlobalAnsi(str2));
Mais je reçois des erreurs de lien? Je l'ai déjà lié ?? !! ??
erreur LNK2028: jeton non résolu (0A000356) "public: __thiscall Obj1 :: Obj1 (int, char const *, char const *)" (?? 0Obj1 @@ $$ FQAE @ HPBD0 @ Z) référencé dans la fonction " int __cdecl principal (void) »
erreur LNK2028 (principale @@ $$ HYAHXZ?): jeton non résolu (0A00035B) "void __cdecl SomeMethod2 (int, char const *, char const *, classe Obj1 *)"(? SomeMethod2 @@ $$ FYAXHPBD0PAVObj1 @@@ Z) référencé dans la fonction "int __cdecl main (void)" (? Main @@ $$ HYAHXZ)
erreur LNK2019: symbole externe non résolu "public: __thiscall Obj1 :: Obj1 (int, char const *, char const *) "(?? 0Obj1 @@ $$ FQAE @ HPBD0 @ Z) référencé dans la fonction" int __cdecl main (void) "(? main @@ $$ HYAHXZ)
erreur LNK2019: symbole externe non résolu "void __cdecl SomeMethod2 (int, char const *, char const *, classe Obj1 *)" (? SomeMethod2 @@ $$ FYAXHPBD0PAVObj1 @@@ Z) référencé dans la fonction "int __cdecl main (vide) "([email protected]@ principale $$ HYAHXZ)
@Martin Désolé, j'ai édité ma publication et ajouté quelques codes. – ras
Ceci est une norme de tourbière [bug pointeur dangling] (https://en.wikipedia.org/wiki/Dangling_pointer). Un bogue très courant dans un programme C ou C++, généralement très difficile à diagnostiquer. Mais pas quand vous utilisez pinvoke, l'espace de pile requis par le marshaller pinvoke garantit que 'obj 'est écrasé de manière fiable. Vous devez le stocker ailleurs, le meilleur endroit est presque toujours le cadre de la pile de l'appelant. Remplacez le type de retour par void et ajoutez un paramètre 'Obj1 * retval'. –
@HansPassant J'ai aussi essayé le vôtre. Mais j'ai toujours une erreur de lien. J'ai modifié mon message pour inclure ce que vous avez mentionné et ajouté une image montrant le lien. – ras