Re: [fpc-pascal] RemoveDir: Error: Identifier not found

2012-04-25 Thread Sven Barth

Am 24.04.2012 17:35, schrieb Jürgen Hestermann:

If I hit Alt+Up on "RemoveDir" within my program I am moved to
D:\Programme\lazarus\fpc\2.6.1\source\rtl\objpas\sysutils\diskh.inc(21,10)
with the function header declaration but when doing it again
on "RemoveDir" within this file I get:

Error: identifier not found: RemoveDir

so I can't see the implementation of this function.
Is this a bug or some kind of limitation?


You are talking about doing this in Lazarus? Then you should complain on 
the Lazarus list, because such lookups are part of the CodeTools of 
Lazarus (and as this function is part of an include file, there are some 
problematic cases still)


As a sidenote: RemoveDir is implemented in the corresponding SysUtils 
units of your platform. E.g. in case of Windows that is 
%fpcdir%\rtl\win\sysutils.pas (the sysutils unit includes the generic 
header files like diskh.inc through sysutilsh.inc)


Regards,
Sven

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Program without window but messages

2012-04-25 Thread Sven Barth

Am 24.04.2012 18:25, schrieb Jürgen Hestermann:

I wanted to write a program that has no window but may show messages to
the user.
I have lots of such programs written with Virtual Pascal but I am
struggling
to do the same with Free Pascal/Lazarus.

A simple test program would look like this:


program Test;
{$mode objfpc}{$H+}
uses Interfaces,Forms,Windows,SysUtils,Dialogs;
{$R *.res}

begin
ShowMessage('TEST');
end.


When I create a new project and select to create an "Application",
copy the above into the main program (ignoring Unit1.pas) and run
the program I get an exception "Fensterklasse nicht gefunden" (in
german, although I setup Lazarus in english!) and I am put into
Win32WSControls.


This specific exception could be the result of a 
SysErrorMessage(GetLastOSError) which on Windows uses the routines of 
Windows to translate the error and thus will be in the language your OS 
is setup for. (Note: this is a guess, but maybe a very valid one ;) )




When I try the same with a new "Program" and use the same test file
(just omitting Interfaces and Forms units, because Lazarus cannot find it.
Why? I did find it when creating an "Application") I cannot even
compile it because I get:

project1.lpr(10,12) Error: Identifier not found "ShowMessage"

