vrijdag 11 december 2009

"External exception C0000006" bij app op WLAN

Als je een applicatie maakt dat moet draaien via een WLAN (Wifi), pas dan even op en lees het onderstaande door:

Windows laadt namelijk niet de gehele executable in het geheugen, maar alleen wat hij op dat moment nodig heeft. Als je bijv. op een knop in je applicatie drukt, dan *kan* Windows een nieuw blok bitjes van je applicatie via het netwerk moeten ophalen (of voor een resource (bijv. een icon) bij een nieuw scherm dat je aanmaakt, etc).
Echter, als je via een WLAN werkt, dan kan natuurlijk net je verbinding weg zijn...
Wat er dan gebeurt? Een "External exception C0000006" :-(
Oplossing? Je moet een flag in je exe zetten, die aangeeft dat je vanaf een removeable medium werkt (USB, Wifi, etc) zodat Windows wel alles inlaadt. In Delphi kun je dit in de .dpr doen:
{$SetPEFlags IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP}

Dit heeft bij mijn huidige klant nogal voor wat hoofdbrekens gezorgd: we kregen deze exceptions op de meest vreemde plaatsen, zonder aanwijsbare bug in de code. Na wat googlen was de oorzaak gauw gevonden en de fix snel gemaakt :-) Zie originele discussie + oplossing:

woensdag 9 december 2009

Windows tijd: in stapjes van 15ms!

Soms wordt je onaangenaam verrast: je meet de tijd van alle SQL queries in je programma met "MillisecondsBetween" en je krijgt als resultaat: 0, 0, 0, en 15ms...

Hmmm, dit is te mooi om waar te zijn, zo snel is MS SQL Server nou ook weer niet! :-)
Er ging bij mij toen wel een lampje branden, ik eens eerder zoiets gezien met "Sleep" en "GetTickCount".

Thread time slices
In Windows (en andere systemen) worden threads 1 voor 1 op een CPU uitgevoerd. Elke thread heeft een "time slice" van 15ms, waarin hij de volledige CPU tot zijn beschikking heeft. Na 15ms breekt Windows de thread af, slaat de inhoud van de CPU registers e.d. op, en laad en start een andere thread ("context switch"). Een "time slice" kun je afbreken door een wait function aan te roepen, zoals "Sleep", "WaitForSingleObject", etc. Op deze manier kan een andere thread de kostbare CPU tijd gebruiken.


Consequenties
De default time slice van 15ms heeft nogal wat consequenties voor het programmeren: zo gaat een "Sleep(1)" niet 1ms wachten, maar 10 - 15ms! (afhankelijk van andere threads etc). Maar ook andere tijd functies zoals "GetTickCount", "Now" (Delphi) of "GetLocalTime" (Windows) werken in stapjes van 15ms!

Nauwkeurige tijdmeting
Gelukkig zijn er andere manieren om het aantal ms te bepalen:
  • hardware timer gebruiken: met QueryPerformanceFrequency + QueryPerformanceCounter kun je met micro en nano secondes werken!
  • kortere "time slice" instellen met "timeBeginPeriod", bijv een time slice van 1ms met "timeBeginPeriod(1)". Dit heeft echter wel nadelen: veel meer context switches, dus meer overhead!
Zelf heb ik andere "Now" functie in Delphi geschreven, die op basis van QueryPerformanceCounter etc werkt (dan werkt alles in 1x op de ms nauwkeurig, of zelfs op de micro seconde).
Ik vervang ("detour") de oude "Now" functie door mijn "NowExact" door middel van "KOLDetours.pas":
OldNow := KOLDetours.InterceptCreate(@Now, @NowExact);
Anekdote
Ik heb eens bij een bedrijf de RS232 communicatie met een PLC flink versneld: in een loopje werd na elke ontvangen character een "Sleep(1)" aangeroepen. Dit heb ik met een factor 10 versneld door pas na een lege character een "Sleep(1)" te doen, en die door middel van "timeBeginPeriod(1)" ook echt 1ms wacht ipv 10 to 15ms!

vrijdag 23 oktober 2009

Gratis internetbellen!

Tegenwoordig begint internetbellen steeds meer in te komen: goedkoop bellen via internet. Dit in navolging van het succes van Skype op de PC: hiermee kun je gratis onderling bellen, en met soort prepaid kun je ook bellen naar vaste toestellen. Internetbellen is een soort Skype, maar dan met de gewone telefooon en zonder dat je een PC met headset nodig hebt :-). De meeste (alle?) providers hebben tegenwoordig wel een "Internet + bellen" abonnement, ook wel bekend als "SIP" en "Voip" (Voice over IP). Voor een vast bedrag per maand kun je dan gratis naar andere Voip gebruikers bellen (net als Skype) en met een goedkoper tarief naar gewone vast telefoon.

