Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Kommunikation per JSON Strings: Attempted to read or write protected memory
HerrOli
myCSharp.de - Member



Dabei seit:
Beiträge: 16

Themenstarter:

Kommunikation per JSON Strings: Attempted to read or write protected memory

beantworten | zitieren | melden

Hallo
ich habe ein Messprogramm programmiert. Das Programm besteht aus einer C++ und einem C#Teil. Die Kommunikation zwischen den beiden Teilen erfolgt über JSON String.


for (int i = 1; i ≤ anzahl_messungen; i++)
            {
                string messwerte = StringReturnAPI01();         

                Console.WriteLine("\nMessung: " + i);
                Console.ForegroundColor = ConsoleColor.Blue;
                Console.WriteLine(messwerte);
                Console.ResetColor();
                
                // teil json string -> objekt
                JsonString JsonObjekt = new JsonString(messwerte);
                
                // ausgabe json objekt
                foreach (var werte in JsonObjekt.MesswerteArray)
                {
                    js_obj.Add(werte.ToString().Replace(Environment.NewLine, ""));
                }
            }

Nun bekomme ich aber in der Zeile JsonString JsonObjekt = new JsonString(messwerte); die Meldung:
Fehler
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.


Hier noch der DllInport:



class Messung
    {
        [DllImport(@"Pfad zu C++ dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        [return: MarshalAs(UnmanagedType.LPStr)]
        public static extern string StringReturnAPI01();

        [STAThread]
        public static void Main()

An was könnte den der Fehler liegen?

PS: Ich verwende VS2008 und die JSON Library von http://json.codeplex.com/
private Nachricht | Beiträge des Benutzers
Coder007
myCSharp.de - Member



Dabei seit:
Beiträge: 1249

beantworten | zitieren | melden

Am besten auch gleich den betreffenden C++ Teil posten, zumindest die Methodensignatur und wie du den String erstellst und zurückgibst. So kann man nicht sagen, ob das zusammenpasst.
private Nachricht | Beiträge des Benutzers
Floste
myCSharp.de - Member

Avatar #avatar-2376.jpg


Dabei seit:
Beiträge: 1158
Herkunft: Norddeutschland

beantworten | zitieren | melden

Zitat

 [return: MarshalAs(UnmanagedType.LPStr)]
        public static extern string StringReturnAPI01();
Nur mal so aus neugierde: Wie sorgst du dafür, dass der speicher für den LPStr wieder freigegeben wird? Wie allokierst du ihn?

Benutzt du json ausschließlich für interop? Ist eher ungewöhnlich aber ok.
Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!
private Nachricht | Beiträge des Benutzers
HerrOli
myCSharp.de - Member



Dabei seit:
Beiträge: 16

Themenstarter:

beantworten | zitieren | melden

Mein C++ Teil

extern "C" __declspec(dllexport) char*  __stdcall StringReturnAPI01()
{	
	meas();
	int laenge;	
	char *sc_temp = new char [2];
	char *rscp_temp = new char [5];
	//char *iscp_temp = new char [5];
		
	strcpy(szSampleString,"{\"db\":{\"measurements\":[");	
	
	for(i;i≤messreihe-1;i++)
	{
		mw=true;
		strcat(szSampleString,"{\"RSCP\":");
		_gcvt(vecwerte[i].rscp , 5, rscp_temp);	
		strcat(szSampleString,rscp_temp);
		rscp_temp[0]='\0';		
		strcat(szSampleString,",\"SC\":");
		_itoa(vecwerte[i].sc, sc_temp,10);
		strcat(szSampleString,sc_temp);
		
		sc_temp[0]='\0';
		strcat(szSampleString,"},");	
	}
	
	ULONG  ulSize = strlen(szSampleString) + sizeof(char);
	char*  pszReturn = NULL;
 
	pszReturn = (char*)::GlobalAlloc(GMEM_FIXED, ulSize);
	
	if(mw==true)
		szSampleString[strlen(szSampleString)-1]='\0';	
	
	// Copy the contents of szSampleString
	// to the memory pointed to by pszReturn.
	strcpy(pszReturn, szSampleString);
	
	strcat(pszReturn,"]}}");	

	return pszReturn;
}

Habe mich im bei meinem Programm an diesem Beispiel gehalten: Returning Strings from a C++ API to C#
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von HerrOli am .
private Nachricht | Beiträge des Benutzers
Coder007
myCSharp.de - Member



Dabei seit:
Beiträge: 1249

beantworten | zitieren | melden

Du schreibst, dass der Fehler in der Zeile

JsonString JsonObjekt = new JsonString(messwerte);

auftritt. Kannst du denn mit dem Debugger in den String reinschauen, ist er richtig?
private Nachricht | Beiträge des Benutzers
Floste
myCSharp.de - Member

Avatar #avatar-2376.jpg


Dabei seit:
Beiträge: 1158
Herkunft: Norddeutschland

beantworten | zitieren | melden

Ich habe eine idee, wie dein fehler kommt.

1.) Deine bibliothek muss eine free-funktion zur verfügung stellen!
extern "C" __declspec(dllexport) char*  __stdcall StringReturnAPI01()
{
....
}

extern "C" __declspec(dllexport) void __stdcall FreeString(char* string)
{
   //todo
}
2.) char* in c++ ist immer Ansi und CharSet.Auto wird standardmäßig unicode. Unicodestrings werden mit 2 nullbytes beendet. Ansi-strings haben aber nur 1 nullbyte. Deshalb wird über das Ende hinaus gelesen und du kiregst ne Access Violation.
3.) Wenn du kein memoryleak haben willst musst du das mashalling eh selber machen.


        [DllImport(@"Pfad zu C++ dll", CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr StringReturnAPI01();


        [DllImport(@"Pfad zu C++ dll", CallingConvention = CallingConvention.StdCall)]
        public static extern void FreeString(IntPtr ptr);


IntPtr lpstr=StringReturnAPI01();
string result=Marshal.PtrToStringAnsi(lpstr);
FreeString( lpstr);
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Floste am .
Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!
private Nachricht | Beiträge des Benutzers
HerrOli
myCSharp.de - Member



Dabei seit:
Beiträge: 16

Themenstarter:

beantworten | zitieren | melden

Ok Danke
Werde ich morgen Testen
private Nachricht | Beiträge des Benutzers
HerrOli
myCSharp.de - Member



Dabei seit:
Beiträge: 16

Themenstarter:

beantworten | zitieren | melden

Zitat von Floste


IntPtr lpstr=StringReturnAPI01();
string result=Marshal.PtrToStringAnsi(lpstr);
FreeString( lpstr);

Hallo
Bin gerate am Testen,
eine frage die letzten drei Zeilen verstehe ich noch nicht ganz.
An welcher Stelle muss ich die drei Zeilen genau hinzufügen?
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von HerrOli am .
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16148

beantworten | zitieren | melden

Kennst Dein eigenen Code nicht?

Vorher:

for (int i = 1; i ≤ anzahl_messungen; i++)
             {
                 string messwerte = StringReturnAPI01();
 
                Console.WriteLine("\nMessung: " + i);
 

nachher

for (int i = 1; i ≤ anzahl_messungen; i++)
             {
                 IntPtr lpstr=StringReturnAPI01();
                 string messwerte=Marshal.PtrToStringAnsi(lpstr);
                 FreeString( lpstr);
 
                Console.WriteLine("\nMessung: " + i);
 
würde ich mal stark vermuten...
- performance is a feature -

Microsoft MVP - @Website - @blog - @AzureStuttgart - github.com/BenjaminAbt
private Nachricht | Beiträge des Benutzers
HerrOli
myCSharp.de - Member



Dabei seit:
Beiträge: 16

Themenstarter:

beantworten | zitieren | melden

Das war auch mein erster Gedanke
allerdings kommt dann das StringReturnAPI01() unbekannt ist.

Hatte vielleicht vergessen zu sagen das das mein erstes C# Programm ist
und das ich noch nicht so bewandert in dieser Sprache bin.
private Nachricht | Beiträge des Benutzers

Moderationshinweis von herbivore (11.09.2011 - 19:06:33):

Wenn du StringReturnAPI01 wie oben beschrieben per DllImport einbindest, sollte der Fehler verschwinden. Bitte beachte auch [Hinweis] Syntaxfehler selbst lösen (Compilerfehlermeldungen) und [Hinweis] Wie poste ich richtig? Punkt 1.1.1. In [FAQ] Wie finde ich den Einstieg in C#? findest du viele weitere nützliche Hinweise.