Zdravím, mám funkci (z class library napsané v c++/cli) která vrátí pointr void* na data a počet bytů. Potřebovat bych v C# aplikaci z toho vytvořit přes MemoryStream objekt Bitmap. Problém je že se mi nedaří převést ten point void* do pole byte[], které potřebuju pro vytvoření toho Streamu. Nemáte někdo fungující kód pokud možno s co nejmenším počtem kopírování paměti?
Fórum › .NET
Void* na byte[] v C#
#1 Radek Chalupa
v C/C++ se to dela zmenou typu pointeru: (byte *)ptr; ci reinterpret_cast<byte*>(ptr); (byte* je ekvivalent pro byte[]).
Neco zminuji na StackOverflow ale tezko rici, jestli z toho neco vydolujes, protoze se to autor snazil delat genericky ci co: http://stackoverflow.com/questions/2570082/converting-c-sharp-void-to-byte
Připomíná mi to používání FTD2xx.dll v C#. Celá dll je v C a funkce vyžadovaly void* a počet bytů. Zkus se podívat na http://www.ftdichip.com/Support/SoftwareExamples/CodeExamples/CSharp.htm , možná je to natolik podobný, že by ses mohl inspirtovat.
hu
Marshal.Copy.
A buď to zkopírovat celé do velkého pole a z něj udělat MemoryStream, nebo napsat vlastní Stream a kopírovat požadované části v Read.
Nevím, jestli má ten marshalling nějaký významný overhead, při větším počtu Readů by možná ten mezibuffer byl efektivnější, ale spíš bych to viděl na stejno.
#1 Radek Chalupa
kdybych to dělal já, tak bych v nastavení projektu povolil allow unsafe code a v unsafe bloku přetypoval void* na byte* a buďto s tím pracoval a nebo, to překopíroval do spravovaného byte[].
Podle toho, co jsem se zatím naučil tak vím, že se nespravovaná pole nedají bez překopírování přetypovat do spravovaných, protože pracují a jsou v paměti uložena jinak.
Díky všem za inspirace, asi to bez toho kopírování navíc nepůjde, použij jsem Marshal.Copy a konečně to zdá se funguje. Kdyby to někoho zajímalo, tak fungující kód je tady:
unsafe
{
long delka = cmd.velikost_dat_blob(0);
void* pv = cmd.obsah_blob(0);
byte[] byty = new byte[delka];
Marshal.Copy((IntPtr)pv, (byte[])byty, (int)0, (int)delka);
MemoryStream ms = new MemoryStream((int)delka);
ms.Write(byty, 0, (int)delka);
bitmapa_.nacist_stream(ms);
ms.Dispose();
}
#7 Radek Chalupa
já bych to udělal takto:
try
{
int delka = (int)cmd.velikost_dat_blob(0);
byte* data = (byte*)cmd.obsah_blob(0);
using (MemoryStream ms = new MemoryStream(delka))
{
for (int i = 0; i < delka; i++) ms.WriteByte(data[i]);
bitmapa_.nacist_stream(ms);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
#10 Radek Chalupa
to je pravda, je to pomalé. Takže to zrychlíme:
try
{
int delka = (int)cmd.velikost_dat_blob(0);
byte[] byty = new byte[delka];
Marshal.Copy((IntPtr)cmd.obsah_blob(0), byty, 0, delka);
using (MemoryStream ms = new MemoryStream(byty))
{
bitmapa_.nacist_stream(ms);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
Procházení struktury byte o byte? — založil Martin
Unsigned byte — založil dan
Typedef void* ve VB.NET — založil Štefan Kakaš
Moderátoři diskuze