Problemen met Voip

Het is echter niet geheel zonder problemen! Van verschillende mensen hoor ik allerlei verhalen over: slechte bereikbaarheid, irritante echo, niet naar buiten kunnen bellen, bel die niet over gaat, etc. Zowieso ben je volledig afhankelijk van het internet: storing van ADSL of provider? Dan kun je niet bellen... (gelukkig gebeurt dit niet zo vaak, maar wel af en toe).
Daarnaast zit je vast aan een vrij duur abbo (minimaal 30 euro per maand) en moet je nog steeds per tik betalen.

Ik wil het ook...

Toen ik echter laatst de rekening van KPN (vaste telefoon) kreeg, ging ik toch wel even nadenken: dit is toch wel vrij duur voor dat beetje bellen van ons. Nu zou ik ook wel internetbellen willen, maar dan zonder de bovengenoemde problemen. In ieder geval wil ik mijn vaste lijn nog gewoon houden en niet afhankelijk zijn van een bepaalde provider.

Oplossing

Na wat zoeken kwam ik tot een hele mooie oplossing: een kastje van Linksys (SPA 3102, 60 euro) + een online Voip account (bijv. VoipBuster.com) (30 euro per jaar) = gratis bellen! Nou ja, helemaal gratis is 30 euro per jaar natuurlijk niet, maar het is een stuk goedkoper dan normale providers en je betaalt niet meer per tik (dus "gratis" :-) ).
Je sluit het kastje (bijv. Linksys SPA 3102) aan op het internet (bijv ADSL router) EN (!) op je vaste KPN telefoonlijn. Je normale telefoon sluit je uiteraard weer op het kastje aan. Je kunt nu gewoon gebeld worden via de vaste lijn, en als de stroom uitvalt, wordt automatisch overgeschakeld op de vaste lijn (je kunt dus ten alle tijde bellen en gebeld worden via de vaste lijn!). Vervolgens kun je via de webinterface van het kastje de accountgegevens van bijvoorbeeld VoipBuster.com invullen. Vanaf dat moment kun je met je normale telefoon via internet bellen! Daarnaast kun je nog dmv een "dialplan" instellen dat als je bijv. een # voor de telefoonnummer draait, hij via vaste telefoonlijn belt. De Linksys SPA 3102 heeft trouwens onnoemlijk veel instellingen! Je kunt bijvoorbeeld de voltage van de telefoonlijn, de frequentie van de kiestoon instellen etc etc etc. Gelukkig staat default de meeste instellingen gewoon goed :-). Voor een goede uitleg: zie deze handleiding.

Kortom: op deze manier kun je zelf je "internetbellen" c.q. "Voip" regelen, waarbij je onafhankelijk bent van een (duur) abbo bij een provider, en altijd kunt bellen en gebeld worden via de oude vertrouwde KPN telefoonlijn.

Opmerkingen

Zelf gebruik ik VoipDiscount.com (zelfde als VoipBuster maar dan andere tarieven...). Voor 10 euro prepaid kun je 120 dagen gratis bellen (Fair use policy: 300 minuten (5uur) per week). Dus met 3 * 10 euro kun je een heel jaar "gratis" bellen. Alleen naar vast (inclusief sommige buitenlanden) is gratis, naar mobiel is niet gratis (en daar verdienen ze weer op). Er zijn verschillende "betamax" klonen en andere providers: vergelijk eerst de tarieven en voorwaarden (bijv goedkoper bellen naar mobiel maar dan maar 90 ipv 120 "free days").
Van de 10 euro beltegoed heb ik voor 1 euro (!) een nederlands nummer aangevraagd (ander netnummer etc maar goed voor 1 euro mag je niet klagen). Dit is een normaal nummer waarop andere mensen mij ook kunnen bellen: hebben ze ook Voip dan bellen ze gratis (net als bij Skype). Oftewel: men kan mij bellen via 2 nummers: via voip en via kpn :-).
Je kunt ook helemaal overstappen op voip: bij oa Budgetphone.nl kun je je huidige KPN nummer laten overnemen voor 10 euro per jaar (per maand nog wel 10 euro linesharing aan KPN betalen ivm ADSL?).

maandag 7 september 2009

Delphi 2010, Coderage + SDN

Delphi 2010 released!

Vlak na de preview van Delphi 2010 (zie mijn vorige post), verscheen al de RTM versie en is het officieel released. Ondertussen zijn er verschillende interessante blogs verschenen, waarbij verschillende verbeteringen verder uitgelegd worden. Ik zal niet alle verbeteringen bespreken, maar een paar uitlichten. (P.S: zie ook de complete "reviewers" guide!)