The wiki ( http://wiki.freepascal.org/Dialog_Examples/de#ShowMessage )
says that this function is definied in Dialogs which I included in my
uses clause. Still it cannot find it. Why is ShowMessage not available?

Creating a console program is not an option because it will create a
console window which I don't need.

Anybody who knows why it is like that?


As you are using LCL functions it would be better if you ask such things 
on the Lazarus list.


Regards,
Sven

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


[fpc-pascal] Re: Program without window but messages

2012-04-25 Thread leledumbo
You need to call Application.Initialize prior to anything if you want to use
LCL features (including its dialogs). Your uses clause seems overkill. Only
Interfaces, Forms and Dialogs units required for ShowMessage function.

--
View this message in context: 
http://free-pascal-general.1045716.n5.nabble.com/Program-without-window-but-messages-tp5662570p5664268.html
Sent from the Free Pascal - General mailing list archive at Nabble.com.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Sending break on (Windows) serial comms

2012-04-25 Thread Mark Morgan Lloyd

Mark Morgan Lloyd wrote:

Marco van de Voort wrote:

In our previous episode, Mark Morgan Lloyd said:
Marco, I see you had a StackOverflow question on this a year or so 
ago. Did you ever get anywhere with it in practice?


It was an idea to lower the overhead and improve the reliability of our
serial protocol. (because of the out of band information is guaranteed
unique and can't happen in the datastream)

But if you can't insert the break cleanly into the character stream, 
it is

useless for protocol purposes I guess. And it was not worth centering the
rest of the application around it.

I did't have any confidence in the solutions presented (just reset the
connection and pauze) because both the pauze is not reliable in length on
preemptive systems like Windows, and the damage to the FIFOs is a 
problem,

since that would negate the size advantages.

I never pursued it further.


OK. I'll start off with the standard API, with an explicit check that 
the output has drained by default, and a mSec parameter (which will get 
rounded up to something gross on unix).


I'm still hoping that at some point the units and test code will be 
bundled in place of the existing unix-only serial.pp.


I've added it, but it's best avoided except for the classic use of 
getting a remote system's attention. On Linux the only working parameter 
is zero indicating a break of around 250 mSec, on Solaris it doesn't 
work at all, and on Windows I've not found a way of preventing a break 
from trashing anything that's sitting in the Tx buffer.


Modified library appended to issue 18946 in Mantis.

--
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk

[Opinions above are the author's, not those of his employers or colleagues]
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


[fpc-pascal] Re: does disconnected tLSocket auto destroy in lnet

2012-04-25 Thread ZHANG Dao-yuan

On 04/24/2012 05:01 PM, ZHANG Dao-yuan wrote:

I'm using tLTcp with tLEventer. I've set tLTcp.eventer to the associated 
tLEvent object and call tLEvent.callAction to wait for new events. After a 
socket disconnected, OnDisconnect gets called shipped with an aSocket:tLSocket 
parameter.
Should I call aSocket.destroy explicitly to prevent the disconnected aSocket 
from leaking the memory?


Ok, the problem is resolved. We don't worry about it since thess memory is 
handled by Lnet.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Program without window but messages

2012-04-25 Thread Jürgen Hestermann

Sven Barth schrieb:
>> When I create a new project and select to create an "Application",
>> copy the above into the main program (ignoring Unit1.pas) and run
>> the program I get an exception "Fensterklasse nicht gefunden" (in
>> german, although I setup Lazarus in english!)
>
> This specific exception could be the result of a 
SysErrorMessage(GetLastOSError)
> which on Windows uses the routines of Windows to translate the error 
and thus
> will be in the language your OS is setup for. (Note: this is a guess, 
but maybe a very valid one ;) )


Yes, meanwhile this came to my mind too. It makes sense because my 
Windows is in german. ;-)




> As you are using LCL functions it would be better if you ask such 
things on the Lazarus list.


You are right. I will do so. Thanks for the hint.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Re: Program without window but messages

2012-04-25 Thread Jürgen Hestermann

leledumbo schrieb:
> You need to call Application.Initialize prior to anything if you want 
to use

> LCL features (including its dialogs).

Is "ShowMessage" part of the LCL? I thought that it comes with Free 
Pascal directly
because the wiki 
http://wiki.freepascal.org/Dialog_Examples/de#ShowMessage , which

explains this message, is located on wiki.freepascal.org.
But if it's realy from the LCL then it makes sense that I cannot use 
this function without a form.
Still very missleading to explain LCL functions under a Free Pascal web 
site.

How should someone know where these functions come from?
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] RemoveDir: Error: Identifier not found

2012-04-25 Thread Jürgen Hestermann

Sven Barth schrieb:
> You are talking about doing this in Lazarus? Then you should complain 
on the Lazarus list,
> because such lookups are part of the CodeTools of Lazarus (and as 
this function is part of

> an include file, there are some problematic cases still)

Yes, you are right (again). ;-) I will do this.


> As a sidenote: RemoveDir is implemented in the corresponding SysUtils 
units of your platform.
> E.g. in case of Windows that is %fpcdir%\rtl\win\sysutils.pas (the 
sysutils unit includes

> the generic header files like diskh.inc through sysutilsh.inc)

Thanks. Will have a look there.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Re: Program without window but messages

2012-04-25 Thread Jonas Maebe

On 25 Apr 2012, at 17:49, Jürgen Hestermann wrote:

