Laden...

Problem mit P/Invoke

Erstellt von Madome31 vor 9 Jahren Letzter Beitrag vor 9 Jahren 1.003 Views
M
Madome31 Themenstarter:in
8 Beiträge seit 2014
vor 9 Jahren
Problem mit P/Invoke

Hallo,

ich habe wieder mal ein Problem. Diesmal beim P/Invoke einer C Dll. Diese Dll soll ein Input und Output Array als Argumente nehmen und mit diesen dann einige Rechenintensive Operationen durchführen.
Die Methode in der Dll sieht so aus(zum verdeutlichen) :


extern "C"
{
	__declspec(dllexport) void DisplayGoodByeFromDLL(unsigned char* input, int sizeOfArray, unsigned char* output)
	{
		for (int i = 0; i<sizeOfArray; i++){
			output[i] = input[i];
		}
		printf("FINISH");
		
	} 
}

Compilieren der Dll und alles funktioniert ohne Problme, bloß wenn ich die die Methode in C# verwenden möchte erhalte ich folgende Exception :

Fehlermeldung:

ConsoleApplication1.Program::DisplayGoodByeFromDLL" hat das Gleichgewicht des Stapels gestört. Wahrscheinlich stimmt die verwaltete PInvoke-Signatur nicht mit der nicht verwalteten Zielsignatur überein. Überprüfen Sie, ob die Aufrufkonvention und die Parameter der PInvoke-Signatur mit der nicht verwalteten Zielsignatur übereinstimmen.

Ich weiß, dass die Exception von dem Methodenaufruf kommt, und das die Methode in der Dll aber fertig gelaufen ist. Deswegen habe ich auf verschiedenste Arten versucht die Methode aufzurufen :


[DllImport("Win32Project1.dll")]
public static extern void DisplayGoodByeFromDLL([In, Out]byte[] input, int Size, [In, Out]byte[] output);


[DllImport("Win32Project1.dll")]
public static extern void DisplayGoodByeFromDLL([In, Out, MarshalAs(UnmanagedType.LPArray)]byte[] input, int Size, [In, Out, MarshalAs(UnmanagedType.LPArray)]byte[] output);


[DllImport("Win32Project1.dll")]
public static extern void DisplayGoodByeFromDLL([In, Out]IntPtr input, int Size, [In, Out] IntPtr output);

Das die ersten beiden Versuche mit einem ganz normalen methodenaufruf, den letzten mit folgendem Code :


            byte[] test = new byte[512];
            byte[] test2 = new byte[512];
            for (int i = 0; i < 512; i++)
            {
                test[i] = 25;
            }
            GCHandle pinnedRawData = GCHandle.Alloc(test, GCHandleType.Pinned);
            GCHandle pinnedRawData2 = GCHandle.Alloc(test2, GCHandleType.Pinned);
            try
            {
                IntPtr pin = pinnedRawData.AddrOfPinnedObject();
                IntPtr pin2 = pinnedRawData2.AddrOfPinnedObject();
                DisplayGoodByeFromDLL(pin, 512, pin2);
                Marshal.Copy(pin2, test2, 0, 512);
            }
            finally
            {
                pinnedRawData.Free();
                pinnedRawData2.Free();
            }

Ich erhalte aber jedes Mal die selbe Exception. Ich finde einfach keine Lösung zu diesem Problem.
Ich hoffe ihr könnt mir helfen.

Vielen Dank schon einmal

Madome31

W
872 Beiträge seit 2005
vor 9 Jahren

In Deinem Fall musst Du höchstwahrscheinlich

CallingConvention=CallingConvention.Cdecl

Funktionierte jedenfalls bei mir.
Oder im C++ Code noch

__stdcall

hinzufügen.

M
Madome31 Themenstarter:in
8 Beiträge seit 2014
vor 9 Jahren

@weismat : Danke, hat das Problem gelöst, jetzt funktioniert alles. Vielen Dank

Der Code :


[DllImport("Win32Project1.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void DisplayGoodByeFromDLL([In, Out]IntPtr input, int Size, [In, Out] IntPtr output);