Uitgebreide online wiki help (!)
Na de Delphi Prism Wiki is de hele RAD Studio via een mooie online wiki te doorzoeken. Bijvoorbeeld voor het complete overzicht van alle verbeteringen in de 2010 versie:

Voor een handig beginpunt:

Maar ook de complete Delphi Language Guide is beschikbaar, evenals bijvoorbeeld de VCL, etc.

Class constructors
Een mooie uitbreiding (wat nog niet zo nadrukkelijk genoemd is), is de ondersteuning van Class Constructors (net als .Net)

Een voorbeeld hoe je het kunt gebruiken:

RTTI (a la .Net reflection)
Verder is de RTTI sterk verbeterd, meer object georiënteerd zoals .Net Reflection werkt, zonder allerlei pointers, records, etc.

Class attributes
Zoals je ziet, zijn in D2010 verschillende .Net technieken verwerkt. Nu heeft Delphi ook ondersteuning voor class attributes:

TStopwatch
Nog een kleine maar handige uitbreiding is de TStopwacht, voor het meten van tijden (hoe lang een stuk code duurt etc):

Andere handigheidjes:

Datasnap (multitier):

IDE & Source Code:

DBX: Firebird + alle sourcecode (!)
Wat ik zelf erg mooi vind, is de native ondersteuning van de open source database Firebird (compatible (?) met Interbase). Maar ook dat de broncode van alle drivers meegeleverd wordt! Niet alleen van DBX, maar ook (eindelijk!) van Midas.dll (oa bekend van TClientdataset).

Extra's
De eerste extra functies en fixes van "andy" zijn al verschenen voor D2010:

TPL (Task Parallel Library) voor Delphi (!)

Laatst is er een interessante dotNed meeting geweest bij DTS/4DotNet over TPL voor .Net. Gelukkig bestaat voor Delphi zoiets dergelijks al een poosje:

CodeRage 4 & SDN Conference

dinsdag 18 augustus 2009

Delphi 2010 Preview!

Op de site van Codegear/Embarcadero is vorige week de Delphi 2010 Preview Center verschenen: Nog 7 dagen, 2 uur, 31 minuten (and counting…) en dan is het zover.
Delphi 2010 belooft de beste Delphi release ooit te worden, met veelbelovende nieuwe features en verbeteringen! Zoals (Multi)Touch, Mouse Gestures, IDE Insight (alles (!) vinden in 1 scherm), background compilation, verbeterde debugger (oa threads), verbeterde RTTI (.Net Reflection!), class attributes, Direct2d canvas (Win7), etc etc.

Bekijk onder andere deze video eens:

Vervolgens zijn er op de Codegear blog een groot aantal artikelen hierover verschenen:

Niet minder interessant zijn de blog artikelen van de “Wings of wind” blog!:

Een ander blog had een leuk artikel over een andere (kleine) verbetering mbt API wrappers:

1 ding is zeker: ze zijn bij Codegear/Embarcadero druk bezig met Delphi! De toekomst zag met al het .Net geweld er somber uit, maar de zon schijnt achter de wolken. Wat betreft “native code” versus “managed/.Net code” vond ik de volgende gedeelte van de blog van Pawel Glowacki wel mooi:

Tim Anderson in his post “Native code makes a comeback – except it never away” has some good points on this subject as well. The very good example why native code continues to be important is new Windows 7 Direct2D graphics. I like the quote from MSDN Magazine June 2009 issue “Introducing Direct2D” where author sums it up:

(…) if you want to develop high-performance and high-quality commercial applications, you’ll still look to C++ and native code to deliver that power. (…)

That is why Delphi and C++Builder developers are not looking to move away from native to managed code.

maandag 25 mei 2009

Random Things #6

Er is de laatste tijd weer genoeg nieuws te melden. Deze keer over nieuwe zoekmachines, PopupMode, gratis Blaise Pascal Magazine editie, MonoDevelop op Mac & Windows, Delphi Prism May 2009 met AOP(!) en VS2010 met .Net 4.0 met PFX.

Zoekmethoden:

RemObjects SDK:

  • In de volgende release wordt het Remoting Framework uitgebreide met ZeroConf+ voor service discovery.
  • En met Olympia kan eenvoudig "scalable server farms" gemaakt worden met "load balancing" en "fail over".

Delphi:

Visual Studio:

Delphi Prism:

Mono:

Axum in Visual Studio:

  • Axum is een .Net taal. waarmee veilige parallelle software gemakkelijk gemaakt kan worden.
  • Een korte uitleg is hier beschikbaar, en de demo film is ook interessant.

The Future of Delphi!