> Is "ShowMessage" part of the LCL? I thought that it comes with Free Pascal 
> directly
> because the wiki http://wiki.freepascal.org/Dialog_Examples/de#ShowMessage , 
> which
> explains this message, is located on wiki.freepascal.org.

http://wiki.freepascal.org is exactly the same as 
http://wiki.lazarus.freepascal.org. There is only one wiki for both projects.


Jonas___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Program without window but messages

2012-04-25 Thread Jürgen Hestermann

JC Chu schrieb:
> Try this.
> program Test;
> {$MODE DELPHI}
> {$APPTYPE GUI}
> uses
>   {$IF Defined(UNIX) and Defined(UseCThreads)}cthreads,{$ENDIF}
>   Interfaces, Forms, Dialogs;
>
> begin
>   Application.Initialize;
>   ShowMessage('Test');
> end.


Yes, this works!

Now I only need to understand why. ;-)

I was expecting the "application.initialize" to create a
window so I omitted it.
What does the initialize routine?
Why is it needed?

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Re: Program without window but messages

2012-04-25 Thread Tomas Hajny
On Wed, April 25, 2012 17:49, Jürgen Hestermann wrote:
> leledumbo schrieb:
>  > You need to call Application.Initialize prior to anything if you want
> to use
>  > LCL features (including its dialogs).
>
> Is "ShowMessage" part of the LCL? I thought that it comes with Free
> Pascal directly
> because the wiki
> http://wiki.freepascal.org/Dialog_Examples/de#ShowMessage , which
> explains this message, is located on wiki.freepascal.org.
> But if it's realy from the LCL then it makes sense that I cannot use
> this function without a form.
> Still very missleading to explain LCL functions under a Free Pascal web
> site.
> How should someone know where these functions come from?

The Wiki is common for both projects
(http://wiki.lazarus.freepascal.org/Dialog_Examples/de#ShowMessage shows
the same article). Looking up the documentation or reference to the unit
location for a particular function from your IDE (Lazarus in your case) is
probably better source of information where it belongs to than the Wiki.
In general, visual components are provided by LCL (unless talking about
general GUI elements which are available in the respective interface units
like unit Windows for Win32/Win64 or Xlib, etc.). Also the page mentioned
above contains several references to LCL and Lazarus.

Tomas


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Program without window but messages

2012-04-25 Thread Jürgen Hestermann

Howard Page-Clark schrieb:
> A GUI program requires a "main window" since that is the avenue for 
user interaction.
> You can hide that window (not "ignore" it) as in the following 
program, which compiles
> and runs. However, I can't myself see the use of such truncated GUI 
functionality.
> Once the main form is hidden, I see no way for the user ever to get 
back to it.


> program Project1;
> {$mode objfpc}{$H+}
> uses Interfaces, Forms, Unit1, Dialogs;
> {$R *.res}
> begin
>   Application.Initialize;
>   Application.CreateForm(TForm1, Form1);
>   Form1.Hide;
>   ShowMessage('TEST');
>   Form1.Close;
>   Application.Run;
> end.

I also thought about this but wanted to avoid any flickering window
coming up on program start when it's created with CreateForm and
directly hidden again afterwards.

JC Chu gave an example by omitting most of the above and only leaving:

begin
Application.Initialize;
ShowMessage('TEST');
end;

This works. Though I thought that ShowMessage is not part of the LCL
so the 1.5 MB added to the program could be avoided.
But okay, if it is from the LCL then I will use the Windows API messagebox
function instead.

Thanks everybody for the hints!
I think I know now how to get on the road.

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Re: Program without window but messages

2012-04-25 Thread Jürgen Hestermann

Jonas Maebe schrieb:
>> Is "ShowMessage" part of the LCL? I thought that it comes with Free 
Pascal directly
>> because the wiki 
http://wiki.freepascal.org/Dialog_Examples/de#ShowMessage , which

>> explains this message, is located on wiki.freepascal.org.
> http://wiki.freepascal.org is exactly the same as 
http://wiki.lazarus.freepascal.org. There is only one wiki for both 
projects.


