After finding some changes that Sniffer::HTTP needed, I tried to run its test suite. My Strawberry Perl installation was missing some modules, since I hadn't touched Sniffer::HTTP for some time. Especially, it needed Net::Pcap. So I went, and downloaded the WinPCap driver and developer pack from http://www.winpcap.org/devel.htm and installed them. Then I found that I had already reported about four months ago that Net::Pcap 0.16 with libpcap 1.0 does not compile on Windows. So, I decided to look deeper into the problem:

cpanm --look Net::Pcap

...dropped me in the unpacked distribution directory. And fair enough, running the Makefile.PL with the appropriate parameters showed me that it did not find any of the "interesting" functions of the library. In fact, I found that DynaLoader loads DLLs on Windows (as expected) but seems to load .a files and other object files on other operating systems . At least, that's what the usage in the Makefile.PL suggests to me:

sub have_functions { my @funcs = (); print "detecting available functions... "; my @paths = DynaLoader::dl_findfile(qw(-lpcap)); my $libref = DynaLoader::dl_load_file($paths[0]); for my $func (@_) { my $symref = DynaLoader::dl_find_symbol($libref, $func); push @funcs, $func if defined $symref } print "ok\n"; return @funcs } ... # Check that '-lwpcap' exports 'pcap_open_live' print have_functions('pcap_open_live');

So, "all" I had to do was to find a suitable replacement (or suitable munging) of that code to find whether an object file exports a certain symbol or not.

I ended up with the following, fairly ugly code:

sub have_functions { my @funcs = (); print "detecting available functions... "; my @paths = DynaLoader::dl_findfile(split /\s+/, $options{LIBS}); die "Couldn't find any library file satisfying '$options{LIBS}'" unless @paths; my $libfile = $paths[0]; # On Win32, we assume that the lib file will not be statically lin +ked # but will be a thin wrapper for a similarly named .dll file. # This is not universal but works in many cases # This assumes that a library -l$foo will map to lib$foo.a # through DynaLoader. We then try to find and load $foo.dll in $EN +V{PATH} if ($has_Win32) { (my $dll = basename $libfile) =~ s/\.\w+$//; $dll =~ s/^lib//; $dll .= '.dll'; ($libfile) = grep { -f } map { File::Spec->catfile($_,$dll) } +File::Spec->path; die "'$dll' not found in PATH" unless $libfile; }; warn "Using '$libfile' as potential symbol candidate"; my $libref = DynaLoader::dl_load_file($libfile); warn "Couldn't load $libfile via DynaLoader ($^E)" unless $libref; for my $func (@_) { my $symref = DynaLoader::dl_find_symbol($libref, $func); push @funcs, $func if defined $symref; #print "$func", $symref ? "" : " NOT", " found\n"; }; print "ok\n"; return @funcs }

That code munges a found .a file and infers the name of the DLL that belongs to it, at least for gcc. Then it searches that DLL in $ENV{PATH} and uses DynaLoader to load and inspect that DLL.

My question is whether anybody knows how to extract the symbols of a library. I'm sure that there must be a much better, Perlish way to find out whether an object file (or a C header) exports a certain symbol or not. I briefly toyed with the idea of parsing the output of nm $libfile, but that will break on MSVC, and also, I know nothing about the different incarnations of nm across operating systems. The only relevant module I found is ExtUtils::FindFunctions by Maddingue and it (unsurprisingly) suffers the same problems, as Maddingue also is the author of Net::Pcap.

PS: The patch is submitted so that should make Net::Pcap compile again on Windows (and elsewhere?), and hopefully, a new release of Net::Pcap will include these.


In reply to On Yaks and the Shaving Thereof - finding exported symbols of a C library by Corion

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.