[C++] char array naar .NET Byte[]?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Darkvater
  • Registratie: Januari 2001
  • Laatst online: 26-08-2024

Darkvater

oh really?

Topicstarter
Hoe krijg ik precies een blok geheugen gealloceerd in unmanaged code in managed code?

Mijn probleem is als volgt: ik laat graphviz een graph naar een memory buffer schrijven (die alloceert hij zelf) in BMP formaat (of PNG, maakt niks uit), en die wil ik dan laten zien in een windows form. Ik dacht dus het volgende te doen:

C++:
1
2
3
4
5
char* buf = NULL;
int len = 0;
gvRenderData(gv, g, &buf, &len);
IO::MemoryStream s(buf, false);
Drawing::Bitmap bmp = Drawing::Image::FromStream(%s);


zoiets dan, maar MemoryStream kan die char* array niet naar Byte[] converteren. Uiteraard, maar hoe moet ik dat dan doen? Heb al veel geprobeerd maar niks werkte. correctie: ik kan wel element voor element naar een managed array kopieren maar dat wilde ik niet, ik wilde gewoon de al bestaande buffer gebruiken. Kan ik dit doen?

[ Voor 1% gewijzigd door Darkvater op 22-09-2009 19:15 . Reden: foute functie-call in code ]


Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge


Acties:
  • 0 Henk 'm!

  • jmzeeman
  • Registratie: April 2007
  • Laatst online: 12-09 16:17
Direct van een char* naar een Byte[] kan volgens mij niet, omdat een Byte[] niet het zelfde is en extra informatie bevat. Je kan Marshal.Copy gebruiken om een IntPtr naar een managed array te copieeren de IntPtr krijg je door de char * naar een IntPtr te converteren.
Zoiets dus:
C++:
1
2
Byte[] managedBuffer = gcnew Byte[len];
Marshal.Copy(IntPtr(buf), managedBuffer, 0, len);

Ook zou je nog naar de constructor van Bitmap kunnen kijken deze kan ook een intptr als parameter mee krijgen voor de pixeldata alleen moet deze volgens mij de rouwe pixeldata hebben zonder de bijbehorende headers. Je hebt er dan dus waarschijnlijk weer extra werk aan om zelf de hoogteen breedte uit te lezen en de header te strippen. Maar het zou volgens mij de meest efficiente manier zijn.

Voor de headers zie BITMAPFILEHEADER en BITMAPINFOHEADER.

[ Voor 61% gewijzigd door jmzeeman op 22-09-2009 20:05 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Darkvater schreef op dinsdag 22 september 2009 @ 19:11:
Hoe krijg ik precies een blok geheugen gealloceerd in unmanaged code in managed code?

Mijn probleem is als volgt: ik laat graphviz een graph naar een memory buffer schrijven (die alloceert hij zelf)
Kun je daar omheen? Als je zelf een buffer aan kunt leveren, dan kun je gewoon een managed array maken en daar het adres van opvragen middels pin_ptr, zodat je dat adres weer aan graphviz kunt voeren. Die schrijft z'n data dan in feite direct naar de managed array.

Andersom gaat helaas niet vziw.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
Mijn vraag is eerder als je toch C++ aan het gebruiken bent waarom wil je dan naar managed code gaan. BMP, JPG en PNG readers er zijn genoeg C++ libs te vinden die dit voor je doen.

ex-FE Programmer: CMR:DiRT2,DiRT 3, DiRT Showdown, GRID 2, Mad Max


  • pedorus
  • Registratie: Januari 2008
  • Niet online
Het lijkt me ook lastig zonder Copy, maar de vraag is natuurlijk of het echt niet kan, ondanks dat MS ons doet geloven dat Copy het beste is. :) Misschien kan het wel via SizeParamIndex. Dus iets als:
C++:
1
2
void Method( [MarshalAs(UnmanagedType::LPArray, SizeParamIndex=1)] Byte[] data, 
             int size )

En dan daar kijken of je data goed hebt ontvangen (en of er niet gekopieerd is).

