Laden...

Forenbeiträge von mifi261 Ingesamt 3 Beiträge

02.07.2020 - 07:38 Uhr

Habe meinen Fehler selbst gefunden, war ein Anfänger Fehler. Hatte vergessen den Speicher im Managed Bereich zu Allokieren. 😭

Habe nun "innere_ = new Innere();" in der For-Schleife eingefügt jetzt klappt alles wie gewünscht.


        main()
         {
             IntPtr pAeusere;

             getData(pAeusere);

             Aeusere aeusere = (Aeusere) Marshal.PtrToStructure(pAeusere, typeof(emxArray));

             // Bisheriger Versuch Daten zu kopieren
             Innere[] innere = new Innere[aeusere.size];
             for (int i = 0; i < aeusere.size; i++)
             {
                 IntPtr pElement = new IntPtr(aeusere.data.ToInt32() + Marshal.SizeOf(typeof(Innere)) * i);
                 Innere element =  (Innere) Marshal.PtrToStructure(pElement, typeof(Innere)); // Geht (Element enthält richtige Daten)
                 innere[i] = new Innere();  // Hier war der Fehler
                 innere[i] = element;   // Hier tritt Exception auf
             }
         } 

01.07.2020 - 16:09 Uhr

Danke für deine Antwort, bei mir im Programm haben die Strukturen und Variablen andere Namen. Beim kopieren habe ich wohl vergessen alle zu ändern, daher sollte "emxArray" eigentlich "Aeusere" heißen.

Leider kann ich im C++ Code nichts ändern, dieser ist fest vorgegeben.

01.07.2020 - 15:10 Uhr

Hallo zusammen,

ich möchte in C# eine Funktion aus einer C++ DLL aufrufen. Diese Funktion liefert mir einen Pointer auf Äußere Struktur zurück. Diese Äußere Struktur enthält wiederum ein Array bzw. Pointer auf eine Innere Struktur.

Meine Frage ist nun, wie kann ich die Daten des Array of Structs aus dem Unmanaged Bereich in ein Array of Struct in den Managed Bereich kopieren.
Folgend ist die Realisierung der Strukturen, sowie der Realisierte Aufruf der C++ Funktion und ein Lösungsvorschlag zum kopieren der Daten:


		[StructLayout(LayoutKind.Sequential)]
        private struct Innere
        {
            public IntPtr data;
            public int size;
            //Weitere Felder
        }
		
		[StructLayout(LayoutKind.Sequential)]
        rivate struct Aeusere
        {
            public Int32 iValue1;
            public Int32 iValue2;
            public double dValue;                               
        };
		
		[DllImport(DLLPfad, CallingConvention = CallingConvention.Cdecl)]
        private static extern void getData(IntPtr Data);
		
		main()
		{
			IntPtr pAeusere;
			
			getData(pAeusere);
			
			Aeusere aeusere = (Aeusere) Marshal.PtrToStructure(pAeusere, typeof(emxArray));
            
			// Bisheriger Versuch Daten zu kopieren
            Innere[] innere = new Innere[aeusere.size];
            for (int i = 0; i < aeusere.size; i++)
            {
                IntPtr pElement = new IntPtr(aeusere.data.ToInt32() + Marshal.SizeOf(typeof(Innere)) * i);
                Innere element =  (Innere) Marshal.PtrToStructure(pElement, typeof(Innere)); // Geht (Element enthält richtige Daten)
                innere[i] = element;   // Hier tritt Exception auf
            }
		}


Strukturen und Funktion in C++:



struct Innere
{
  int iValue1;
  int iValue2;
  double dValue;
};

struct aeusere
{
  Innere *data;
  int size;
  // Weitere Felder
};

DLL_EXPORT void getData(Aeusere* pAeusere)
{
	//Allokiere Speicherplatz für aeusere und Befülle aeusere
}


Beim bisherigen Versuch kann ich Problemlos die Außere Struktur auf meine C# Variable kopieren. Ebenso kann ich die Daten der Inneren Struktur auf meine Variable element kopieren.
(Im Überwachungsfenster beim Debuging werden mir die richtigen Werte innerhalb der Variablen element angezeigt.)

Erst bei der Zuweisung der Element Variable an das Array (innere) (im Code markiert) tritt eine mit folgendem Wortlaut Exception auf:
"Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."

Ich verstehe jedoch nicht wieso die Variable element nicht zugewiesen werden kann? Im Überwachungsfenster ist sie ja schließlich befüllt und nicht "null".
Hatte jemand schon ein solches Problem oder kann jemand einen Fehler in meinem Programm feststellen?