Laatst sprak ik klant, en die vroeg mij over de toekomst van Delphi. Ik kon toen daar geen goed antwoord op geven. De huidige Delphi 2007 en 2009 zijn mooie en goede versies, maar daarna?
Deze week was de Delphi Live! 2009 conferentie, waarin veel nieuwe en interessante sessies waren, en waar open en vrij over gesproken werd. 1 ding is duidelijk als je kijkt naar roadmap: Embarcadero investeert flink in Delphi! Daarnaast is het team uitgebreid, en ondanks de crisis: “the business is healty”. Kortom: de toekomst ziet er zonnig uit :-).

Na de “serieuze” disclaimer :-) werden de sessies gehouden. Hieronder een overzicht van de vele onderdelen:

  • Project Weaver
    • Main Themes
      • User Experience
      • Enhance Connectivity
      • Documentation
    • IDE usability
    • Team Productivity
    • Touch (demo film) en MultiTouch (demo film) (!)
    • IDE – Insight (easy Keyboard access to almost everything) (demo film)
    • Improvements to DataSnap
    • Firebird Support
    • .NET AOP
    • SCM Support (oa Subversion)
    • Enhanced RTTI Support (á la .Net reflection!)
    • Attribute Support (!, Win32 AOP?)
    • Seamless .NET <> Native communication
    • Windows 7 APIs and Direct2D Canvas (demo film) (demo aan film einde)
    • Mouse gestures (demo film)
    • Full Support of SOAP 1.2 Clients
  • Project X(!)
    • Cross-platform Windows, Mac OS, and Linux (demo aan film einde)
    • Cross-platform component library
    • DataSnap on all platforms
  • Project Chromium, Quality, Quality
    • Quality, Quality, Quality
    • Pascal Code Formatter (demo film)
    • Documentation of the OTA
    • New Data binding model allowing binding to almost any property on a control (á la .Net DataBinding?)
    • More integration with the database tools.
  • Project Commodore
    • 64 Bit native (!)
    • Full compiler, RTL and VCL support for 64 native
    • Multi-Core. Multi-threaded applications.

Tot slot nog een samenvatting en bespreking van dag 2 en dag 3 (!) door Marco Cantu, een overzicht van Pawel Glowacki en de Delphi Live! 2009 Recap and Product Address.

Edit: er zijn nog meer video’s beschikbaar gekomen:

dinsdag 5 mei 2009

Random Things #5

Weer een overzicht van allerlei nieuws en interessante informatie.

Je kunt op verschillende manieren Win32 en .Net naast elkaar gebruiken. Voor als je bijvoorbeeld veel Win32 code hebt, die je niet 123 helemaal kunt/wilt porten naar .Net. Ander .Net nieuws:
Natuurlijk ook normaal Delphi nieuws en tips:
Verder nog leuk om te vermelden:

maandag 20 april 2009

Random things #4

Een aantal zaken mbt Delphi (Win32 + Prism):

  • RemObjects heeft hun open source repository uitgebreid metDelpi Prism Templates en Delphi Prism Aspects .
    Op moment van schrijven zitten er alleen een Monoobj Template en een ASP.Net MVC Template en een CheckDisposedAttribute Aspect .
    De bedoeling is dat dit natuurlijk uitgebreid wordt, en iedereen wordt aangemoedigd om mee te helpen!
  • Ik had in mijn vorige blog al even Plastic SCM genoemd. Er is een interessant blog van de makers verschenen over het blame commando: hiermee kun je opvragen welke regel door wie of in welke branch aangepast is!
  • Verder kun je Plastic SCM koppelen dmv triggers met bijvoorbeeld CruiseControl, voor Contineous Integration .
  • Momenteel ben ik aan het oriënteren voor een nieuwe data object structuur bij mijn huidige opdrachtgever. Dit omdat in de toekomst waarschijnlijk meer met .Net gedaan gaat worden (Delphi 2007 + Delphi Prism?). Dan vervalt sowieso de huidige (en oude) structuur. Dus als iemand ideeën of tips heeft, graag! (het liefst voor zowel Delphi als .Net te gebruiken ipv 2 verschillende).
  • Een interessante kandidaat is Hitsoft SQL Object Library (HitSQLe): een soort LINQ voor Delphi Win32! Uiteraard niet 100% compatible maar toch heel uitbreid en krachtig. Zo hoef je oa niet druk te maken over Oracle of SQL Server commando's, en het heeft een ingebouwde connection pool. O ja, en het is nog open source ook!
  • Een ander alternatief is Data Abstract van RemObjects . Hiermee kan namelijk eenvoudig multi-tier systemen mee gebouwd worden. Ik heb al eens een Proof Of Concept gemaakt voor multi-tier, boven op het RemObjects Remoting Framework (wat wat we al voor messaging en onderlinge service communicatie gebruiken). Maar Data Abstact werkt ook boven op dezelfde SDK, en het is idem database onafhankelijk (het gebruikt oa Schema Modeler ). Ook interessant dus :-).
  • Momenteel ben ik bezig met het opfrissen van de GUI. Oa met de nieuwe versie van de VCL Components van TMS (ze hebben ook .Net componenten). Hiermee kan bijvoorbeeld eenvoudig een "Office 2007 Blue" look verkregen worden, maar je kunt ook zelf de kleuren schema's aanpassen. Zo moet straks een groene Greenax look verkregen worden ivm de integratie hiermee.
  • Verder heeft TMS mooie "Smooth" componenten! Deze maakt gebruik van de videokaart voor de 3D effecten.
  • Naast de TMS componenten, wordt nu ook gebruik gemaakt van de mooi iconen van GlyphLab. Dit is een hele uitgebreide set, inclusief originele gelayerde PhotoShop bestanden, zodat je zelf eenvoudig aanpassingen en combinaties kunt maken! En $200 is dan niet duur! Een verademing in vergelijking met de ouderwetse Delphi 3 iconen... Het leuke van het aanpassen van GUI is dat in principe de werking gelijk blijft, maar het toont gelijk een heel stuk beter!
  • Nog meer wat betreft de GUI? Ja, want GUI testen is nogal lastig. Hopelijk gaat OpenCTF mij hierbij helpen. Dit is een uitbreiding op DUnit, waarmee ik al bezig geweest ben voor een POC voor integratie testen.