That would be ok if it does not matter much where a function is located.
But this seems to be very important so making readers believe ShowMessage
comes with plain Free Pascal by explaining it under a Free Pascal link 
is not so good.


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Program without window but messages

2012-04-25 Thread JC Chu
As leledumbo has pointed out, you need to call Application.Initialize()
before using LCL features.  The code for TApplication.Initialize() shows
that it initializes the currently active widget set, which is maintained
by the Interfaces unit.  ShowMessage() relies ultimately upon
TWidgetSet.PromptUser(), and that is why TApplication.Initialize() is
needed.

On April 26, at 00:04, Jürgen Hestermann wrote:

> JC Chu schrieb:
>> Try this.
>> program Test;
>> {$MODE DELPHI}
>> {$APPTYPE GUI}
>> uses
>>   {$IF Defined(UNIX) and Defined(UseCThreads)}cthreads,{$ENDIF}
>>   Interfaces, Forms, Dialogs;
>>
>> begin
>>   Application.Initialize;
>>   ShowMessage('Test');
>> end.
> 
> Yes, this works!
> Now I only need to understand why. ;-)
> 
> I was expecting the "application.initialize" to create a
> window so I omitted it.
> What does the initialize routine?
> Why is it needed?
> 
> ___
> fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal

-- 
Best Regards,
JC Chu
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Program without window but messages

2012-04-25 Thread Sven Barth

On 24.04.2012 18:25, Jürgen Hestermann wrote:

I wanted to write a program that has no window but may show messages to
the user.
I have lots of such programs written with Virtual Pascal but I am
struggling
to do the same with Free Pascal/Lazarus.

A simple test program would look like this:


program Test;
{$mode objfpc}{$H+}
uses Interfaces,Forms,Windows,SysUtils,Dialogs;
{$R *.res}

begin
ShowMessage('TEST');
end.




A different (maybe not completly serious ;) ) idea is the following: If 
you only want to show error messages and your application should only 
work on Windows then you can do the following:


=== example begin ===

program Test;

{$apptype gui} // only to illustrate that this is a GUI application

begin
  Writeln(StdErr, 'TEST'); // alternatively you can use StdOut as well
end.

=== example end ===

This way an error dialog that is created using basic Windows API calls 
is created which you can confirm using Ok. This only works on Windows 
and only if the application is compiled as a GUI application (which is 
by default the case in Lazarus). There is only one caveat: The dialog is 
not immediately displayed, but only if enough data has accumulated and 
Flush(StdErr) doesn't work either in that case to force the output... 
thus the following code will show one dialog which contains both written 
lines (as seperate lines) - that's why this idea isn't a really serious 
suggestion:


=== example begin ===

program winerrortest;

{$apptype gui}

begin
  Writeln(StdErr, 'Hello World');
  Flush(StdErr);
  Writeln(StdOut, 'Hello World 2');
  Flush(StdOut);
end.

=== example end ===

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


[fpc-pascal] typesafe typecasting

2012-04-25 Thread Bernd
Hi,

While translating some headers I have run across the following problem
(I am sure had this in different variations many times before already
and always lived with it and ignored it by casting from untyped
pointers). Consider this situation:

unit Unit1;

{$mode objfpc}{$H+}

interface

type
  PData = Pointer;
  PCallback = procedure(Data: PData); cdecl;

procedure RegisterCallback(Proc: PCallback; Data: PData);


implementation

procedure RegisterCallback(Proc: PCallback; Data: PData);
begin
  //just call the callback now for demonstration purpose
  Proc(Data);
end;

end.

The above unit might be an API for some C library or some other piece
of code that will allow me to register a callback (a timer or
something similar) and pass additional data via a pointer to my
callback function. The following unit will use this API:

program project1;

{$mode objfpc}{$H+}{$T+}

uses Unit1;

type
  PMyData = ^TMyData;
  TMyData = record
Foo: Integer;
Bar: Integer;
  end;


procedure MyUglyCallback(D: Pointer); cdecl;
begin
  // ugly typecasting everytime I access my data
  writeln(PMyData(D)^.Foo);
  Dispose(PMyData(D));
end;

procedure MyNiceCallback(var D: TMyData); cdecl;
begin
  // this function looks much nicer but although it is binary
  // identical its signature is deemed incompatible by FPC
  writeln(D.Foo);
  Dispose(@D);
end;

procedure Run;
var
  D : PMyData;
begin
  New(D);
  D^.Foo := 42;
  RegisterCallback(@MyUglyCallback, D);

  New(D);
  D^.Foo := 23;
  // unsafe typecasting, would accept *any* procedure
  RegisterCallback(PCallback(@MyNiceCallback), D);
end;

begin
  Run;
end.

None of the two possibilities feels right, the first one is what I
have always used (out of desperation) because it will at least enforce
that I do not accidentally forget the cdecl in my callback function
but the casting of the Pointer inside the function looks just ugly to
me and simply does not feel right, it is against the spirit of the
language and it is still unsafe.

The second option will almost guarantee that in one of my (many)
callback functions I will sooner or later accidentally forget the
cdecl because It will allow me to pass *anything* to RegisterCallback,
this one feels even more type-unsafe to me.

Now I have come up with the following:

program project1;

{$mode objfpc}{$H+}{$T+}

uses Unit1;

type
  PMyData = ^TMyData;
  TMyData = record
Foo: Integer;
Bar: Integer;
  end;

  PMyCallback = procedure(var Data: TMyData); cdecl;

function CastMyCallback(Proc: PMyCallback): PCallback; inline;
begin
  Result := PCallback(Proc);
end;

procedure MyNiceCallback(var D: TMyData); cdecl;
begin
  // this function looks much nicer but although it is binary
  // identical its signature is deemed incompatible by FPC
  writeln(D.Foo);
  Dispose(@D);
end;

procedure Run;
var
  D : PMyData;
begin
  New(D);
  D^.Foo := 5;
  // this is the only way I have found to let me have my
  // own types and still retain total type-safety
  RegisterCallback(CastMyCallback(@MyNiceCallback), D);
end;

begin
  Run;
end.

This has an overhead of only 4 code lines (the CastMyCallback
function) and only once for all my different callback functions that
use the same data structure and it would completely retain strong type
safety. What do you think, is this a good idea or would there have
been an even more elegant way to achieve the same?

Bernd
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] typesafe typecasting

2012-04-25 Thread JC Chu
When you assign a “specialized” pointer, say a PInteger, to a generic
Pointer variable, the assignment is valid because the compiler knows
that PInteger is a subtype of Pointer.  There is however no general way
of determining a subtype relation between procedural types, even if some
of their parameters are known to be related.  Even in unary cases,
T1 ≺ T2 does not imply that a PROCEDURE (T1) can be safely assigned to
a PROCEDURE (T2)–typed variable, nor vice versa; for example, given
PMyRecord ≺ Pointer, you probably wouldn’t want

  ◦ @FreeMem() assigned to
VAR finalizeMyRecord: PROCEDURE (rec: PMyRecord); or
  ◦ something like @InitMyRecord() assigned to
VAR: reserve100GB: PROCEDURE (ptr: Pointer).

Using a generic callback procedure as in your scenario does potentially
permit such unwanted operations.

I do vaguely remember a UNIV modifier that’s available in the
Macintosh Pascal mode, but I couldn’t find any documentation about it
(nor do I know if it can be enabled in other modes) and I’m not sure
what it exactly does.  Although it does seem to eliminate the need for
manual typecasts, type-safety is generally not guaranteed.

Your last proposal is not completely safe, because you can still use
non-PMyData pointers with RegisterCallback().

