Posts Tagged Delphi

Memory mapped files in .NET 4

Similarly to my way to CountdownEvent class, I found MemoryMappedFiles namespace, which is new in .NET 4. It’s in System.IO.

If you’ve done some work in stone ages in C/C++ or maybe ObjectPascal (Delphi) you may remember using these files. I used these for exchanging data between two applications, but the usage is pretty much endless. And now you can benefit from it in .NET directly, without using P/Invoke.

To see what’s inside, I wrote two simple applications that are reading and writing some data (no synchronization ;) ).

The first one is doing writing and reading:

using (MemoryMappedFile mmf = MemoryMappedFile.CreateOrOpen("TestMemoryMappedFile", 1024 * 1024))
{
	using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor())
	{
		HelperStuff.WriteData(accessor, 0);

		Console.ReadLine();

		HelperStuff.ReadData(accessor, 0);
	}
}

and the second one is just reading:

using (MemoryMappedFile mmf = MemoryMappedFile.CreateOrOpen("TestMemoryMappedFile", 1024 * 1024))
{
	using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor())
	{
		HelperStuff.WriteData(accessor, 0);

		Console.ReadLine();

		HelperStuff.ReadData(accessor, 0);
	}
}

Nothing magical. The reading and writing methods (placed in shared library) are simply creating some dummy data. In my case struct and string, saved as array of bytes.

public static void ReadData(MemoryMappedViewAccessor accessor, int position)
{
	SomeData data1;

	accessor.Read<SomeData>(position, out data1);
	position += Marshal.SizeOf(typeof(SomeData));

	int length = accessor.ReadInt32(position);
	position += Marshal.SizeOf(typeof(int));

	byte[] data2 = new byte[length];

	accessor.ReadArray<byte>(position, data2, 0, data2.Length);

	Console.WriteLine(data1.CurrentDate);
	Console.WriteLine(Encoding.Unicode.GetString(data2));
}

public static void WriteData(MemoryMappedViewAccessor accessor, int position)
{
	SomeData data1 = new SomeData() { CurrentDate = DateTime.Today.Ticks };
	byte[] data2 = Encoding.Unicode.GetBytes(DateTime.Today.ToLongDateString());

	accessor.Write<SomeData>(position, ref data1);
	position += Marshal.SizeOf(typeof(SomeData));

	accessor.Write(position, data2.Length);
	position += Marshal.SizeOf(typeof(int));

	accessor.WriteArray<byte>(position, data2, 0, data2.Length);
}

The struct is really dummy:

public struct SomeData
{
	public long CurrentDate { get; set; }
}

The reading and writing is little bit limited, as you’re in fact dealing with just a bunch of memory, not some structured storage. But if you like working with it directly as stream (or you have some smart wrappers around streams), you can also use method CreateViewStream instead of CreateViewAccessor used in my example. These method have some overloads with option to specify also the access rights using MemoryMappedFileAccess, so you can i.e. use CopyOnWrite and any write operations will not be seen by other processes.

Tags: , , ,

Windows 7, mouse, multitouch, gravitation – flashback

While reading Mike Taulty’s posts about playing with Windows 7 and multitouch some words like deceleration, inertia etc. started some process in my head and I recalled some very old program everybody was creating. I don’t know if everybody, but at least 99,9% of Delphi developers.

The idea behind program was pretty simple. No window, somehow hook the mouse (I don’t remember whether it was classic hook, because it was in Win98/95 era). And everytime you put the mouse to the top, it started falling down, like if the gravitation worker for mouse cursor too. I remember too some modification, that if you done some horizontal move with mouse it had some inertia and decelerated. So it was fun try to click on some button or similar stuff. :) And if you put the mouse to the top of the screen with this move, it was falling down with parabola path.

Sure, the code and/or program was absolutely useless, but it was a great rest during long day at work. I wish I found the program somewhere now and look at it. :)

Tags: , , , ,

Rotační hyperboloid? Ale kdepak.

Minulý týden jsem byl v Liberci, kde jsem prováděl školení pro firmu INISOFT. Mimochodem skvělá parta lidí – a BabySmash, náhodou zmíněný, zaznamenal fenomenální úspěch. ;-)

Mimo to jsem měl možnost se podívat na horu Ještěd (1012m). Na vrcholu je stavba (televizní vysílač a hotel), jejíž tvar má být rotační hyperboloid. Z dálky možná, ale na místě … Některé plochy jsou prostě víc rovné než “oblé”. Podvod. :) Nicméně i tak doporučuji navštívít. Výhled je super a stavba opravdu pěkně následuje tvar terénu.

Tags: , , ,

if, else, return

Občas vidím ve zdrojácích funkce s konstrukcí:

