Steve Hay <[EMAIL PROTECTED]> writes: >Nick Ing-Simmons wrote: >>If you use the MAGIC * as the "signature" it can't fail ;-) >> >An excellent idea. > >So attached is hopefully my final take.
Which looks fine - I see there is another mail though so will study that. > >Using sv_magic(), I've dropped the re-use of the SV in the 2nd arg since >(a) I couldn't pull that trick if I actually wanted to use mg_obj for >something else and (b) the subsequent mg_find() call is always >_immediately_ after sv_magic() anyway so no other magic could have been >added. the MAGIC * is then stored within the struct itself. Later on >(and possibly in another part of the code, when mg_find() wouldn't be >"safe"), the pointer stored with the struct is used to verify that the >correct MAGIC * was found. > >Using sv_magicext() is even easier since it returns the MAGIC * for us. > >Thanks (once again!) for your help. > >- Steve > > >------------------------------------------------ >Radan Computational Ltd. > >The information contained in this message and any files transmitted with it are >confidential and intended for the addressee(s) only. If you have received this >message in error or there are any problems, please notify the sender immediately. >The unauthorized use, disclosure, copying or alteration of this message is strictly >forbidden. Note that any views or opinions presented in this email are solely those >of the author and do not necessarily represent those of Radan Computational Ltd. The >recipient(s) of this message should check it and any attached files for viruses: >Radan Computational will accept no liability for any damage caused by any virus >transmitted by this email. >#include "EXTERN.h" >#include "perl.h" >#include "XSUB.h" > >#include "ppport.h" > >typedef struct { > MAGIC *mg; > char *buf; >} Foo; > >static Foo *FooAlloc(pTHX); >static void FooFree(pTHX_ Foo *foo); >static int MagicFooFree(pTHX_ SV *sv, MAGIC *mg); > >static MGVTBL Foo_vtbl = { > NULL, > NULL, > NULL, > NULL, > MagicFooFree >}; > >static Foo *FooAlloc(pTHX) { > Foo *foo; > Newz(0, foo, 1, Foo); > Newz(0, foo->buf, 1024, char); > strcpy(foo->buf, "Hello, world."); > return foo; >} > >static void FooFree(pTHX_ Foo *foo) { > Safefree(foo->buf); > Safefree(foo); >} > >static int MagicFooFree(pTHX_ SV *sv, MAGIC *mg) { > FooFree(aTHX_ (Foo *)mg->mg_ptr); > return 1; >} > >MODULE = Foo PACKAGE = Foo > >void >magicfoo() >PPCODE: >{ > SV *sv; > Foo *foo; > MAGIC *mg; > // Initialise > foo = FooAlloc(aTHX); > sv = NEWSV(0, 0); > sv_magic(sv, NULL, PERL_MAGIC_ext, (char *)foo, 0); > // This mg_find() can't fail since we're doing it straight away. > if (!(mg = mg_find(sv, PERL_MAGIC_ext))) > croak("Can't find new magic"); > foo->mg = mg; > mg->mg_virtual = &Foo_vtbl; > SvREADONLY_on(sv); > // Use it. This could be much later in another function, so we > // need to check that mg_find() found the right magic. > if (!(mg = mg_find(sv, PERL_MAGIC_ext))) > croak("Can't find magic"); > if (!(foo = (Foo *)(mg->mg_ptr))) > croak("Can't find magic pointer"); > if (foo->mg != mg) > croak("Found wrong magic pointer"); > //printf("%s\n", foo->buf); > // Clean up > SvREFCNT_dec(sv); >} > >void >magicextfoo() >PPCODE: >{ > SV *sv; > Foo *foo; > MAGIC *mg; > // Initialise > foo = FooAlloc(aTHX); > sv = NEWSV(0, 0); > if (!(mg = sv_magicext(sv, NULL, PERL_MAGIC_ext, &Foo_vtbl, (char *)foo, 0))) > croak("Can't add magic"); > foo->mg = mg; > SvREADONLY_on(sv); > // Use it. This could be much later in another function, so we > // need to check that mg_find() found the right magic. > if (!(mg = mg_find(sv, PERL_MAGIC_ext))) > croak("Can't find magic"); > if (!(foo = (Foo *)(mg->mg_ptr))) > croak("Can't find magic pointer"); > if (foo->mg != mg) > croak("Found wrong magic pointer"); > //printf("%s\n", foo->buf); > // Clean up > SvREFCNT_dec(sv); >}