Re: [fpc-pascal] how to use procedure of object in C
Xiangrong Fang wrote: However, like in my first mail, if I define THandler a procedure of object, it makes easier to SetHandler(AMethod); but how can I use that procedure of object pointer in the so? It works the same, cast the data you receive to a TMethod and call the code member with the appropriate parameters. So, in the C library do this: typedef struct { Data: Pointer; Code: Pointer; }TMethod; void SetHandler(TMethod h); { StoredH = h; } typedef void (*TDataHandler)(void* Self, void* Data); void DoSomething(); { ((TDataHandler)(StoredH.Code))(StoredH.Data, SomeData); } Warning, this is pseudo code, you should adapt it so that it can compile. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] how to use procedure of object in C
On 10 Mar 2015, at 10:40, OBones wrote: Xiangrong Fang wrote: However, like in my first mail, if I define THandler a procedure of object, it makes easier to SetHandler(AMethod); but how can I use that procedure of object pointer in the so? It works the same, cast the data you receive to a TMethod and call the code member with the appropriate parameters. So, in the C library do this: Note that you have to make sure that you declare your procedure of object as cdecl in that case, and as a result you'll also have to declare all methods that you want to assign to this procvar as cdecl. Jonas ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] how to use procedure of object in C
On 03/09/2015 04:20 PM, Xiangrong Fang wrote: can I implement SetHandler in a library written in C, then call h in C? For inter-language calls you obviously need to to define the calling style on both sites. e.g. STDCALL or PASCAL, to make both use compatible calling conventions. I don't know if/how such keywords exist for procedure of object style of functions (and hence for the types of the variables pointers to them are stored in). If not you should use a flat calling scheme: on both sites use standard (non-object) functions with e.g. STDCALL (adding/extracting the Self pointer explicitly on the way, if appropriate). Regarding variables for holding (pointers to) such functions they need to be a record of a (flat) function pointer plus a Self pointer. This said, you can't (easily) pass objects to a C library, anyway, as the memory management is not synchronized by default. Like with Pascal Strings, a e.g. Free will lead into chaos. -Michael ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] how to use procedure of object in C
On 09 Mar 2015, at 18:43, Michael Van Canneyt wrote: You must be sure that self is passed in the correct register. I am not sure this is the case if you declare it as an extra argument. It is, as long as the `self` is the first parameter. Same goes for `Class Procedure XXX;` kind of declarations (in constrast to `Class procedure XXX; static;`). I don't know how long that is going to last however (since this hidden parameter thingy is an implementation detail of the compiler I think). So I fully agree: it would be a kindness of the compiler people to confirm this :-) -- Ewald ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] how to use procedure of object in C
On Mon, 9 Mar 2015, OBones wrote: Michael Van Canneyt wrote: On Mon, 9 Mar 2015, Xiangrong Fang wrote: Hi all, I define a procedure like this: type TDataHandler = procedure(data: Pointer) of object; procedure SetHandler(h: TDataHandler); external cdecl; Now, can I implement SetHandler in a library written in C, then call h in C? IMHO Not without separate assembler code for each CPU. Michael. How about using TMethod? procedure DataHandler(DummySelf: Pointer; data: Pointer); begin // do what you want to do, DummySelf is always nil. end; var Method: TMethod; begin Method.Data := nil; Method.Code := @DataHandler; SetHandler(TDataHandler(Method)); end; You must be sure that self is passed in the correct register. I am not sure this is the case if you declare it as an extra argument. It may be so, but compiler people should confirm this. I don't think you can take it for granted. Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] how to use procedure of object in C
On Mon, 9 Mar 2015, Xiangrong Fang wrote: Hi all, I define a procedure like this: type TDataHandler = procedure(data: Pointer) of object; procedure SetHandler(h: TDataHandler); external cdecl; Now, can I implement SetHandler in a library written in C, then call h in C? IMHO Not without separate assembler code for each CPU. Michael.___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] how to use procedure of object in C
Michael Van Canneyt wrote: On Mon, 9 Mar 2015, Xiangrong Fang wrote: Hi all, I define a procedure like this: type TDataHandler = procedure(data: Pointer) of object; procedure SetHandler(h: TDataHandler); external cdecl; Now, can I implement SetHandler in a library written in C, then call h in C? IMHO Not without separate assembler code for each CPU. Michael. How about using TMethod? procedure DataHandler(DummySelf: Pointer; data: Pointer); begin // do what you want to do, DummySelf is always nil. end; var Method: TMethod; begin Method.Data := nil; Method.Code := @DataHandler; SetHandler(TDataHandler(Method)); end; ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] how to use procedure of object in C
2015-03-10 0:33 GMT+08:00 OBones obo...@free.fr: How about using TMethod? procedure DataHandler(DummySelf: Pointer; data: Pointer); begin // do what you want to do, DummySelf is always nil. end; var Method: TMethod; begin Method.Data := nil; Method.Code := @DataHandler; SetHandler(TDataHandler(Method)); end; I'm not sure how this works, but it seems that you are deliberately converting a normal procedure to a method. What I want is exactly opposite - I want to convert a method to a normal procedure. If I define the interfact of DataHandler like this: TDataHandler = procedure(data: Pointer); cdecl; It is very easy to use in an so, no matter it is written in C or pascal. But the problem is, I want to do this: SetHandler(h); where h is a METHOD, not a normal procedure. Because I want to use the handler wrapped in my Class. However, like in my first mail, if I define THandler a procedure of object, it makes easier to SetHandler(AMethod); but how can I use that procedure of object pointer in the so? Thanks! ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal