byte[] in char[]



  • Hallo,

    vielen Dank für den Hinweis.

    Ich habe mittlerweile eine andere Lösung. Geht die auch?

    int Insert(Byte^ object)
    	{
    		int Oid = 0;
    		const int length = object->Length;
    		array<char>^ CharArr;
    		CharArr = gcnew array<char>(length);
    		//Copy Byte array into gc char Array
    		object->Copy(object, CharArr, object->Length);
    		pin_ptr<char> pinnedPointer = &CharArr[0]; 
    		//set native pointer to pinned address of gc heap...
    		char *nativePointer = pinnedPointer;
    		Oid = unmanagedObject->CreateBlob(nativePointer, length);
    		return Oid;
    	}
    

    Deine Lösung sieht aber besser aus...
    Ich glaube, dass dies auch geht, da das erzeugte array keine managed objekte enthält. Aber dazu muß ich erst einmal dieses erzeugen mit einem weiteren gc array.

    p.s. Dein Code funktioniert nichnt wenn ich dass unsigned entferne bei char. Wofür ist das gut? Ist dies ein Problem, wenn ich es so wie von Dir verwende?



  • Char in C++/CLI ist != char!!!

    System::Char ist 2 Byte, während "char" nur ein Byte ist!

    System::Byte ist ein "unsigned char"; char ansich ist signed...



  • Hallo,

    ich glaube ich rufe in C#, die c++/cli funktion falsch auf.

    Wrapper wrapperClass = new Wrapper();
    Byte[] a = new Byte[2024];
    //a[i] = 1; für alle indexe...
    wrapperClass.Insert(a);
    

    Und hier in C++/Cli

    void Insert(array<System::Byte> ^largeObject)
    	{
    		pin_ptr<System::Byte> pinPtr = &largeObject[0];   // pin pointer to first element
    		unsigned char *pArr = pinPtr;   // pointer to the first element in arr
    		char *unmanagedArray = new char[largeObject->Length];
    		memcpy(unmanagedArray, pArr, largeObject->Length);
    		Oid = unmanagedObject->CreateBlob(unmanagedArray, largeObject->Length);
    	}
    

    Wenn ich im Debug Modus das largeObject anscheue, so hat es Kästchen hinter den Zahlen.

    Ich muß der nativen funktion ein char* value übergeben. unsigned char *value wird nicht unterstützt.

    Vielen Dank für die Hilfe!



  • Du rufst es schon richtig auf... mach es aber so wie ich geschrieben habe...

    void Insert(array<System::Byte> ^largeObject)
    {
      pin_ptr<System::Byte> pinPtr = &largeObject[0];
      unsigned char* pArr = pinPtr;
      // Vorausgesetzt die Methode ändert die Daten nicht! Sonst musst DU es zuerst kopieren!!!
      unmanagedObject->CreateBlob((char*) pArr, largeObject->Length);
    }
    


  • PS: Ich würde auch noch ein wenig Fehlerhandling einbauen...

    void Insert(array<System::Byte> ^largeObject)
    {
      if (largeObject == nullptr) return;
      if (largeObject->Length <= 0) return;
      // ...
    }
    


  • Hier ist die weitere Funktion:

    unsigned int CreateBlob( char *buf, int count)
    	{
    		Oid			lobjId;
    		int			lobj_fd;
    		int			tmp;
    		int			nBytes;
    		char		*tmpBuf;
    
    		lobjId = lo_creat(conn, INV_READ | INV_WRITE);
    		if (lobjId == 0)
    			fprintf(stderr, "can't create large object");
    
    		lobj_fd = lo_open(conn, lobjId, INV_WRITE);
    		int i = 0;
    		while (i < count)
    		{
    			int size = i * sizeof(char) + BUFSIZE * sizeof(char);
    			if (size< count)
    			{
    				nBytes = BUFSIZE;
    			}else
    			{
    				nBytes = count - i * sizeof(char);
    			}
    			//std::copy(buf + i, buf + i + nBytes, tmpBuf);
    			tmpBuf = buf + i * sizeof(char);
    			tmp = lo_write(conn, lobj_fd, tmpBuf, nBytes);
    			if (tmp < nBytes)
    			{
    				fprintf(stderr, "error while creating Blob from argument");
    			}
    			i +=BUFSIZE;
    		}
    		lo_close(conn, lobj_fd);
    		return lobjId;
    	}
    

    In der ersten Iteration sollte tmpBuf auf dieselbe Adresse wie buf zeigen. Somit sollten dort die Daten liegen, die vorher importiert wurden.

    Nach dem Aufrufen von lo_write wird aber eine -1 zurückgegeben, dass etwas nicht funktioniert hat. Ich verwende diese Klasse auch in einer reinen c++/cli Klasse und es funktioniert hier so:

    char buf[2048];
    	for (int i = 0; i < 2048; i++)
    	{
    		buf[i] = 'h';
    	}
    	lobjOid = createBlob( buf, 2048);
    

    Das fangen von Fehlern kommt auf jeden Fall. Bin aber erst einmal froh, wenn ich überhaupt die c++/cli Klasse als Wrapper verwenden kann...



  • Wenn -1 zurück kommt, dann ging ja schon das lo_create/open schief... hat also noch gar nichts mit den Daten zu tun!



  • Hallo,

    ja, aus einem mir nicht verständlichen Grund geht meine testaplplikation und diese hier nicht. Auch wenn ich ohne übergabe wie in der testapplikation etwas reinschreibe. Da muß ich mal schauen, warum er das so nicht mag.

    Vielen Dank für die Hilfe!

    Habe nicht gedacht, dass alles richtig gewesen wäre.



  • Hallo,

    ich habe es nun geschafft. Vielen dank für die Hilfe!
    Es war ein Fehler vorhanden, der nichts mit c++/cli zu tun hatte. Warum man arraySystem::Byte^val verwendet, anstatt wie ich gelesen habe array<Byte>val ist mir nicht klar, aber es geht.

    Kann mir jemand vielleicht noch sagen wie ich aus einem String^ oder System::String ein char* bekomme?



  • Ein String ist in .NET Unicode.
    Unicode != char...
    Deshalb musst Du es zuerst in eine passende Codepage konvertieren.^

    Z.B. so:

    System::String ^str = "Managed String";
      array<System::Byte> ^ascii = System::Text::Encoding::ASCII->GetBytes(str);
    

    Und dann hast Du ja ein byte-Array, welches Du dann wie gehabt nach char* konvertieren kannst...



  • Hallo,

    es tut mir leid, dass ich soviele Fragen habe.

    Wie konvertiere ich am besten rückgängig char * zu System::String oder String^, so dass ich z.B. ein property habe, welche für .NET String typen anzeigt aus einem char* Wert der unmanaged klasse...?

    Bekomme dies leider nicht hin

    😞



  • kiev schrieb:

    Wie konvertiere ich am besten rückgängig char * zu System::String oder String^, so dass ich z.B. ein property habe, welche für .NET String typen anzeigt aus einem char* Wert der unmanaged klasse...?

    Zu String-Konvertiergen siehe FAQ...
    Am einfachsten

    String ^str = gcnew String(unmanagedString);
    


  • Ah,

    das geht ja ganz einfach. Da habe ich sehr falsches probiert. Ok,
    vielen Dank!


Anmelden zum Antworten