Quantcast
Channel: windows deep internals
Viewing all articles
Browse latest Browse all 264

binding c++ objects to perl

$
0
0

Sure there are lots of ways to do this (as usually in Perl: "there's more than one way to do it"), just to name few:

  • swig - result looks not native and clumsy, also you need to make facade-like interfaces for really complex classes
  • ffi - also has problems with complex classes
  • XS - official and wide-spread way. Btw smoothest and most seamless Win32::OLE module uses it exactly

and besides you can simple call perl functions directly from c++ code (with all bells and whistles "dSP; ENTER; SAVETMPS" etc) like polymake do

So this article is just remaining for myself how to bind small-sized c++ classes to perl using XS. Lets begin with simplest one - just perl wrapper around Interval-Tree

  • to create new skeleton: h2xs -cfn Module::Name
  • patch Makefile.PL to add XSOPT="-C++" and change C compiler CC="g++", also highly likely we should add -lstdc++ to LIBS
  • don't forget to add all source/header files to MANIFEST

Code is simple, I prefer to make my own MAGIC instead of implementation DESTROY method - you will see further why

 

Next module is more complex bcs I want to have native tied arrays for stuff like sections/segments/symbols/relocs etc to make possible things like
my $e = Elf::Reader->new($ARGV[0]);

my $syms = $e->syms($sec);
foreach ( @$syms ) { ...

To achieve this we need to make our new magic. However there is problem - I have my own COM-like reference counting and want to have custom destructor in MAGIC table, so type PERL_MAGIC_tied doesn't fit. On other hand method FETCHSIZE called from Perl_magic_sizepack which is PERL_MAGIC_tied->length. Ok, we can implement our own length method for each magic table. Then magic tables sets up like:
sv_magicext((SV*)AV_var, NULL, PERL_MAGIC_tied, &magic_vtab, (const char *)object, 0);
and we can implement only FETCH method for each iterator

Last module is wrapper around mips disassembler library - nothing special except it must be dynamically linked with described above native module. This is little bit tricky - we must pass several arguments to linker

  1. module name - bcs it don't starts with lib prefix we must use dirty hack: -l:module_name
  2. path to module for -L - you can extract it from Config as $Config{'sitearch'}
  3. and finally peek -Wl,--as-needed

Now my module can be loaded from perl. ldd shows:
    linux-vdso.so.1 (0x00007ffec81db000)
    Reader.so => /usr/local/lib/x86_64-linux-gnu/perl/5.30.0/auto/Elf/Reader/Reader.so (0x00007f2b9f036000)
    libstdc++.so.6 => /usr/local/lib64/libstdc++.so.6 (0x00007f2b9ee0c000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2b9ebfb000)
    libgcc_s.so.1 => /usr/local/lib64/libgcc_s.so.1 (0x00007f2b9ebda000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f2b9ea8b000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f2b9f06a000)

As result of all this hard work I have mips disasm in perl with 100 lines of code


Viewing all articles
Browse latest Browse all 264

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>