Nog wat leuke informatie mbt .Net algemeen:

  • Het Mono project heeft een aantal uitbreidingen gemaakt voor .Net. 1 ervan is Mono.Simd. Hiermee kan eenvoudig en snel met vectoren gewerkt worden, die door de Mono compiler omgezet wordt in SSE /SIMD instructies voor de CPU. Dit is stukken sneller dan normale CPU instructies. Mono.Simd is compatible met het Microsoft .Net framework, alleen maakt deze compiler er normale CPU instructies van, dus vele malen trager (maar het is wel compatible). Het is vooral bedoel voor games, omdat deze veel gebruik maken van vectoren.
  • Een specifiekere uitbreiding is ondersteuning voor Microthreads (of Continuations). Vooral bedoeld voor games, maar kan ook goed gebruikt worden voor afhandeling van veel (kleine) netwerk connecties. Microthreads draaien in 1 thread, waarbij bijvoorbeeld de status van een functie opgeslagen kan worden (CPU registers, stack, etc), zodat deze later weer "resumed" kan worden. Het gaat te ver om het helemaal uit te leggen, lees het blog zelf maar :-). Maar een voorbeeld is wel handig:

prince.WaitForObjectVisible (princess);
prince.WalkTo (princess);
prince.Kiss (princess);

Random things #3

Het heeft een poosje geduurd, maar bij deze weer een aantal interessante links:
Alweer wat ouder maar nog steeds interessant:

vrijdag 13 februari 2009

RemObjects SDK voor Delphi

RemObjects SDK is een Remoting Framework, waar onder andere eenvoudig WebServices mee gemaakt kunnen worden. Het is van het gelijknamige RemObjects.com . De laatste tijd is het vooral bekend geworden door Delphi Prism , omdat zij de Oxygene compiler geschreven hebben. RemObjects maakt nog meer mooie software: Hydra (.Net assemblies in Win32 gebruiken), Data Abstract , Pascal Script, etc. Niet alleen Delphi maar ook .Net (Visual Studio) wordt ondersteunt.
Ik heb geluk gehad dat ik bij mijn huidige detacheringsopdracht met deze mooie software in aanraking mocht komen :-).

