[Lazarus] BitBlt caused SIGFPE in lclproc.pas
Hi There, Why the following code generated SIGFPE on BitBlt? === procedure TForm1.Button1Click(Sender: TObject); var png: TPortableNetworkGraphic; ScreenDC, ClipDC: HDC; r: TRect; begin r := Rect(0, 0, 300, 200); png := TPortableNetworkGraphic.Create; ScreenDC := GetDC(0); ClipDC := CreateCompatibleDC(ScreenDC); BitBlt(ClipDC, 0, 0, r.Right - r.Left, r.Bottom - r.Top, ScreenDC, r.Left, r.Top, SRCCOPY); png.LoadFromDevice(ClipDC); DeleteDC(ClipDC); ReleaseDC(0, ScreenDC); png.SaveToFile('test.png'); end; === I am on Ubuntu GTK2 and hope this code to run cross platform. Thanks-- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
[Lazarus] polymophic function pointers
Hi, Is it possible to do the following: === example === program test; type TMyClass = class type TDataFilter = function public Value : Double; Filter: TDataFilter; procedure ViewData; end; procedure TMyClass.ViewData; begin if Filter = nil then WriteLn(Value) else WriteLn(Filter(Value)); end; var t : TMyClass; begin t := TMyClass.Create; t.Value = 2; t.Filter := @sqr; //this does not work t.Filter := @ln; //this does not work either t.ViewData; t.Free; end. = The problem is, while assign function pointers to Filter, I would like to make it accept all numeric functions. That is, if I define it to accept Double, it should accept Single and Integers, and if I define it to accept Extended, it should accept all numbers. Possible? Thanks, Shannon-- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
[Lazarus] "default" visibility for class members
Hi All, My class looks like this: TMyClass = class FField1: Integer; private FField2: string; public FField3: string; end; Question is, is FField1 private or public or protected? For all lcl classes, I see a lot of fields above "private", it looks like they are same as "public", because I can access them from outside. But why allow them to be put there instead of directly under "public"? Thanks, Shannon -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] "global" operator overloading
No, it's not a dilemma, but rather a requirement. Before generics specialization, all required operations for given type must be known. This is because the symbol table when the generics is parsed must be reconstructed when it gets specialized. Think about declaring usual classes with the generic parameter replaced with actual type. If at that time, the operation < is not yet defined, the code won't compile anyway. It is a pity. I think if fpc supports class operators, maybe this problem could be solved by using class helpers (my purpose is that users of ttreap class does not have to modify treap.pas) ? Is that possible in future FPC? -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
[Lazarus] "global" operator overloading
Hi There, Days ago I posted a message about compiling error related to operator overloading. I found the reason now, but don't know how to fix that. The code is: = uses Classes, treap; type TSLCounter = specialize TTreap; operator <(sl1, sl2: TStringList): Boolean; = The compiler complains about "<" is not defined for string list. If I put the operator overloading into treap.pas, there is no problem. Is there anyway to avoid this dilemma? Because I don't want treap.pas to "reversely" rely on a specialized class. Thanks, Shannon-- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] operator overloading
I confirm that it does not work. Test program below, and the class source is attached. ==Test Program=== program test; {$mode objfpc}{$H+} uses Classes, treap; type TSLCounter = specialize TTreap; operator <(sl1, sl2: TStringList): Boolean; begin Result := sl1.Text < sl2.Text; end; begin end. ==Error Message== Options changed, recompiling clean with -B /home/xrfang/git/fpcollection/src/units/treap.pas(216,10) Error: Operator is not overloaded: "TStringList" < "TStringList" /home/xrfang/git/fpcollection/src/units/treap.pas(218,15) Error: Operator is not overloaded: "TStringList" > "TStringList" test.lpr(19) Fatal: There were 2 errors compiling module, stopping = i.e. whether the operator overloading is defined or not, error message is same. Thanks. 在 日, 2月 24, 2013 at 4:21 下午,leledumbo 写道: FPC operator overloading doesn't work inside classes, it must be declared globally, so method2 should work. What error do you get? What FPC version do you use? -- View this message in context: http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-operator-overloading-tp4029399p4029400.html Sent from the Free Pascal - Lazarus mailing list archive at Nabble.com. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus unit treap; {$mode objfpc} interface type { TTreap } generic TTreap = class const MAX_PRIORITY = $7FFF; type PNode = ^TNode; TNode = record Key: TKey; Value: TValue; Priority: Cardinal; Left, Right: PNode; end; private Altered: Boolean; //for Insert & Delete GoOn: Boolean;//for Traverse FCount: Integer; NullNode, RootNode: PNode; function GetCount: Integer; function LeftRotate(Node: PNode): PNode; function RightRotate(Node: PNode): PNode; function InsertNode(Key: TKey; Value: TValue; Node: PNode): PNode; function DeleteNode(Key: TKey; Node: PNode): PNode; procedure TraverseNode(Node: PNode; dir: Integer); procedure ClearNode(Node: PNode); function Compare({%H-}Key: TKey; Node: PNode): Integer; protected function Traverse({%H-}Key: TKey; {%H-}Value: TValue): Boolean; virtual; procedure OnDispose({%H-}Value: TValue); virtual; function OnInsert({%H-}Key: TKey; {%H-}Value: TValue; {%H-}IsNew: Boolean): Boolean; virtual; public property Count: Integer read GetCount; function Insert(Key: TKey; Value: TValue): Boolean; function Delete(Key: TKey): Boolean; function Find(Key: TKey): PNode; procedure Clear; constructor Create; virtual; destructor Destroy; override; procedure Walk(dir: Integer = 0); //0=ascending; 1=descending end; implementation function TTreap.InsertNode(Key: TKey; Value: TValue; Node: PNode): PNode; begin if Node = NullNode then begin if OnInsert(Key, Value, True) then begin New(Node); Node^.Key := Key; Node^.Value := Value; Node^.Priority := Random(MAX_PRIORITY); Node^.Left := NullNode; Node^.Right := NullNode; Altered := True; Inc(FCount); end; end else begin case Compare(Key, Node) of 0: begin Altered := Node^.Value <> Value; if Altered and OnInsert(Key, Value, False) then Node^.Value := Value; end; 1: begin Node^.Right := InsertNode(Key, Value, Node^.Right); if Node^.Right^.Priority < Node^.Priority then Node := RightRotate(Node); end; else begin Node^.Left := InsertNode(Key, Value, Node^.Left); if Node^.Left^.Priority < Node^.Priority then Node := LeftRotate(Node); end; end; end; Result := Node; end; function TTreap.DeleteNode(Key: TKey; Node: PNode): PNode; begin if Node <> NullNode then begin case Compare(Key, Node) of 0: begin if Node^.Left^.Priority < Node^.Right^.Priority then Node := LeftRotate(Node) else Node := RightRotate(Node); if Node <> NullNode then Node := DeleteNode(Key, Node) else begin OnDispose(Node^.Left^.Value); Dispose(Node^.Left); Node^.Left := NullNode; Altered := True; Dec(FCount); end; end; 1: Node^.Right := DeleteNode(Key, Node^.Right); else Node^.Left := DeleteNode(Key, Node^.Left); end; end; Result := Node; end; procedure TTreap.TraverseNode(Node: PNode; dir: Integer); begin if (not GoOn) or (Node = NullNode) then Exit; if dir = 0 then begin TraverseNode(Node^.Left, dir); if GoOn then GoOn := Traverse(Node^.Key, Node^.Value); TraverseNode(Node^.Right, dir); end else begin
Re: [Lazarus] operator overloading
I will test again tomorrow to find out what's wrong with my code. For now, one more queston: I noticed that generics does not work without {$mode objfpc}. I wonder what is the default mode without $mode? Why objfpc is not the default mode? 在 日, 2月 24, 2013 at 11:00 下午,Sven Barth 写道: On 24.02.2013 15:51, Wildfire wrote: > *From:* xrfang > *Sent:* Sunday, February 24, 2013 7:31 AM > *To:* Lazarus@lists.lazarus.freepascal.org > > *Subject:* [Lazarus] operator overloading > > operator < (p1, p2: TPainter) b: Boolean; <—method2 > Close, but no cigar... > operator < (p1, p2: TPainter): Boolean; Both variants will work. The variant with "b: Boolean" was originally introduced for the non-Object-Pascal modes (fpc, tp), because there you only have the name of the procedure/function as a result variable and as operators don't have names (in that sense) you can specify the name of the result variable. It works in the Object Pascal modes (delphi, objfpc) however as well. Regards, Sven -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
[Lazarus] operator overloading
Hi All, How can I use operator overloading? I know the syntax, but it simply does not compile... My situation is: 1. I wrote a TTreap generic class, which is a binary tree. 2. TTreap defines a Compare() with involves < and > operation on its keys. 3. I try to specialize it with the following: === interface TPainterManager = class(specialize TTreap) public class operator < (p1, p2: TPainter) b: Boolean; <-- method1 end; operator < (p1, p2: TPainter) b: Boolean; <-- method2 implementation .. === but neither method1 nor method2 compiles. What is the correct way to write operator overload routines? Thanks, Shannon I -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
[Lazarus] Check if an abstract method is implemented or not
Hi All, I wrote a TPainter abstract class, and a TPaintRect class. In the TPaintRect class I have this code: procedure TPaintRect.OnMouseEnter(Sender: TObject); var i: Integer; p: TPainter; begin for i := 0 to painters.Count - 1 do begin p := TPainter(painters.Objects[i]); try p.OnMouseEnter(Sender); except on EAbstractError do ; end; end; if Assigned(FOnMouseEnter) then FOnMouseEnter(Sender); end; While running in IDE, the program will crash because OnMouseEnter is abstract. My problems are: 1) As I already wrapped it with try-except, I hope it won't trigger IDE exception. But even I turn off "Notify on Lazarus Exception" in debugger options it still pops up, and the popup said RunError(211), NOT EAbstractError. The program runs well outside of IDE. 2) Is there a way to detect if an abstract method is implemented or not, without trying to call it and try...except? Thanks, Shannon -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
[Lazarus] property setter
Hi all, Lazarus auto generated the following code for my class: procedure TPainter.SetFont(AValue: TFont); begin if FFont=AValue then Exit; FFont:=AValue; end; My question is, why the "if" clause needed? Is there any performance benefits? Thanks, Shannon-- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Dynamic library dependency error
Hi Howard, Thanks for your info. After adding LCLBase to dependencies, I get these errors: /usr/bin/ld: warning: link.res contains output sections; did you forget -T? /usr/bin/ld: /home/xrfang/Desktop/paintrect/lib/x86_64-linux/paintrect.o: relocation R_X86_64_32S against `_$PAINTRECT$_Ld1' can not be used when making a shared object; recompile with -fPIC /home/xrfang/Desktop/paintrect/lib/x86_64-linux/paintrect.o: 无法读取符号: 错误的值 liboval.lpr(14) Error: Error while linking where "无法读取符号: 错误的值" means "cannot read symbol: illegal value". What's wrong here? Thanks, Shannon 在 二, 1月 22, 2013 at 10:41 下午,Howard Page-Clark 写道: On 22/1/13 2:22, xrfang wrote: > I try to make a dynamic library and get this error: > > paintrect.pas(0,0) Fatal: Can not find unit Controls used by paintrect. > Check if package LCLBase is in the dependencies. You need to add LCLBase as a project dependency. Use the Project Inspector's Add button to show the Add to Project dialog. Project -> Project Inspector, then in the Project Inspector click the middle tab to open the New Requirement page, and in the Package Name combo dropdown choose LCLBase from the long list presented. Then click the [Create New Requirement] button, and you're done - the new package requirement will be listed under Required Packages node in the Project Inspector. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
[Lazarus] Dynamic library dependency error
Hi All, I try to make a dynamic library and get this error: paintrect.pas(0,0) Fatal: Can not find unit Controls used by paintrect. Check if package LCLBase is in the dependencies. The source code of my library is: library liboval; {$mode objfpc}{$H+} uses paintrect, oval; function GetPainter: TPainter; begin end; exports GetPainter; begin end. And the used paintrect.pas is attached. Any hint is greatly appreciated. Thanks, Shannonunit paintrect; {$mode objfpc}{$H+} interface uses Classes, Controls, ExtCtrls, Graphics, Types, SysUtils, LCLType; type TPainter = class abstract public OnKeyDown: TKeyEvent; OnKeyUp: TKeyEvent; OnUTF8KeyPress: TUTF8KeyPressEvent; OnMouseDown: TMouseEvent; OnMouseEnter: TNotifyEvent; OnMouseLeave: TNotifyEvent; OnMouseMove: TMouseMoveEvent; OnMouseUp: TMouseEvent; OnMouseWheel: TMouseWheelEvent; OnMouseWheelDown: TMouseWheelUpDownEvent; OnMouseWheelUp: TMouseWheelUpDownEvent; procedure Paint(Canvas: TCanvas; Rect: TRect); virtual abstract; end; { TPaintRect } TPaintRect = class private align: TAlign; box: TPaintBox; _span: Real; painters: TStringList; //array of TPainter; prect: TPaintRect; FOnKeyDown: TKeyEvent; FOnKeyUp: TKeyEvent; FOnMouseDown: TMouseEvent; FOnMouseEnter: TNotifyEvent; FOnMouseLeave: TNotifyEvent; FOnMouseMove: TMouseMoveEvent; FOnMouseUp: TMouseEvent; FOnMouseWheel: TMouseWheelEvent; FOnMouseWheelDown: TMouseWheelUpDownEvent; FOnMouseWheelUp: TMouseWheelUpDownEvent; FOnPaint: TNotifyEvent; FOnUTF8KeyPress: TUTF8KeyPressEvent; function GetRect(Invert: Boolean = False): TRect; function GetSpan: Real; procedure SetSpan(AValue: Real); procedure OnKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure OnKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); procedure OnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure OnMouseEnter(Sender: TObject); procedure OnMouseLeave(Sender: TObject); procedure OnMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure OnMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure OnMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); procedure OnMouseWheelDown(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean); procedure OnMouseWheelUp(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean); procedure OnPaint(Sender: TObject); procedure OnUTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char); procedure Initialize; public property Span: Real read GetSpan write SetSpan; constructor Create(ABox: TPaintBox; AnAlign: TAlign; ASpan: Real); constructor Create(ARect: TPaintRect; AnAlign: TAlign; ASpan: Real); destructor Destroy; override; procedure AddPainter(AName: string; APainter: TPainter); end; implementation { TPaintRect } function TPaintRect.GetRect(Invert: Boolean): TRect; var pr : TRect; function Size: Integer; begin case align of alBottom, alTop: Result := pr.Bottom - pr.Top; else Result := pr.Right - pr.Left; end; if _span < 1 then begin Result := Round(_span * Result); end else begin if _span < 0 then Result := 0 else if _span < Result then Result := Trunc(_span); end; end; begin if Assigned(prect) then pr := prect.GetRect(True) else pr := Rect(0, 0, box.ClientWidth - 1, box.ClientHeight - 1); if align in [alNone, alClient, alCustom] then begin if Invert then Result := Rect(0, 0, 0, 0) else Result := pr; end else if Invert then begin case align of alBottom: Result := Rect(pr.Left, pr.Top, pr.Right, pr.Bottom-Size); alLeft: Result := Rect(pr.Left+Size, pr.Top, pr.Right, pr.Bottom); alRight: Result := Rect(pr.Left, pr.Top, pr.Right-Size, pr.Bottom); alTop: Result := Rect(pr.Left, pr.Top+Size, pr.Right, pr.Bottom); end; end else begin case align of alBottom: Result := Rect(pr.Left, pr.Bottom-Size+1, pr.Right, pr.Bottom); alLeft: Result := Rect(pr.Left, pr.Top, pr.Left+Size-1, pr.Bottom); alRight: Result := Rect(pr.Right-Size+1, pr.Top, pr.Right, pr.Bottom); alTop: Result := Rect(pr.Left, pr.Top, pr.Right, pr.Top+Size-1); end; end; end; function TPaintRect.GetSpan: Real; begin Result := _span; end; procedure TPaintRect.SetSpan(AValue: Real); begin _span := AValue; box.Invalidate; end; procedure TPaintRect.OnKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); var i: Integer; p: TPainter; begin for i := 0 to painters.Count - 1 do begin p := TPainter(painters.Objects[i]); if Assigned(p.OnKeyDown) then p.OnKeyDown(Sender, Key, Shift); end; if Assigned(FOnKeyDown) then FO
[Lazarus] Initial value for procedure of object
Hi, If I define a class like this: TMyClass = class(TWinControl) private FOnClick: TNotifyEvent; ... end; What is the initial value of FOnClick? Do I have to set it to nil explicitly in the constructor? Thanks, Shannon-- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
[Lazarus] Handle user inputs
Hi, I want to use TApplicationProperties.OnUserInput to process keyboard/mouse events. But the parameter of this method is a Cardinal. My questions are: 1) How do I know its event type, such as keydown/keyup/keypress or mouse move etc? 2) How do I know the actual key that is pressed, or the X, Y coordinates of the mouse? Thanks, Shannon-- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
[Lazarus] cross-platform way of put pascal class in a dynamic library
Hi All, Is there a safe and cross-platform way to put a Lazarus Class into a dynamic library? The description here: http://wiki.freepascal.org/shared_library seems not complete and / or out-dated? Thanks, Shannon-- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] record literal in FPC?
I don't know if it's related to the fact that TEdit.CaretPos.X (or Y) is read only, or as Mattias said, the with syntax cannot work with record anyway... :-) This should be a problem (if any) with lazarus not fpc. Shannon 在 三, 1月 9, 2013 at 8:27 下午,Andreas Schneider 写道: Interesting. IIRC that worked correctly in Delphi 2010 (it's been a while ...). This might be a bug in FPC. The root of the problem is how properties are handled. Afaics however, the use of with should cause it to assign the final record afterwards. Apparently it doesn't - at least not always. Could be by design, could be a bug. I'll check the bug tracker later and may report that. (You can do that yourself, if you want, but sooner or later I would like that functionality to work too, so I've a personal interest in this and therefore would not mind to report it :-)) Greetings, Andreas On 09.01.2013 13:19, xrfang wrote: Hi Adreas, I just tried, your method did not work as expected. It compiled ok, but didn't put the cursor at the end of the line as I wanted. However, assign CaretPos a new TPoint worked. Regards, 在 三, 1月 9, 2013 at 4:47 下午,Andreas Schneider 写道: Hi, you could also use the with-statement, that is pretty handy in such cases: with Edit1.CaretPos do begin X := 0; Y := 0; end; Best Regards, Andreas On 08.01.2013 16:30, xrfang wrote: Hi, Is there "record literal in FPC? e.g. normally, you do: var cp : TPoint; cp.X := 0; cp.Y := 0; Edit1.CaretPos := cp; I would like to use literal directly, such as: Edit1.CaretPos := (X: 0, Y: 0); But the above syntax is wrong. Is there such thing exists? Thanks, Shannon -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] record literal in FPC?
Hi Adreas, I just tried, your method did not work as expected. It compiled ok, but didn't put the cursor at the end of the line as I wanted. However, assign CaretPos a new TPoint worked. Regards, 在 三, 1月 9, 2013 at 4:47 下午,Andreas Schneider 写道: Hi, you could also use the with-statement, that is pretty handy in such cases: with Edit1.CaretPos do begin X := 0; Y := 0; end; Best Regards, Andreas On 08.01.2013 16:30, xrfang wrote: Hi, Is there "record literal in FPC? e.g. normally, you do: var cp : TPoint; cp.X := 0; cp.Y := 0; Edit1.CaretPos := cp; I would like to use literal directly, such as: Edit1.CaretPos := (X: 0, Y: 0); But the above syntax is wrong. Is there such thing exists? Thanks, Shannon -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] record literal in FPC?
Well, my purpose is to make the source code look comfortable, not how the binary code is generated :) Well, again, I got a good idea from Andreas. Thanks to all of you. 在 三, 1月 9, 2013 at 7:45 下午,leledumbo 写道: > As far as I know pascal inline directive only affect the compiler, not how you write code. Could you please give an example how inline function helps in my question? Yes it does, what I mean is to create something that Point() function does and using inline directive it's nearly the same as assigning record via literal. Well, if you know how it's done by other compilers, record literal assignment is actually broken down into field by field assignment. So if you make a function that returns the record with given arguments as record fields, with inline directive the final code would be the same. Well... maybe you'll need some other directives as well, but it's just my thought. I never really compare the generated code... -- View this message in context: http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-record-literal-in-FPC-tp4028464p4028478.html Sent from the Free Pascal - Lazarus mailing list archive at Nabble.com. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] record literal in FPC?
Thanks, but what I want is to AVOID any kind of declarations. So I will use the Point() function suggested by ik. 在 三, 1月 9, 2013 at 12:26 上午,Howard Page-Clark 写道: On 08/1/13 3:30, xrfang wrote: > I would like to use literal directly, such as: > > Edit1.CaretPos := (X: 0, Y: 0); You can use a typed constant thus: const Origin: TPoint = (x:0; y:0); begin .. Edit1.CaretPos := Origin; .. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
[Lazarus] record literal in FPC?
Hi, Is there "record literal in FPC? e.g. normally, you do: var cp : TPoint; cp.X := 0; cp.Y := 0; Edit1.CaretPos := cp; I would like to use literal directly, such as: Edit1.CaretPos := (X: 0, Y: 0); But the above syntax is wrong. Is there such thing exists? Thanks, Shannon-- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Linking dynamic libraries
It's clear now. One more question, I just installed liblua5.2-0 and it linked happily, what else does the "dev" package offer for development? Thanks, Shannon 在 日, 12月 30, 2012 at 11:54 下午,Sven Barth 写道: On 30.12.2012 16:47, xrfang wrote: > Hi All, > > While I compile my program which uses liblua52.so, Lazarus refuse to > compile if it cannot find the so file. But on windows, it compile > happily without the DLL file. > > As far as I understand dynamic link libraries are only required at > runtime, why lazarus require it on compilation? First you need to understand that libraries can be dynamically linked in two ways: * at runtime * at linktime The first case is when you (or e.g. an unit) does a LoadLibrary and manually queries for each function it needs (often done by the database units provided by Lazarus). The other method is used when you have methods declared with "external Bar name Foo". Then the library name and the functions that are imported are mentioned in the import section of the resulting executable and the OS loader ensures that the libraries are loaded and initialized before the main application starts. If such a library is missing at program startup you'll get an error message. And here is where a difference between Windows and Unix systems lies (Note: your lua52 unit uses the second case): on Windows it is enough to know the library name and the function name and if the library is missing at link time this doesn't matter. On Unix though you must have the library available, because the linker needs information that is only provided inside the library file itself, because the filename is less important on Unix systems. So this is not the fault of Lazarus (or Free Pascal to be more precise, as Lazarus is only the IDE which calls FPC), but of the different concepts used on Unix. Solution: just install the dev package of your distribution and it should work. Regards, Sven -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
[Lazarus] Linking dynamic libraries
Hi All, While I compile my program which uses liblua52.so, Lazarus refuse to compile if it cannot find the so file. But on windows, it compile happily without the DLL file. As far as I understand dynamic link libraries are only required at runtime, why lazarus require it on compilation? Thanks, Shannon-- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] SEGFAULT: difference between pointer and dynarray?
Hi Sven, I think that's the library we are talking about... However, make that call to @lr[0] will NOT fix the problem, as I mentioned in previous emails. To help you see what happened, I attach the debug log (from lazarus assembly window) again. Also, it is very strange that my programs act very differently on Linux64 and Win32. On windows, even the "correct" version (which runs well on command line) will cause access violation in the IDE! Thanks! 在 日, 12月 30, 2012 at 9:34 下午,Sven Barth 写道: On 30.12.2012 05:30, leledumbo wrote: > Program received signal SIGSEGV, Segmentation fault. > 0xb7e386d2 in ?? () from /lib/i386-linux-gnu/libc.so.6 > (gdb) bt > #0 0xb7e386d2 in ?? () from /lib/i386-linux-gnu/libc.so.6 > #1 0xb7fa2d12 in ?? () from /usr/lib/i386-linux-gnu/liblua5.2.so.0 > #2 0xb7f95f09 in lua_setfield () from > /usr/lib/i386-linux-gnu/liblua5.2.so.0 > #3 0xb7fa9a9a in luaL_setfuncs () from > /usr/lib/i386-linux-gnu/liblua5.2.so.0 > #4 0x08066821 in LUAL_SETFUNCS (L=0x8071008, LR=..., highLR=1, NUP=0) at > lua52.pas:835 > #5 0x080669e4 in LUAL_NEWLIB (L=0x8071008, LR=..., highLR=1) at > lua52.pas:859 > #6 0x0804a3ea in main () at test.pas:31 > > As you can see, the pointer changes when you pass an open array into another > function expecting open array, even when static array is used (I've tried > that one too). So, somebody with enough compiler knowledge should analyze > this. Maybe you should create a bug report. If the code of that lua52.pas is the one available here: http://lua-users.org/files/wiki_insecure/lua52.pas the error is understandable if one looks at the luaL_newlib function (the array overload): === source begin === procedure luaL_newlib(L: Plua_State; lr: array of luaL_Reg); begin luaL_newlibtable(L, lr); luaL_setfuncs(L, @lr, 0); end; === source end === The address of the open array parameter is passed, not the array to the first element. If you change the luaL_setfuncs call to === source begin === luaL_setfuncs(L, @lr[0], 0); === source end === it should work... Regards, Sven -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus == CASE 1: SIGSEGV @ callq 0x4e01d8 == procedure luaL_newlib(L: Plua_State; lr: array of luaL_Reg); begin 856 luaL_newlibtable(L, lr); 857 luaL_setfuncs(L, @lr, 0); //luaL_setfuncs(L, lr, 0); 859 end; -- lua52.pas:856 luaL_newlibtable(L, lr); 4E0364 488b55e8 mov-0x18(%rbp),%rdx 4E0368 488b75f0 mov-0x10(%rbp),%rsi 4E036C 488b7df8 mov-0x8(%rbp),%rdi 4E0370 e8e3fe callq 0x4e0258 lua52.pas:857 luaL_setfuncs(L, @lr, 0); 4E0375 488b75f0 mov-0x10(%rbp),%rsi 4E0379 488b7df8 mov-0x8(%rbp),%rdi 4E037D ba mov$0x0,%edx 4E0382 e851fe callq 0x4e01d8 <-- lua52.pas:859 end; == CASE 2: SIGSEGV @ callq 0x4e01d8 == procedure luaL_newlib(L: Plua_State; lr: array of luaL_Reg); begin 856 luaL_newlibtable(L, lr); 857 luaL_setfuncs(L, @lr[0], 0); //luaL_setfuncs(L, lr, 0); 859 end; -- lua52.pas:856 luaL_newlibtable(L, lr); 4E0364 488b55e8 mov-0x18(%rbp),%rdx 4E0368 488b75f0 mov-0x10(%rbp),%rsi 4E036C 488b7df8 mov-0x8(%rbp),%rdi 4E0370 e8e3fe callq 0x4e0258 lua52.pas:857 luaL_setfuncs(L, @lr[0], 0); 4E0375 488b75f0 mov-0x10(%rbp),%rsi 4E0379 488b7df8 mov-0x8(%rbp),%rdi 4E037D ba mov$0x0,%edx 4E0382 e851fe callq 0x4e01d8 <-- lua52.pas:859 end; == CASE 3: NO ERROR == procedure luaL_newlib(L: Plua_State; lr: array of luaL_Reg); begin 856 luaL_newlibtable(L, lr); // luaL_setfuncs(L, @lr, 0); 858 luaL_setfuncs(L, lr, 0); 859 end; -- lua52.pas:856 luaL_newlibtable(L, lr); 4E0364 488b55e8 mov-0x18(%rbp),%rdx 4E0368 488b75f0 mov-0x10(%rbp),%rsi 4E036C 488b7df8 mov-0x8(%rbp),%rdi 4E0370 e8e3fe callq 0x4e0258 lua52.pas:858 luaL_setfuncs(L, lr, 0); 4E0375 488b55e8 mov-0x18(%rbp),%rdx 4E0379 488b75f0 mov-0x10(%rbp),%rsi 4E037D 488b7df8 mov-0x8(%rbp),%rdi 4E0381 b9 mov$0x0,%ecx 4E0386 e855fe callq 0x4e01e0 lua52.pas:859 end; -
Re: [Lazarus] SEGFAULT: difference between pointer and dynarray?
Hi leledumbo, Apparently, I've been wrong for all these years using Delphi :-S. I always think that open arrays are same as dynamic arrays. So, 1) from the source code of lua52.pas, how do you know the array parameter to luaL_newlib() accepts only static array but not dynamic array? If you don't read the source code or document of lua API? 2) If the api only accept static array but I passed dynamic array and hence it crashed, then it is my fault, not FPC compilers. In such case, shall I still file a bug report? 3) Finally, if I still file a bug, can I just ask the reviewer to read this mail thread as it is archived? Thanks 在 日, 12月 30, 2012 at 7:41 下午,leledumbo 写道: > 1) what's the difference between open array and dynamic array? Is "array of Integer" open or dynamic? Open array can only be declared as parameter type, it can't be declared as a variable type. When done in latter case, it will always be dynamic array. The following example will explain: type TDynIntArray = array of Integer; procedure p1(a: TDynIntArray); // here a is dynamic array procedure p2(a: array of Integer); // here a is open array a good article explaining open array: http://rvelthuis.de/articles/articles-openarr.html so "array of Integer" can mean both, depending where and how it's declared. > 2) How to report a bug, and I believe this maybe a bug in the fpc > compiler? http://wiki.lazarus.freepascal.org/How_do_I_create_a_bug_report or just go to bugs.freepascal.org, login (create account if you don't have one) and press report issue (the fields are mostly intuitive). -- View this message in context: http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-SEGFAULT-difference-between-pointer-and-dynarray-tp4028296p4028321.html Sent from the Free Pascal - Lazarus mailing list archive at Nabble.com. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] SEGFAULT: difference between pointer and dynarray?
Hi leledumbo, I have a few questions: 1) what's the difference between open array and dynamic array? Is "array of Integer" open or dynamic? 2) How to report a bug, and I believe this maybe a bug in the fpc compiler? Thanks 在 日, 12月 30, 2012 at 12:30 下午,leledumbo 写道: Sorry, I think I was too fast in reading the unit. After reading slowly, the APIs actually uses open array, not dynamic array. In this case @lib should be the same as @lib[0], but here's something interesting: I tried your code (converted as program): uses lua52; type TluaLReg = array of luaL_Reg; var LUA: Plua_State; lib : array of luaL_Reg; //lib : PluaL_Reg; i: Integer; function l_dat_upd(LUA: Plua_State): LongInt; cdecl; begin end; function l_dat_clr(LUA: Plua_State): LongInt; cdecl; begin end; begin LUA := luaL_newstate(); luaL_openlibs(LUA); SetLength(lib, 2); //SetLength(TluaLReg(lib), 2); lib[0].name := 'update'; lib[0].func := @l_dat_upd; lib[1].name := 'clear'; lib[1].func := @l_dat_clr; writeln('actual = $'+HexStr(ptruint(@lib),8)); luaL_newlib(LUA, lib); lua_setglobal(LUA, 'data'); lua_close(LUA); end. inserting some writelns in lua52 unit near problematic functions and running in gdb results in: luaL_newlib oa = $BFFFEE30 luaL_setfuncs oa = $BFFFECC0 Program received signal SIGSEGV, Segmentation fault. 0xb7e386d2 in ?? () from /lib/i386-linux-gnu/libc.so.6 (gdb) bt #0 0xb7e386d2 in ?? () from /lib/i386-linux-gnu/libc.so.6 #1 0xb7fa2d12 in ?? () from /usr/lib/i386-linux-gnu/liblua5.2.so.0 #2 0xb7f95f09 in lua_setfield () from /usr/lib/i386-linux-gnu/liblua5.2.so.0 #3 0xb7fa9a9a in luaL_setfuncs () from /usr/lib/i386-linux-gnu/liblua5.2.so.0 #4 0x08066821 in LUAL_SETFUNCS (L=0x8071008, LR=..., highLR=1, NUP=0) at lua52.pas:835 #5 0x080669e4 in LUAL_NEWLIB (L=0x8071008, LR=..., highLR=1) at lua52.pas:859 #6 0x0804a3ea in main () at test.pas:31 As you can see, the pointer changes when you pass an open array into another function expecting open array, even when static array is used (I've tried that one too). So, somebody with enough compiler knowledge should analyze this. Maybe you should create a bug report. -- View this message in context: http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-SEGFAULT-difference-between-pointer-and-dynarray-tp4028296p4028316.html Sent from the Free Pascal - Lazarus mailing list archive at Nabble.com. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] SEGFAULT: difference between pointer and dynarray?
The end of array mark is added by lua52.pas, if you read the source code... My problem is solved if I remove the overloaded luaL_newlib function and use only the original pointer version, i.e. var lib: array of luaL_Reg; luaL_newlib(L, PluaL_Reg(lib)); It seems that while converting from dynamic array to pointer, the compiler knows to point to the first element of the array, not the structure. Could anyone confirm this behavior? The remaining problems are: 1) why the lupas program works well even with the problematic overloaded version? I tested on Windows 7 (32bit), both programs failed. 2) I will email the author of lua52.pas to investigate the overloaded functions, and personally I will suggest to not use overloading at all. Shannon 在 六, 12月 29, 2012 at 9:39 下午,leledumbo 写道: Reading luaL_newlib documentation and lua52.pas implementation of it (it's a macro in the original C code), I see that you need a sentinel value to mark the end of the array by putting nil in the name part. I was already skeptic since the API doesn't mention the number of elements in the array as commonly required by a C function. -- View this message in context: http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-SEGFAULT-difference-between-pointer-and-dynarray-tp4028296p4028310.html Sent from the Free Pascal - Lazarus mailing list archive at Nabble.com. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] SEGFAULT: difference between pointer and dynarray?
PluaL_Reg is defined by lua52.pas. In the email I omitted irrelevant code, but full source is attached in the first email. 在 六, 12月 29, 2012 at 3:13 下午,Flávio Etrusco 写道: Your code sample doesn't have a declaration for PluaL_Reg (and you don't use the TluaLReg type). Was it a simple copy'n'paste error or is it declared by the Lua wrapper? On Sat, Dec 29, 2012 at 4:00 AM, xrfang wrote: > Sorry, we are talking about same thing. In my program I am using dynamic > array, NOT static, but the assembly is same. In leledumbo's example, the > assembly is differnt. > > 在 六, 12月 29, 2012 at 2:55 下午,Hans-Peter Diettrich 写道: > > leledumbo schrieb: >>> The Assembler shows that @lib and @lib[0] are exactly same thing. > > That's true for static arrays. > >> The following program shows that they are NOT the same > > That's true for dynamic (managed) arrays. > > You're talking about different array types. > > DoDi > > > -- > ___ > Lazarus mailing list > Lazarus@lists.lazarus.freepascal.org > http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus > > > > -- > ___ > Lazarus mailing list > Lazarus@lists.lazarus.freepascal.org > http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus > -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] SEGFAULT: difference between pointer and dynarray?
Sorry, we are talking about same thing. In my program I am using dynamic array, NOT static, but the assembly is same. In leledumbo's example, the assembly is differnt. 在 六, 12月 29, 2012 at 2:55 下午,Hans-Peter Diettrich 写道: leledumbo schrieb: >> The Assembler shows that @lib and @lib[0] are exactly same thing. That's true for static arrays. > The following program shows that they are NOT the same That's true for dynamic (managed) arrays. You're talking about different array types. DoDi -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] SEGFAULT: difference between pointer and dynarray?
Hi leledumbo, You are right that they are not same: begin setlength(a1,1); a1[0] := 12345; getvalue(@a1); getvalue(@a1[0]); end. The assembly code for the 2 getvalue() are: project1.lpr:14 getvalue(@a1); 0040022F 48bf40a26200 movabs $0x62a240,%rdi 00400239 e862ff callq 0x4001a0 project1.lpr:15 getvalue(@a1[0]); 0040023E 488b3c2540a26200 mov 0x62a240,%rdi 00400246 e855ff callq 0x4001a0 One used movabs, and the other use mov. But why the generated assembly in my code are same? Shannon 在 六, 12月 29, 2012 at 1:26 下午,leledumbo 写道: > The Assembler shows that @lib and @lib[0] are exactly same thing. The following program shows that they are NOT the same #!/usr/bin/instantfpc var a1: array of Integer; begin setlength(a1,1); writeln(ptruint(@a1)); writeln(ptruint(@a1[0])); end. output: $ chmod +x test.pas $ ./test.pas 134651632 3077795880 -- View this message in context: http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-SEGFAULT-difference-between-pointer-and-dynarray-tp4028296p4028303.html Sent from the Free Pascal - Lazarus mailing list archive at Nabble.com. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] SEGFAULT: difference between pointer and dynarray?
Please see attached log file I copied from the assembler window. I am yet to test this on windows. Thanks, Shannon 在 六, 12月 29, 2012 at 1:26 下午,leledumbo 写道: > The Assembler shows that @lib and @lib[0] are exactly same thing. The following program shows that they are NOT the same #!/usr/bin/instantfpc var a1: array of Integer; begin setlength(a1,1); writeln(ptruint(@a1)); writeln(ptruint(@a1[0])); end. output: $ chmod +x test.pas $ ./test.pas 134651632 3077795880 -- View this message in context: http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-SEGFAULT-difference-between-pointer-and-dynarray-tp4028296p4028303.html Sent from the Free Pascal - Lazarus mailing list archive at Nabble.com. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus == CASE 1: SIGSEGV @ callq 0x4e01d8 == procedure luaL_newlib(L: Plua_State; lr: array of luaL_Reg); begin 856 luaL_newlibtable(L, lr); 857 luaL_setfuncs(L, @lr, 0); //luaL_setfuncs(L, lr, 0); 859 end; -- lua52.pas:856 luaL_newlibtable(L, lr); 4E0364 488b55e8 mov-0x18(%rbp),%rdx 4E0368 488b75f0 mov-0x10(%rbp),%rsi 4E036C 488b7df8 mov-0x8(%rbp),%rdi 4E0370 e8e3fe callq 0x4e0258 lua52.pas:857 luaL_setfuncs(L, @lr, 0); 4E0375 488b75f0 mov-0x10(%rbp),%rsi 4E0379 488b7df8 mov-0x8(%rbp),%rdi 4E037D ba mov$0x0,%edx 4E0382 e851fe callq 0x4e01d8 <-- lua52.pas:859 end; == CASE 2: SIGSEGV @ callq 0x4e01d8 == procedure luaL_newlib(L: Plua_State; lr: array of luaL_Reg); begin 856 luaL_newlibtable(L, lr); 857 luaL_setfuncs(L, @lr[0], 0); //luaL_setfuncs(L, lr, 0); 859 end; -- lua52.pas:856 luaL_newlibtable(L, lr); 4E0364 488b55e8 mov-0x18(%rbp),%rdx 4E0368 488b75f0 mov-0x10(%rbp),%rsi 4E036C 488b7df8 mov-0x8(%rbp),%rdi 4E0370 e8e3fe callq 0x4e0258 lua52.pas:857 luaL_setfuncs(L, @lr[0], 0); 4E0375 488b75f0 mov-0x10(%rbp),%rsi 4E0379 488b7df8 mov-0x8(%rbp),%rdi 4E037D ba mov$0x0,%edx 4E0382 e851fe callq 0x4e01d8 <-- lua52.pas:859 end; == CASE 3: NO ERROR == procedure luaL_newlib(L: Plua_State; lr: array of luaL_Reg); begin 856 luaL_newlibtable(L, lr); // luaL_setfuncs(L, @lr, 0); 858 luaL_setfuncs(L, lr, 0); 859 end; -- lua52.pas:856 luaL_newlibtable(L, lr); 4E0364 488b55e8 mov-0x18(%rbp),%rdx 4E0368 488b75f0 mov-0x10(%rbp),%rsi 4E036C 488b7df8 mov-0x8(%rbp),%rdi 4E0370 e8e3fe callq 0x4e0258 lua52.pas:858 luaL_setfuncs(L, lr, 0); 4E0375 488b55e8 mov-0x18(%rbp),%rdx 4E0379 488b75f0 mov-0x10(%rbp),%rsi 4E037D 488b7df8 mov-0x8(%rbp),%rdi 4E0381 b9 mov$0x0,%ecx 4E0386 e855fe callq 0x4e01e0 lua52.pas:859 end; -- 830 procedure luaL_setfuncs(L: Plua_State; lr: PluaL_Reg; nup: Integer); cdecl; external LUA_LIB_NAME; procedure luaL_setfuncs(L: Plua_State; lr: array of luaL_Reg; nup: Integer); begin 834 luaL_setfuncs(L, @lr, nup); 835 end; -- lua52.pas:834 luaL_setfuncs(L, @lr, nup); 4E022F 488b75f0 mov-0x10(%rbp),%rsi 4E0233 8b55e8 mov-0x18(%rbp),%edx 4E0236 488b7df8 mov-0x8(%rbp),%rdi 4E023A e899ff callq 0x4e01d8 lua52.pas:835 end; == -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] SEGFAULT: difference between pointer and dynarray?
The Assembler shows that @lib and @lib[0] are exactly same thing. The problem is in lua52.pas, which I am still tracing. Now the most strange thing is why one of my two programs caused SIGSEGV while another one using same code block does not? Is it because one of them is gui program and the other is cli? I will post a debug report of assembly call points for these 2 programs on both Linux-64 and Win-32 platforms. Thanks, Shannon 在 六, 12月 29, 2012 at 12:26 上午,leledumbo 写道: Pointer and dynamic array are not the same, even though dynamic array is built on top of pointer (to a structure). When you pass a dynamic array variable, you're passing pointer TO THE STRUCTURE, NOT THE DATA. To correctly do it, you have to pass pointer to the first data, which is @lib[0] in your case. -- View this message in context: http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-SEGFAULT-difference-between-pointer-and-dynarray-tp4028296p4028297.html Sent from the Free Pascal - Lazarus mailing list archive at Nabble.com. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
[Lazarus] SEGFAULT: difference between pointer and dynarray?
Hi All, I encountered a strange problem with lua integration. Following is the problematic part (full source attached): type TluaLReg = array of luaL_Reg; var LUA: Plua_State; lib : array of luaL_Reg; //lib : PluaL_Reg; i: Integer; implementation //omitted, see attached source... initialization LUA := luaL_newstate(); luaL_openlibs(LUA); SetLength(lib, 2); //SetLength(TluaLReg(lib), 2); lib[0].name := 'update'; lib[0].func := @l_dat_upd; lib[1].name := 'clear'; lib[1].func := @l_dat_clr; luaL_newlib(LUA, lib); <--Access Violation Here lua_setglobal(LUA, 'data'); finalization lua_close(LUA); end. The above code caused access violation, unless I use the commented blue code to replace the red code. I wonder what's the difference between PluaL_Reg and array of luaL_Reg?? What's more strange is that the same code is OK after I copied it to a separate console mode application. In the attached archive, there are both the problematic project and the OK project. In LUA manual about luaL_newlib(), it said, the 2nd parameter (lib) must be an array not pointer to an array. I am confused what happened here and further more, what's the underlying structure of a normal array in FP (If I am correct, dynamic array is same as pointer, at least that's what I learned in Delphi). My environment is 64 bit Linux 3.5.0 (Mint 14). Thanks a lot. Sincerely, Shannon luaintf.tar.gz Description: application/compressed-tar -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Traverse a TFPDataHashTable
Cool, btw, what is the release plan for 2.6.2 and 2.6.4 ? 在 五, 12月 28, 2012 at 7:36 下午,Sven Barth 写道: On 28.12.2012 12:22, xrfang wrote: > Hi, > > How can I traverse a TFPDataHashTable? The ForEachCall method is > protected. Do I have to write a sub-class to expose this method? > > The requirement is that I use it to organize a bunch of objects, and > need to free the memory of these objects. Around two weeks ago a public call "Iterate" was added to "TFPDataHashTable" in trunk. If you use 2.6.0 or the to-be-released 2.6.2 you'll need to either sub-class the type or use a class helper... Regards, Sven -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
[Lazarus] Traverse a TFPDataHashTable
Hi, How can I traverse a TFPDataHashTable? The ForEachCall method is protected. Do I have to write a sub-class to expose this method? The requirement is that I use it to organize a bunch of objects, and need to free the memory of these objects. Thanks, Shannon-- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Is it possible to detect type in a generic class
Thanks a lot for the code sample. TypeInfo will be useful, but for now I give up this route, because I hope it to be more "elastic" by providing an Append() method if T is an array of something, otherwise no Append() method, this seems can only be achieved by inheritance instead of generics. 在 五, 12月 28, 2012 at 7:11 下午,Sven Barth 写道: On 28.12.2012 00:58, xrfang wrote: > Hi, > > Suppose I have a generic class like this: > > type > TSerie = generic class > public > procedure Append(value: T); > end It should be "generic TSerie = class". > > then, in the Append procedure can I do something like: > > case *typeof*(T) of > integer: // do something with integer > string: // do someting with string > ... ... > end; Don't use "TypeOf". The function you are looking for is called "TypeInfo" and works with every type, except Enums with jumps (e.g. TTestEnum = (teOne := 1, teTwo := 5)). Here you have an example: === source begin === program tgentypes; {$mode objfpc} uses typinfo; type generic TTest = class class procedure DoSomething(aArg: T); end; { TTestClass } class procedure TTest.DoSomething(aArg: T); var ti: PTypeInfo; begin ti := TypeInfo(aArg); case ti^.Kind of tkInteger: Writeln('Type is an integer'); tkAString: Writeln('Type is an AnsiString'); tkUString: Writeln('Type is a UnicodeString'); tkBool: Writeln('Type is a Boolean'); tkEnumeration: Writeln('Type is an enumeration'); tkSString: Writeln('Type is a ShortString'); tkClass: Writeln('Type is a class'); tkObject: Writeln('Type is an object'); else Writeln('Unhandled type: ', ti^.Kind); end; end; type TTestEnum = (teOne, teTwo, teThree); TTestObject = object end; TTestLongInt = specialize TTest; TTestAnsiString = specialize TTest; TTestUnicodeString = specialize TTest; TTestShortString = specialize TTest; TTestBoolean = specialize TTest; TTestTTestEnum = specialize TTest; TTestTObject = specialize TTest; TTestTTestObject = specialize TTest; var obj: TObject; testobj: TTestObject; begin TTestLongInt.DoSomething(42); TTestAnsiString.DoSomething('Hello World'); TTestUnicodeString.DoSomething('Hello World'); TTestShortString.DoSomething('Hello World'); TTestBoolean.DoSomething(True); TTestTTestEnum.DoSomething(teOne); TTestTObject.DoSomething(obj); TTestTTestObject.DoSomething(testobj); end. === source end === For getting the exact value of the argument you need to rely on the information provided by the RTTI as you can't use e.g. "IntToStr(aArg)" in case of an integer as you'll get a compiler error when you specialize the class with something that is not an Integer. Regards, Sven -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
[Lazarus] Is it possible to detect type in a generic class
Hi, Suppose I have a generic class like this: type TSerie = generic class public procedure Append(value: T); end then, in the Append procedure can I do something like: case typeof(T) of integer: // do something with integer string: // do someting with string ... ... end; Thanks! Shannon-- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus