Gist of the Day: Some convenience macros for use with Perl C internals

I feel awful. Like, really awful. The baby is sick, my partner is sick, I am sick. You still want something neat though, so I’m going to show you something very simple that I’ve used for a while.
As I’m sure you noticed in yesterday’s Inline::C demo, Perl guts and C API are pretty noisy with a lot of boiler-plate. For this reason, when I first started playing with Perl guts and API, I created a header file just to make things a little simpler. Nothing here is terribly complicated, and they’re all just simple convenience macros, but sometimes that type of macro saves you oodles of time.

The Code

The macros:

  • SV_STRING() – Makes a C string into a scalar value
  • SV_CARRAY() – Makes a scalar value from a C character array (which is only different from a C string insomuch as there is not necessarily a at the end
  • SV_UINT() – Makes an unsigned int into a scalar value
  • SV_INT() – Makes a signed int into a scalar value
  • SV_DECIMAL() – Makes a decimal number (incl. float or double) into a scalar value
  • SV_UNDEF_VAL – A scalar value containing undef
  • SV_UNDEF_REF – An undefined reference
  • HASH_STORE_UINT() – Store an unsigned int into a hash reference
  • HASH_STORE_INT() – Store a signed int into a hash reference
  • HASH_STORE_DECIMAL() – Store a decimal value (float or double) into a hash reference
  • HASH_STORE_STRING() – Store a string into a hash reference
  • HASH_STORE_CARRAY() – Put a char array into a hash reference
  • HASH_STORE_SV() – Store a scalar value in a hash reference
  • HASH_FETCH_SCALAR() – Fetch a scalar value from a hash reference using the key
  • PUSH() – Push a value onto an array reference
  • SHIFT() – Shift a value off of an array reference
  • MAKEREF() – Create a SV* which is a reference to some other value (SV*, AV*, and HV* work)
  • MAKEREF_NOINC() – Make a reference with and don’t increment the reference counter (use when you’re already doing something that does this)
  • DR_HASHREF() – Dereference a reference to some other value (SV*, AV*, or HV*)
  • SV_RETAIN() – Increment the reference counter
  • SV_RELEASE() – Decrement the reference counter
  • SvGET_CSTR_FROM_HV() – Get a C string (a char array which is null-terminated)

Note that there is a difference between SV_UNDEF_VAL and SV_UNDEF_REF. The SV_UNDEF_VAL is for when you want $foo = undef, and SV_UNDEF_REF is when you want return undef. The difference is that essentially where the value is stored. SV_UNDEF_REF is a literal undef whereas SV_UNDEF_VAL is the value of undef stored in a variable. The main reason you would choose SV_UNDEF_VAL over an SV_UNDEF_REF is because you want an SV* which you can then modify the value of. You cannot/should-not modify SV_UNDEF_REF and you will most likely experience a memory fault crash if you try.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.