De RO SDK is een beetje te vergelijken met WCF van .Net en DataSnap van Delphi. Maar het vooral veelzijdiger dan deze 2! Het is in principe taal onafhankelijk (C++, C#, php, Delphi maar ook FPC), meerdere platformen (Windows, Linux en MacOs!), ondersteunt verschillende formaten (binair, SOAP, JSON, XML, etc) en allerlei transporten (TCP, UDP, HTTP, mail, IPC, Messages, dll(!) etc). Daarnaast ondersteunt het verschillende vormen van encryptie en compressie. Juist deze brede ondersteuning biedt heel veel mogelijkheden, waarbij WebServices maar een van de vele is.

Ontwikkelen met de RO SDK is eenvoudig, globaal te verdelen in 4 stappen:

  1. Interface definieren in een aparte grafische tool
  2. Code wordt automatisch gegenereerd door de SDK
  3. Implementatie maken aan de server kant
  4. De interface aanroepen aan de client kant

Doordat de software mooi integreert met oa Delphi wordt je stap voor stap geholpen door middel van een wizard. Zo kan automatisch een server en client project aangemaakt worden, zodat je snel er mee kunt werken. Ook worden vele demos (inclusief handleiding en uitleg!) meegeleverd, zodat wat geavanceerde technieken eenvoudig geleerd kunnen worden. Ook de gegenereerde code is netjes gedocumenteerd. Alles is gewoon heel netjes afgewerkt!

Demonstratie

Om het een en ander toe te lichten, zal ik de stappen tonen waarmee je een nieuwe RO applicatie maakt.
Als eerste maken een nieuw project via File -> New -> Other:

Vervolgens kiezen we voor een VCL Standalone server (dit is het makkelijkst te testen):

Na het drukken op OK verschijnt een mooie wizard van RO:

Via de "Advanced Project Options" knop kunnen wat meer instellingen aangepast worden:

Na het drukken op OK hebben we een nieuwe Project Group met een server en client project.

Cliënt

De client bestaat uit een channel (in dit geval een TCP client), een message (binair formaat) en een remote service waarmee we de functies aan de server kant mee kunnen aanroepen:

Server

De server bestaat uit een TCP server en message component (binair formaat):

Standaard staat alles al goed ingesteld, tijd om de "service interface" te bekijken.

Service Interface

Om de interface te bekijken of aan te passen, klikken we op "Edit Service Library" in het "RemObjects SDK" menu:

Vervolgens verschijnt de Service Builder, met default de volgende interface:

Zoals je ziet in de bovenstaande screenshot, kun je hier je eigen structures, enumerations en arrays maken. Deze types kunnen als parameter of result van een functie gebruikt worden. Ook kunnen custom exceptions gedefinieerd worden en asynchrone events gemaakt worden. Het mooie van deze types en definities is dat deze ook als fixed types in code gebruikt kunnen worden!

Server Code

Zodra het project gecompileerd wordt (of via het RO menu) wordt vanuit de Service Definitie de code gegenereerd. Voor elke "service" wordt een RO Datamodule aangemaakt:

Verder wordt een "invoker" unit, "interface" unit (met alle types) en een "implementation" unit gemaakt. De eerste 2 units worden elke keer automatisch ververst en hoeven niet aangepast te worden. Alleen de implementatie moet uiteraard zelf gemaakt worden, zoals in dit geval voor de "Sum" en "GetServerTime" functies:

Client Code

Het enige wat we nu nog moeten doen is een paar knoppen toevoegen aan de client, zodat we server functies kunnen aanroepen:

procedure TClientForm.btnServerTimeClick(Sender: TObject);
var dtServer: TDateTime;
begin
dtServer := (RORemoteService as INewService).GetServerTime;
lblServerTime.Caption := DateTimeToStr( dtServer );
end;

procedure TClientForm.btnSumClick(Sender: TObject);
var iSum: integer;
begin
iSum := (RORemoteService as INewService).Sum( edtA.Value, edtB.Value );
edtSum.Text := IntToStr( iSum );
end;

Als laatste builden we de beide projecten.

Uitvoeren

Om onze code te testen, starten we als eerste via het RO menu de server:

Het eenvoudige scherm van de server verschijnt, waarna we de client kunnen starten (zie onder voor server en client):

Zoals je ziet werkt de code uitstekend :-). En dat met maar 6 regels code!

maandag 9 februari 2009

Dephi Prism: Aspect Oriented Programming

Vorige week heeft CodeGear de Delphi Prism Roadmap vrijgegeven. 1 onderdeel wat me opviel was de support voor "Aspect Oriented Programming" (AOP). Ik heb deze term opgezocht bij Wikipedia (AOP [nl] en AOP [en] ) en simpel gezegd komt het erop neer dat het een uitbreiding is van "Object Oriented Programming", waarbij de nadruk ligt in het verdelen van functionaliteit in "aspecten". Leuk, maar hoe werkt dit in de praktijk?

Gelukkig verscheen eind vorige week een interesante blog op de blogsite van RemObjects (makers van de Oxygene compiler in Delphi Prism): Delphi Prism AOP - Cirrus

Cirrus is de code naam voor de AOP implementatie. Het is een onderdeel van de compiler: tijdens het compileren worden de "aspecten" aan de classes toegevoegd. Het is een beetje te vergelijken met "class c.q. extensions methods" en "partial classes". Maar AOP gaat veel verder, doordat je de aspecten kun hergebruiken en toe kunt passen op alle classes!
Erg interesant, maar de bovenstaande blog was vooral een simpel voorbeeld hoe het technisch werkt, wat ook bleek uit de reacties in de trant van: "Leuk, maar wat kun je er nou mee?". Hierop werd de volgende uitleg gegeven:

The reason this is cool is it allows you to separate your concerns. When you are writing code you don't need mix your concerns by including logging code in your main business logic classes, and you don't need to duplicate the calls to logging in each method.

Keep in mind this is the simplest example. You can use AOP to add multi-threading support, security, logging, etc. to a class. You implement the logging, security, threading, etc. code in one class, and the business logic in another class. Then it is injected for you.

It makes code easier to write and maintain. Less duplication of code so less bugs.

Later verscheen de volgende blog met een specifiek partijk voorbeeld hoe je AOP kunt gebruiken: Prism Aspects to Help with Monobjc Development

AOP is niet de oplossing voor alle problemen, maar zeker een nuttige feature om te gebruiken! Sommige C# programmeurs werden al jalours toen ze die blog lazen... ;-)

dinsdag 27 januari 2009

Prism: Compact Framework en Asynchrone functies

Ik heb een kleine test gedaan om te kijken of je met Delphi Prism en het Compact Framework ook "async" blokken en "future" variabelen kunt gebruiken (voor parallelle c.q. asynchrone verwerking). Hiervoor maakte ik een klein test project (zie mijn vorige blog) met onder een knop de volgende (nutteloze) test code:
method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);
begin
var i: future Integer;
var j: Integer;

i := async 1; //background asigning 1 to i, next line will wait
j := 2 + i; //j should be 3 now
end;
Prism compileert de code gewoon, alleen als ik tijdens het runnen op de bewuste test knop druk, krijg ik een foutmelding: FileLoadException System.Core.dll.
Ook in de emulator gaat het fout, en krijg ik dezelfde foutmelding. Tijd om even wat dingen uit te zoeken!

RemObjects (de makers van de Oxygene c.q. Prism compiler) heeft gelukkig een aantal nieuwsgroepen waar actief en snel reactie gegeven wordt:
Support page: http://www.remobjects.com/support.aspx
Newsgroup support: http://www.remobjects.com/page.aspx?id={C4764DFE-288D-4C17-90F8-FA5B7BFB3BCB}

Aangezien de PublicKeyToken belangrijk is bij het laden van assembly's, heb ik met .Net Reflector gekeken naar de references van mijn executable. Hierbij viel gelijk het probleem op:
Alle references wezen naar assembly's met PublicKeyToken=969db8053d3322ac, behalve "System.Core.dll", deze verwees naar b77a5c561934e089!
In de nieuwsgroep kreeg ik de tip om het project te compileren met de gratis command line compiler. En om met de hand mijn .oxygene bestand (=project file) aan te passen, zodat het de goede reference voor System.Core.dll zou gebruiken:


(op de een of andere manier lukt het niet om als tekst te doen: opmaak gaat fout bij XML...)

Vervolgens gecompileerd via de command line:
oxygene.exe -rebuild -frameworkfolder="C:\Program files\Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE"
En nu kan ik hem wel gewoon draaien en debuggen... alleen op de desktop... Helaas gaat het nog steeds fout in de emulator (harde crash zonder foutmelding).
Als je kijkt met Proces Explorer welke dlls hij op de desktop gebruikt, blijkt dat .Net altijd de volledige (niet de CF) System.Core.dll gebruikt: deze is wel aanwezig op de desktop, maar uiteraard niet in de emulator.

Als laatste poging heb ik via .Net Reflector met de FileGenerator plugin mijn assembly geëxporteerd naar C# code:
Het trouwens wel interessant om te kijken wat voor code automatisch gegenereerd wordt voor mijn paar regels code (de meeste code zit overigens in de "FutureHelper" class):
Vervolgens heb ik met C# Visual Studio Express een nieuw project aangemaakt (zie deze link voor VS Express en Compact Framework). Na wat aanpassingen compileerde het en kon ik het testen in de emulator. Deze geeft gelukkig wat meer informatie: op de volgende regel gaat het fout:
Func func = PrivateImplementationDetails.FutureHelper.ExecuteAsync(delegate {
return 1;
}, true);
Deze geeft de foutmelding:
NotSupportedException: .Net Compact Framework does not support invoking delegates asynchronously
Dus het Compact Framework ondersteunt deze functionaliteit gewoon niet! Dus einde oefening...

In ieder geval was het erg leerzaam (onder het motto: je leert het meest bij fouten). Waarschijnlijk zal CodeGear/RemObjects in de volgende versie een aantal kleine bugs die ik tegen kwam verhelpen. Misschien dat .Net CF versie 4 wel betere asynchrone ondersteuning heeft (dmv Parallel Extensions).

vrijdag 23 januari 2009

