byte[] in char[]
-
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 einfachstenString ^str = gcnew String(unmanagedString);
-
Ah,
das geht ja ganz einfach. Da habe ich sehr falsches probiert. Ok,
vielen Dank!