Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Re: Using Inline::C in a package

by BrowserUk (Patriarch)
on Sep 04, 2013 at 17:23 UTC ( [id://1052399]=note: print w/replies, xml ) Need Help??


in reply to Using Inline::C in a package

Whilst multiple use Inline C => ... lines are common a useful; without the C being followed by a fat comma (=>) the C becomes a prohibited bareword. In any case, that second use line with no arguments is redundant.

Correct that (ie. remove the redundant line) and you'll find your next error:

C:\test>perl junk.pm Can't modify constant item in scalar assignment at junk.pm line 19, ne +ar ");"

Which is this line:

h = openDevice()

Variables need sigils in Perl.

Cccorrect that and you're on your own as I don't have the headers or library to try to compile your c code.


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^2: Using Inline::C in a package
by rem45acp (Novice) on Sep 04, 2013 at 17:45 UTC
    I have been able to get it to fully compile.
    It croaks if OpenDevice returns a HANDLE, which is
    typedef void* HANDLE;
    But if OpenDevice returns void everything compiles and runs at least.
    Here is the updated code:
    package PIC::DevaSysI2CIO; use strict; use Inline C => Config => LIBS => "-LE:/drivers/usb/devasys_i2cio -lusbi2cio", INC => "-IE:/drivers/usb/devasys_i2cio", BUILD_NOISY => 1; use Inline C => q { #include <windows.h> #include "Usbi2cio.h" #include <stdio.h> void OpenDevice() { HANDLE handle = INVALID_HANDLE_VALUE; handle = DAPI_OpenDeviceInstance("UsbI2cIo", 0); if (handle == INVALID_HANDLE_VALUE) { printf("Could not open device\n"); } else { printf("Opened device!\n"); } } }; sub new { my ($class_name) = @_; my ($self) = {}; bless($self, $class_name); return $self; } sub open_device { OpenDevice(); } 1;

      You'll need to wrap the C handle in a bless reference. See Re^12: odd line in windows for an example.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        You'll need to wrap the C handle in a bless reference

        Actually, I think you can just return the HANDLE to perl with newSVuv().
        I certainly have a script that passes a HANDLE between perl and C (in both directions) as a UV, and it works fine:
        use warnings; use strict; use Inline C => Config => BUILD_NOISY => 1; use Inline C => <<'EOC'; SV * get_handle() { return newSVuv(GetStdHandle(STD_OUTPUT_HANDLE)); } SV * get_attr(SV * h) { CONSOLE_SCREEN_BUFFER_INFO Info; if(!GetConsoleScreenBufferInfo((HANDLE)SvUV(h), &Info)) croak("Error obtaining current attributes"); return newSVuv(Info.wAttributes); } void set_attr(SV * h, SV * attr) { if(!SetConsoleTextAttribute((HANDLE)SvUV(h), (WORD)SvUV(attr))) croak("Error setting attributes"); } EOC use constant { FOREGROUND_BLUE => 1, FOREGROUND_GREEN => 2, FOREGROUND_RED => 4, FOREGROUND_INTENSITY => 8, BACKGROUND_BLUE => 16, BACKGROUND_GREEN => 32, BACKGROUND_RED => 64, BACKGROUND_INTENSITY => 128}; $| = 1; my $h = get_handle(); my $current = get_attr($h); my $current_background = $current & (BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY); # $current_foreground not needed in this script my $current_foreground = $current & (FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY); # Set $message to intense red on current background my $message = FOREGROUND_RED | FOREGROUND_INTENSITY | $current_background; set_attr($h, $message); print "ERROR_MSG = xyz"; # Restore original foreground/background colours. set_attr($h, $current); print "\n All Done\n";

        (On Windows, that script just prints "ERROR_MSG = xyz" in bold red, then "All Done" in the original console color.)

        So ... for the OP, I'm thinking if it's desired that OpenDevice() returns the handle, then it just needs to be:
        SV * OpenDevice() { HANDLE handle; /* Do stuff that creates the handle */ return newSVuv(handle);
        And to pass that handle from perl back to C:
        void pass_handle(SV * handle) { HANDLE h = (HANDLE)SvUV(handle); /* Do stuff with the handle */ }
        Alternatively, it can be passed around just as well as an unsigned long:
        unsigned long OpenDevice() { HANDLE handle; /* Do stuff that creates the handle */ return (unsigned long)handle;
        And to pass that handle from perl back to C:
        void pass_handle(unsigned long handle) { HANDLE h = (HANDLE)handle; /* Do stuff with the handle */ }

        That seems to be all that's needed - for any HANDLEs I've passed around, at least.

        Cheers,
        Rob

      Hi, rem45acp,

      I suggest you use InlineX::C2XS to get the task done with out any annoyance. first: create a test.pl like below:

      use strict; use Inline C => Config => LIBS => "-LE:/drivers/usb/devasys_i2cio -lusbi2cio", INC => "-IE:/drivers/usb/devasys_i2cio", BUILD_NOISY => 1; use Inline C => q { #include <windows.h> #include "Usbi2cio.h" #include <stdio.h> void OpenDevice() { HANDLE handle = INVALID_HANDLE_VALUE; handle = DAPI_OpenDeviceInstance("UsbI2cIo", 0); if (handle == INVALID_HANDLE_VALUE) { printf("Could not open device\n"); } else { printf("Opened device!\n"); } } };
      then run: c2xs ....... it will produce a XS package for you. Please refer Inline::C2XS doc for details.




      I am trying to improve my English skills, if you see a mistake please feel free to reply or /msg me a correction

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1052399]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (7)
As of 2024-04-23 10:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found