Delphi 2009: nieuwe IDE, Language en GUI features

Codegear heeft een aantal Whitepapers op hun website staan. Deze zijn erg interessant om door te lezen! Hierin staat veel nuttige informatie over de veranderingen die in Delphi 2009 zitten. Om eerlijk te zijn: er zijn veel meer veranderingen en verbeteringen dan ik eerst dacht! Ik kan niet alles opnoemen, maar ik heb wel even een overzicht gemaakt:

De nieuwste Whitepaper van Marco Cantu gaat over User Interface wijzigingen (VCL):
http://dn.codegear.com/article/images/39226/Building-User-Interfaces-with-Delphi-2009_WP.pdf

Om even een idee te geven zal ik de deze wijzigingen kort bespreken:

  • Custom hints en Balloon hints

In plaats van saaie simpele hints, kun je nu gelikte hints geven, met een image en title:

  • TButton uitbreidingen

Deze heeft nu standaard image support (net als TBitButton), CommandLink type, Dropdown button, Elevation required (Vista UAC) property:

  • Edit control uitbreidingen

Er is oa een Alignment property toegevoegd (text left/right), "numbers only" format, empty text hint, XP password char:

  • Nieuwe TButtonedEdit control

Dit is een nieuwe edit control, met rechts een button en een image, en de mogelijkheid voor een drop down menu:

  • Listview grouping

De listview ondersteunt nu ook geavanceerde groupings!

  • Nieuwe CatagoryPanelGroup control

Nog een nieuwe control, waarbij de panels kunnen in en uitklappen:

  • Verbeterde graphics support

Nu ingebouwde PNG ondersteuning, 32bit bitmaps (met transparantie kanaal), en "PartialTransparency" support.

  • Nieuwe Ribbon control (Office 2007 Ribbon)

Een door Codegear ontwikkelde Ribbon control (die veel lijkt qua werking en uiterlijk op de Office 2007 Ribbon):

Conclusie: redenen genoeg om Delphi 2009 te gaan gebruiken!

woensdag 21 januari 2009

Delphi Enumerators: "for o in MyObject do"

Ik gebruik Delphi 2007 nog niet zo heel lang, omdat de huidige klant nog de oude Delphi 6 versie gebruikte. Sowieso zijn er best veel bedrijven die bijvoorbeeld Delphi 7 nog steeds gebruiken (wat vaak gewoon goed bevalt). Best jammer, want Delphi 2007 en 2009 zijn mooie en goede Delphi versies, met veel verbeteringen: IDE, VCL en Language features.

Het nadeel van nieuwe features is echter: je moet ze wel gebruiken :-). Heel gauw ben je geneigd om je oude gewoontes te blijven gebruiken: bijvoorbeeld nog steeds "for i := 0 to stringlist.Count-1 do" gebruiken in plaats van "for s in stringlist".

Ik had al eens een serie interessante blogs gelezen over "fun with enumerators":
http://17slon.com/blogs/gabr/2007/03/fun-with-enumerators-part-1.html
http://17slon.com/blogs/gabr/2007/03/fun-with-enumerators-part-2-multiple.html
http://17slon.com/blogs/gabr/2007/03/fun-with-enumerators-part-3.html
http://17slon.com/blogs/gabr/2007/03/fun-with-enumerators-part-4-external.html
http://17slon.com/blogs/gabr/2007/03/fun-with-enumerators-part-5-class.html

In feite komt het erop neer, dat elke class die een "public GetEnumerator" functie heeft, gebruikt kan worden voor een "for in" loop.
De GetEnumerator functie moet een class teruggeven met de volgende functies (als voorbeeld van TStringList.GetEnumerator):
TStringsEnumerator = class
public
function GetCurrent: string;
function MoveNext: Boolean;
property Current: string read GetCurrent;
end;
Van de volgende code...:
for s in stringlist do
ShowMessage(s);
...maakt Delphi onderwater de volgende code ervan:
enumerator := stringlist.GetEnumerator;
while enumerator.MoveNext do
begin
s := enumerator.Current;
ShowMessage(s);
end;
enumerator.Free;
Je kunt dus ook zelf eenvoudig aan een eigen class deze handige enumerator functionaliteit toevoegen! Of via "class helpers" aan een bestaande class.

Op een gegeven moment was ik het namelijk zat om steeds "for i to count-1" te gebruiken, en toen moest ik weer denken aan de eerder genoemde blogs. Met de bovenstaande code kon ik zelf een veelgebruikte class even uitbreiden met enumerators :-).

Trouwens, "for in" kun je ook gebruiken met arrays en sets:
var i:integer;
c: char;
begin
for i in intergerarray do ;
for c in teststring do ;
end;