In principe zou een Byte-array Blittable moeten zijn. Van Managed->Unmanaged gaat dat prima, maar andersom ontbreekt dus een handige methode in Marshal vziw.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • Darkvater
  • Registratie: Januari 2001
  • Laatst online: 26-08-2024

Darkvater

oh really?

Topicstarter
.oisyn schreef op dinsdag 22 september 2009 @ 23:44:
Kun je daar omheen? Als je zelf een buffer aan kunt leveren, dan kun je gewoon een managed array maken en daar het adres van opvragen middels pin_ptr, zodat je dat adres weer aan graphviz kunt voeren. Die schrijft z'n data dan in feite direct naar de managed array.
Ik gebruik de graphviz library om van een graphviz file een output te krijgen. gvRenderData() is de enige manier om naar memory to renderen en het geheugen wordt binnenin die functie zelf gealloceerd - je hebt vantevoren geen idee natuurlijk hoe groot je plaatje wordt, dat hangt af van de layout, shapes, labels, attributen, etc.
NC83 schreef op woensdag 23 september 2009 @ 00:27:
Mijn vraag is eerder als je toch C++ aan het gebruiken bent waarom wil je dan naar managed code gaan. BMP, JPG en PNG readers er zijn genoeg C++ libs te vinden die dit voor je doen.
Tuurlijk, ik zou het plaatje naar een bestand kunnen renderen en dan inlezen, maar dat hele memory > disk > memory wilde ik juist weglaten, en zowiezo heb je soms geen rechten om bestanden aan te maken. Het hele GUI gebeuren is al managed C++, dus daar moet het heen :)

Dank je jmzeeman, ik zal kijken of het werkt, inderdaad kan je raw data sturen naar de Bitmap allocator. Dat ik dat niet gezien heb |:(

[ Voor 5% gewijzigd door Darkvater op 23-09-2009 10:08 ]


Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge


  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
Je kunt ook in memory images creeren met de meeste van deze libs hoor en dan wordt het converteren naar een byte array veel makkelijker. En deze libs halen de headers voor je weg en kunnen je een directe pointer naar de pixel data geven als het moet.

ex-FE Programmer: CMR:DiRT2,DiRT 3, DiRT Showdown, GRID 2, Mad Max


  • Darkvater
  • Registratie: Januari 2001
  • Laatst online: 26-08-2024

Darkvater

oh really?

Topicstarter
Nou, dit wordt helemaal niks... gvRenderData() heeft ergens in de graphviz library een out-of-bounds access waardoor een free van de gealloceerde buffer een heap error geeft.

Dus toch maar naar file wegschrijven - dat werkt wel - en dan de bitmap constructor van een bestand aanroepen. Alle moeite voor niks :s

NC83: ik *moet* graphviz gebruiken. Nou, niet moet, maar die library bouwt de hele grafische representatie op van mijn boom wat hij heel goed doet. Dus ik zit er een beetje aan vast :)

[ Voor 23% gewijzigd door Darkvater op 23-09-2009 22:54 ]


Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge


  • pedorus
  • Registratie: Januari 2008
  • Niet online
Darkvater schreef op woensdag 23 september 2009 @ 22:52:
Dus toch maar naar file wegschrijven - dat werkt wel - en dan de bitmap constructor van een bestand aanroepen. Alle moeite voor niks :s
Marshal.Copy() zou in ieder geval toch moeten werken :?

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • Darkvater
  • Registratie: Januari 2001
  • Laatst online: 26-08-2024

Darkvater

oh really?

Topicstarter
pedorus schreef op woensdag 23 september 2009 @ 22:56:
[Marshal.Copy() zou in ieder geval toch moeten werken :?
Ja, Marshal.Copy() werkt perfect, echter ik moet wel de unmanaged buffer vrijgeven. En als ik dat doe, krijg ik dus een error (ook in een heel simpel C programma, dus het ligt niet aan .NET en alles eromheen). En als ik het niet vrijgeef, krijg ik allemaal memoryleaks wat uiteraard niet wenselijk is.


Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

:? Je kunt toch de Copy doen, en direct daarna de buffer vrijgeven?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1