TYPEMAP
char *  T_PV
char    T_CHAR

// https://perldoc.perl.org/perlxs#Returning-SVs,-AVs-and-HVs-through-RETVAL
AV    * T_AVREF_REFCOUNT_FIXED

Dyncall   * T_PTROBJ_SPECIAL
DynXSub   * T_PTROBJ_SPECIAL
Call      * T_DYN

DCvoid      void
DCCallVM  * T_PTROBJ_SPECIAL
DCsize      T_INT
DCsize    * T_INTPTR
DCshort     T_SHORT
DCint       T_INT
DCbool      T_BOOL
DCchar      T_CHAR
DClong      T_LONG
DClonglong  LONG_LONG_INT
DCfloat     T_FLOAT
DCdouble    T_DOUBLE
DCpointer * T_PTROBJ_SPECIAL
DCpointer   T_PTROBJ_SPECIAL

DCaggr  *       T_PTROBJ_AGGREGATE
const DCaggr  * T_PTROBJ_AGGREGATE
DCsigchar * T_PV
const DCsigchar * T_PV
DCsigchar T_CHAR
const DCsigchar T_CHAR
DLLib     * T_PTROBJ_SPECIAL
DLSyms    * T_PTRREF
DCValue   * T_PTRREF
DCValue     T_PTRREF
DCfield   * T_PTRREF
DCArgs    * T_PTRREF

DCCallback * T_PTROBJ_SPECIAL
DCCallbackHandler * T_PTRREF

INPUT
T_PV
  $var = ($type)SvPV_nolen($arg)

LONG_LONG_INT
  $var = ($type)SvIV($arg);

T_PTROBJ_SPECIAL
  // $Package | $type | $ntype
  if (sv_derived_from($arg, \"Dyn::${
        (my $ntt=$ntype)=~s/_+/::/g;
        $ntt=~s[Ptr$][];
        $ntt=~s[^DCpointer][Call::Pointer];
        $ntt=~s[^DCCallback][Callback];
        $ntt=~s[^DCCallVM][Call];
        $ntt=~s[^DCC][Callback::];
        $ntt=~s[^DC][Call::];
        $ntt=~s[^DL][Load::];
        \$ntt
        }\")){
    IV tmp = SvIV((SV*)SvRV($arg));
    $var = INT2PTR($type, tmp);
  }
  else
    croak(\"$var is not of type Dyn::${
        (my $ntt=$ntype)=~s/_+/::/g;
        $ntt=~s[Ptr$][];
        $ntt=~s[^DCpointer][Call::Pointer];
        $ntt=~s[^DCCallback][Callback];
        $ntt=~s[^DCCallVM][Call];
        $ntt=~s[^DCC][Callback::];
        $ntt=~s[^DC][Call::];
        $ntt=~s[^DL][Load::];
        \$ntt
        }\");

T_PTROBJ_AGGREGATE
  // $Package | $type | $ntype
  if (sv_derived_from($arg, \"Dyn::Call::Aggregate\")){
    IV tmp = SvIV((SV*)SvRV($arg));
    $var = INT2PTR($type, tmp);
  }
  else
    croak(\"$var is not of type Dyn::Call::Aggregate\");

T_DYN
  if (sv_derived_from($arg, \"Dyn\")) {
    IV tmp = SvIV((SV*)SvRV($arg));
    $var = INT2PTR($type, tmp);
  }
  else
    croak(\"$var is not of type Dyn\");

OUTPUT
T_PV
  sv_setpv((SV*)$arg, $var);

LONG_LONG_INT
  sv_setiv($arg, (IV)$var);

T_PTROBJ_SPECIAL
  // $Package | $type | $ntype
  sv_setref_pv($arg,
    \"Dyn::${
        (my $ntt=$ntype)=~s/_+/::/g;
        $ntt=~s[Ptr$][];
        $ntt=~s[^DCpointer][Call::Pointer];
        $ntt=~s[^DCCallback][Callback];
        $ntt=~s[^DCCallVM][Call];
        $ntt=~s[^DCC][Callback::];
        $ntt=~s[^DC][Call::];
        $ntt=~s[^DL][Load::];
        \$ntt
        }\", (void*)$var);

T_PTROBJ_AGGREGATE
  // $Package | $type | $ntype
  sv_setref_pv($arg, \"Dyn::Call::Aggregate\", (void*)$var);

T_DYN
  sv_setref_pv($arg, \"Dyn\", (void*)$var);