A few things. The best way to know what CMOD does is to examine the
generated .c file and find the macros generated there.
The "THIS" macro is defined within each PIKECLASS block to cast the
storage-pointer of the "this" object to the struct defining the member
variables. That is why you can use -> references in c.
However, on the c-level, all object-type PIKEVARs are defined struct
*object.
> And want to use it in the next class:
>
> PIKECLASS Control {
> INHERIT HostApiInfo;
> PIKEVAR HostApiInfo Info;
This does work, and will be a struct *object. To access members in this
object from within this class, you must use the OBJ2_HOSTAPIINFO macro,
which casts an object into the struct you want.
> PIKEFUN HostApiInfo get_host_api_info(int hostApi) {
> const PaHostApiInfo * info;
> info = Pa_GetHostApiInfo(hostApi);
> THIS->Info->structVersion = info->structVersion;
This should be OBJ2_HOSTAPINFO(THIS->Info)->structVersion =
info->structVersion.
> [...]
> RETURN(THIS->Info);
> }
> But it doesn't work that way. At least the HostApiInfo class was
> recognised as a PIKEVAR, but when i use the structVersion function the
> compiler complains:
>
> error: ‘struct object’ has no member named ‘structVersion’
>
> I know, the structure is not initialized. But where and how to do
> that? I tried something like
> THIS->Info = HostApiInfo();
This would be:
THIS->Info = low_clone(HostApiInfo_program);
call_c_initalizers(THIS->Info);
But because of INHERIT pike will make a new HostApiInfo object
automatically everytime a new Control object is made. The way to access
it is to use the get_storage(struct object*, struct program*) function.
Try something like this:
#define THISOBJ Pike_fp->current_object;
PIKECLASS HostApiInfo {
/* ... */
}
#define SUPER_HOSTAPIINFO(o) ( ((struct HostApiInfo_struct *)
get_storage((o), HostApiInfo_program)) )
PIKECLASS Control {
INHERIT HostApiInfo;
PIKEFUN int set_version(int version) {
RETURN (SUPER_HOSTAPIINFO(THISOBJ)->structVersion = version);
}
}
(I might have missed a bracket or two and it be slightly wrong but the
that's the basics)
When you use reference types such as objects and strings in CMOD, you
must initalize them, otherwise they will blow up in pike:
PIKECLASS HostApiInfo {
PIKEVAR string name;
INIT{
THIS->name = NULL;
}
EXIT{
if (THIS->name != NULL) free_string(THIS->name);
}
}
You should use a pike compiled with the "--with-checker" option.
Otherwise you won't see your memory problems.
|