if (<condition>)
{
  x = DoSomething(y);
  return x;
}
return z;

Což je víceméně to samé jako:

if (<condition>)
{
  x = DoSomething(y);
  return x;
}
else
{
  return z;
}

Osobně používám druhý zápis. Přijde mi o něco přehlednější a explicitnější. Pravděpodobně vliv Delphi/ObjectPascalu.

Je však v těchto zápisech nějaký rozdíl? Nějaký praktický aspekt, který mi uniká?

Tags: , ,

Creating Firebird database programatically (Delphi)

Today my colleague asked me the question, “How to create FB database programatically from Delphi?”. Well, the solution is very easy, just use the following code (it’s using the InterBase Express components):


IBDatabase1.DatabaseName := ChangeFileExt(Application.ExeName, ‘.fdb’);
IBDatabase1.Params.Add(‘USER ”SYSDBA”’);
IBDatabase1.Params.Add(‘PASSWORD ”masterkey”’);
IBDatabase1.Params.Add(‘PAGE_SIZE 4096′);
IBDatabase1.Params.Add(‘DEFAULT CHARACTER SET WIN1250′);
IBDatabase1.CreateDatabase;

Tags: ,

Delphi (aspol.) se Borland rozhodl "předat dál"

Ačkoli zde se hodně mluví o Visual Studiu (a příslušenství), nedá mi to abych napsal pár slov.
Asi každý dnes zaregistroval zprávu o tom, že se Borland rozhodl dále se nezaměřovat na produkty jako je Delphi a podobná IDE a předat je do rukou jiných. Sám Borland se chce změřit na ALM (Application Lifecycle Management). Nechci zde rozmýšlet nad problémem, jestli je to správně nebo ne, případně jestli tím Delphi skončí. Pravdou však je, že Borland s Delphi ukázal zajímavou cestu mezi námi vývojáři. Já sám jsem se setkal poprvé s Delphi 3. Je to takové klasické spojení: Borland+Delphi. Pokud řeknete Delphi vybaví se mi (a nejen mně) Borland a obráceně.
Zajímavé a rozhodně za povšimnutí stojí i fakt, že společně s těmito produkty se Borland “vzdává” i InterBase. Bude určitě zajímavé sledovat co se bude dít s touto databázovou platformou dál – má totiž proti sobě pokrevního soupeře, a sice Firebird, který se po oddělení velmi “rozjel” (je to mj. i můj oblíbený DB engine).

Co se stane s Delphi a vůbec celou partou, nikdo nemůže vědět. Jisté je, že tu nějakou dobu určitě bude (jde jen o to, jak dlouhou). Zamáčknu tedy slzu v oku a jdu si (ne)nostalgicky prohlédnout své D7, stejně v nich budu ještě peknou dobu dělat. :)
A InterBase? Ať je Firebirdem totálně převálcován. ;)

PS: Zajímavé bylo dnes sledovat 300% aktivitu na Borland Blogging Community. :)

EDIT: Dnes je u mě asi do 2 hodin v noci, takže proto říkam dnes i když je už 2 minuty zítra (to zní divně).

Tags:

{Read|Write}File Win32 API a peklo v Delphi

Včera jsem psal prográmek, který využíval fce ReadFile a WriteFile. Předem řikám, že jsem v Delphi moc s čistým API nedělal, Delphi ma skoro vše pěkně přístupné. Ale pro tento účel jsem musel použít čisté Win32 API. Vše šlo celkem dobře, ale zásek nastal u bufferu. Nadefinoval jsem si klasicky jako Buffer: array of Byte;. A kouknul do hintu u funkce, jak se to tam predává. Vidím var Buffer: Untyped, říkam paráda, hned si to tam šoupne odkazem a nemusím řešit ukazatel (jak ja to nesnáším). Spustím, dělá co má. Jásám. :) Ovšem než do chvíle, kdy jsem oba soubory (originál a kopii) projel diffem. Soubory se liší. Celé to začínám prohlížet nevidím na dvou příkazech, kde se data načtou do bufferu a zapíšou ven nic podezřelého. Během nesmyslného zkoušení, jsem zjistil, že program od jistých velikostí bufferu spadne, a to buď hned nebo v poslední obrátce smyčky. Po celkem – pro popis nezáživném debuggování – jsem přišel na chybu; resp. hledal jsem na internetu různé věci, které by mě mohly inspirovat a našel jsem. Jako parametr fce jsem na základě nalezené inspirace (nebo spíš několika inspirací) zadal Buffer[0]. A hle ono to fungovalo. Přiznám se, že jsem neřešil co, proč a jak. Důležité je že, to jede.
Ale budu si sakra dlouho pamatovat tenhle “fígl” v Delphi.

Tags: