Ich habe versucht, einen Klassenzeiger von einer nativen DLL an CLR zu übergeben. Ich bin damit nicht so erfolgreich. Ich komme an den Punkt, der den Zeiger mit void * zurückgibt und ihn später mit IntrPtr und ToPointer() in ClassType * umwandelt. Aber sobald ich versuche, auf seine Member-Methoden zuzugreifen, ist es nicht möglich, die alten Eigenschaftswerte zu erhalten. Ich bekomme stattdessen 0 und einige zufällige Werte.Können Objektzeiger zwischen CLR und nativem C++ übergeben werden?
Ich habe sogar versucht, VC100 als Toolset für die CLR und native DLL zu verwenden. Ich bekomme immer noch den Wert "Fehler beim Lesen der Zeichen der Zeichenfolge".
Ich habe versucht, google und kann nicht viele Informationen über die Übergabe von Objektzeigern von nativen CLR finden. Ich habe mich sogar auf das step-by-step verfügbare Code-Projekt bezogen.
Edited dies hinzufügen:
Ich habe eine native DLL, wo eine Funktion, die Objektzeiger
Native.dll zurück:
#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..
}
...
}
Und später in verwaltetem Code clr I Rufen Sie den memberFunct1 mit dem Rückgabezeiger auf.
[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();
Ich benutze dieses obj1 Zeiger ein Element-Methode aufrufen, aber in dem Element-Methode als schlecht ptr die Mitgliedswerte zeigen.
Kann mir bitte jemand in die richtige Richtung zeigen?
Vielen Dank im Voraus.
Ich habe eine zusätzliche Methode in meiner nativen DLL hinzugefügt.
void DLL_EXPORT SomeMethod2(int i1, const char* var1, const char* var2, Obj1* retval);
und nannte es aus meinem CLR Projekt
[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));
Aber ich Linkfehler bekommen? Ich habe es schon verlinkt ?? !! ??
Fehler LNK2028: unaufgelöster Token (0A000356) "public: __thiscall Obj1 :: Obj1 (int, Zeichenkonst *, Zeichenkonst *)" (?? 0Obj1 @@ $$ FQAE @ HPBD0 @ Z) verwiesen in Funktion " int __cdecl main (void) "
Fehler LNK2028: nicht aufgelöstes Token (0A00035B)" void __cdecl SomeMethod2 (int, Zeichenkonst *, Zeichenkonst *, Klasse Obj1 *) "(? SomeMethod2 @@ $$ FYAXHPBD0PAVObj1 @@@ Z) referenziert in der Funktion "int __cdecl main (void)"
Fehler LNK2019: nicht aufgelöstes externes Symbol "public: __thiscall Obj1 :: Obj1 (int, char const *, char const *) "(?? 0Obj1 @@ $$ FQAE @ HPBD0 @ Z) referenziert in der Funktion" int __cdecl main (void) "(? main @@ $$ HYAHXZ)
Fehler LNK2019: nicht aufgelöstes externes Symbol "void __cdecl SomeMethod2 (int, Zeichenkonst *, Zeichenkonst *, Klasse Obj1 *)" (? SomeMethod2 @@ $$ FYAXHPBD0PAVObj1 @@@ Z) referenziert in der Funktion "int __cdecl main (ungültig) "(?)Haupt @@ $$ HYAHXZ)
@Martin Sorry, ich habe meinen Beitrag bearbeitet und einige Codes hinzugefügt. – ras
Dies ist ein Moor-Standard [Dangling Pointer Bug] (https://en.wikipedia.org/wiki/Dangling_pointer). Ein sehr häufiger Fehler in einem C- oder C++ - Programm, normalerweise sehr schwer zu diagnostizieren. Aber nicht, wenn Sie pinvoke verwenden, sorgt der Stack-Platz, den der pinvoke marshaller benötigt, dafür, dass "obj" zuverlässig überschrieben wird. Sie müssen es woanders speichern, der beste Platz ist fast immer der Stapelrahmen des Anrufers. Ändern Sie den Rückgabetyp in void und fügen Sie einen Parameter "Obj1 * retval" hinzu. –
@HansPassant Ich habe es auch versucht. Aber ich bekomme immer noch einen Linkfehler. Ich habe meinen Beitrag bearbeitet, um das, was Sie erwähnt haben, einzuschließen und ein Bild hinzugefügt, das den Link zeigt. – ras