Void* na byte[] v C# – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Void* na byte[] v C# – .NET – Fórum – Programujte.comVoid* na byte[] v C# – .NET – Fórum – Programujte.com

 

Radek Chalupa
~ Redaktor
+1
Super člen
12. 9. 2016   #1
-
0
-

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? 

Nahlásit jako SPAM
IP: 89.177.51.–
KIIV
~ Moderátor
+43
God of flame
12. 9. 2016   #2
-
0
-
Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Radek Chalupa
~ Redaktor
+1
Super člen
12. 9. 2016   #3
-
0
-

#2 KIIV
v C++ by to nebyl problém, ale já to bohužel potřebuju v C# aplikaci...

Nahlásit jako SPAM
IP: 89.177.51.–
12. 9. 2016   #4
-
0
-
Nahlásit jako SPAM
IP: 195.178.67.–
q
~ Anonymní uživatel
219 příspěvků
12. 9. 2016   #5
-
0
-

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.

Nahlásit jako SPAM
IP: 213.211.51.–
BDS+3
Věrný člen
12. 9. 2016   #6
-
0
-

#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.

Nahlásit jako SPAM
IP: 185.69.69.–
W11 :)
Radek Chalupa
~ Redaktor
+1
Super člen
13. 9. 2016   #7
-
0
-

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();
}
Nahlásit jako SPAM
IP: 89.177.51.–
q
~ Anonymní uživatel
219 příspěvků
13. 9. 2016   #8
-
0
-

Vytvoř ten MemoryStream přímo nad tím polem, bez kopírování přes Write...

Nahlásit jako SPAM
IP: 213.211.51.–
BDS+3
Věrný člen
13. 9. 2016   #9
-
0
-

#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);
 }
Nahlásit jako SPAM
IP: 94.113.253.–
W11 :)
Radek Chalupa
~ Redaktor
+1
Super člen
13. 9. 2016   #10
-
0
-

#9 BDS
Je to jistě čistě zabalené z hlediska syntaxe, ale obávám se že to zapisování do streamu po 1 byte bude dost pomalé, když jde konkrétně o fotky a velikost může být nějaký ten MB..

Nahlásit jako SPAM
IP: 89.177.51.–
BDS+3
Věrný člen
13. 9. 2016   #11
-
0
-

#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);
 }
Nahlásit jako SPAM
IP: 185.69.69.–
W11 :)
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 48 hostů

Podobná vlákna

Void* — založil expoox

(void) — založil liborb

Unsigned byte — založil dan

Typedef void* ve VB.NET — založil Štefan Kakaš

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý