System.AccessViolationException bei Aufruf von C++-Funktion aus C#-Form
-
Hallo,
ich habe eine C++ (mit MFC/CLI) Erweiterung für ein Programm geschrieben, dass über einen Thread eine bestimmte Tastenkombination erkennt und dann eine C#-Form aufruft. In der C#-Form mache ich dann weitere Sachen, drücke am Ende auf einen Button, welcher ein Event auslöst, das ich im C++-Code abfange und eine Funktion aufrufen lasse. Diese Funktion führt dann eine weitere SDK-Funktion auf. Beim Aufruf bekomme ich eine System.AccessViolation Exception, die im catch der C#-Funktion geworfen wird.
Warum diese Exception geworfen wird kann ich leider nicht so ganz verstehen. Ich habe mir schon ergoogelt, dass so eine Exception auftritt, wenn unmanaged und managed Code aufeinander stößt und auf nicht zugewiesenem oder nicht freigegebenen Speicher zugegriffen werden soll. Von Speicherverwaltung in C++ und überhaupt C++ habe ich allerdings nicht besonders viel Ahnung...
Ich weiss leider nicht wie ich im C++-Code der C#-Form erlauben kann die Funktion aufzurufen. Hat vielleicht jemand eine Idee, was ich falsch machen könnte?Schon einmal vielen Dank für Bemühungen!
LG
Florian[cli] Global::Form1 = gcnew ShortcutDialer(); //Rufe OnDial()-Funktion auf, wenn ein DialEventArgs kommt: Global::Form1->Dial += gcnew EventHandler<DialEventArgs^>(&OnDial); ... void OnDial(Object^ sender, DialEventArgs^ e) { CVoxCommandResults Results; CString strMessage; strMessage.Format(_T("<Command Name='PHONEDOACTION'><Action>DIAL</Action><ActionInfo><PhoneNumber>%s</PhoneNumber><CallType>%s</CallType><DialType>IVR</DialType></ActionInfo></Command>"), e->Number, Global::Calltype); //execute the command ExecCommandWithResults((TCHAR*)(LPCTSTR)strMessage, &Results); } [/cli]
-
Du kannst den String e->Number nicht einfach als Zeiger in einem Nativen Progamm benutzen. Du musst diesen String schon marshallen un din einen gültigen Zeiger umwandeln.
Das muss ja sonst krachen.
-
Dieser Thread wurde von Moderator/in Martin Richter aus dem Forum MFC (Visual C++) in das Forum C++/CLI mit .NET verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Ich habe einen neuen Pointer deklariert, der die e->Number marshallt. Macht leider keinen Unterschied. Ich glaube auch nicht, dass es da irgendwo dran liegt. Die Exception fliegt bei der ExecCommandWithResults()-Funktion.
Gibt es irgendwelche Berechtigungsshemen, wie ich meiner Form erlauben kann darauf zuzugreifen? Ich glaube, dass die c#-Form auf Speicher(Die Funktion) des C++-Programmes zugreifen will, das aber aus irgendwelchen Gründen nicht darf.
[cli] char* str_number = (char*)(void*)Marshal::StringToHGlobalAnsi(e->Number); strMessage.Format(_T("<Command Name='PHONEDOACTION'><Action>DIAL</Action><ActionInfo><PhoneNumber>%s</PhoneNumber><CallType>%s</CallType><DialType>IVR</DialType></ActionInfo></Command>"), str_number, Global::Calltype); [/cli]
-
Was ist denn "Number" für ein Datentyp? String^?
Und warum castest Du so of (LPCTSTR und TCHAR*). Du konvertierst nach ANSI! Und verwendest dann aber TCHAR*! Was hast Du eingestellt Unicode oder MBCS???
Wenn Unicode, dann verwende bitte: StringToHGlobalUni!
-
Habe das Problem endlich gelöst und gefixt:
Ich hatte eine neue Form über einen WINAPI-Thread, der die Tatenkürzel erkennt erstellt. Von da aus war es der Form nicht erlaubt auf den Speicher/die Funktion (ExecCommandWithResults) zuzugreifen. Ich hab das jetzt so gelöst, dass ich die Form außerhalb des Thrads erstelle und im Thread nur zwischen sichtbar und unsichtbar wechsele. Dann gehts.
Es lag also gar nicht an der OnDial()-FunktionTrotzdem Vielen Dank für Eure Tipps!