So to answer your question, my suggestion would be to define a custom
callback type with a custom RegisterCallback() for each of your custom
data structures.

Hope this helps.


On April 26, at 02:39, Bernd wrote:

> Hi,
> 
> While translating some headers I have run across the following problem
> (I am sure had this in different variations many times before already
> and always lived with it and ignored it by casting from untyped
> pointers). Consider this situation:
> 
> unit Unit1;
> 
> {$mode objfpc}{$H+}
> 
> interface
> 
> type
>   PData = Pointer;
>   PCallback = procedure(Data: PData); cdecl;
> 
> procedure RegisterCallback(Proc: PCallback; Data: PData);
> 
> 
> implementation
> 
> procedure RegisterCallback(Proc: PCallback; Data: PData);
> begin
>   //just call the callback now for demonstration purpose
>   Proc(Data);
> end;
> 
> end.
> 
> The above unit might be an API for some C library or some other piece
> of code that will allow me to register a callback (a timer or
> something similar) and pass additional data via a pointer to my
> callback function. The following unit will use this API:
> 
> program project1;
> 
> {$mode objfpc}{$H+}{$T+}
> 
> uses Unit1;
> 
> type
>   PMyData = ^TMyData;
>   TMyData = record
> Foo: Integer;
> Bar: Integer;
>   end;
> 
> 
> procedure MyUglyCallback(D: Pointer); cdecl;
> begin
>   // ugly typecasting everytime I access my data
>   writeln(PMyData(D)^.Foo);
>   Dispose(PMyData(D));
> end;
> 
> procedure MyNiceCallback(var D: TMyData); cdecl;
> begin
>   // this function looks much nicer but although it is binary
>   // identical its signature is deemed incompatible by FPC
>   writeln(D.Foo);
>   Dispose(@D);
> end;
> 
> procedure Run;
> var
>   D : PMyData;
> begin
>   New(D);
>   D^.Foo := 42;
>   RegisterCallback(@MyUglyCallback, D);
> 
>   New(D);
>   D^.Foo := 23;
>   // unsafe typecasting, would accept *any* procedure
>   RegisterCallback(PCallback(@MyNiceCallback), D);
> end;
> 
> begin
>   Run;
> end.
> 
> None of the two possibilities feels right, the first one is what I
> have always used (out of desperation) because it will at least enforce
> that I do not accidentally forget the cdecl in my callback function
> but the casting of the Pointer inside the function looks just ugly to
> me and simply does not feel right, it is against the spirit of the
> language and it is still unsafe.
> 
> The second option will almost guarantee that in one of my (many)
> callback functions I will sooner or later accidentally forget the
> cdecl because It will allow me to pass *anything* to RegisterCallback,
> this one feels even more type-unsafe to me.
> 
> Now I have come up with the following:
> 
> program project1;
> 
> {$mode objfpc}{$H+}{$T+}
> 
> uses Unit1;
> 
> type
>   PMyData = ^TMyData;
>   TMyData = record
> Foo: Integer;
> Bar: Integer;
>   end;
> 
>   PMyCallback = procedure(var Data: TMyData); cdecl;
> 
> function CastMyCallback(Proc: PMyCallback): PCallback; inline;
> begin
>   Result := PCallback(Proc);
> end;
> 
> procedure MyNiceCallback(var D: TMyData); cdecl;
> begin
>   // this function looks much nicer but although it is binary
>   // identical its signature is deemed incompatible by FPC
>   writeln(D.Foo);
>   Dispose(@D);
> end;
> 
> procedure Run;
> var
>   D : PMyData;
> begin
>   New(D);
>   D^.Foo := 5;
>   // this is the only way I have found to let me have my
>   // own types and still retain total type-safety
>   RegisterCallback(CastMyCallback(@MyNiceCallback), D);
> end;
> 
> begin
>   Run;
> end.
> 
> This has an overhead of only 4 code lines (the CastMyCallback
> function) and only once for all my different callback functions that
> use the same data structure and it