BarneySimpson has asked for the wisdom of the Perl Monks concerning the following question:

I bought this computer chip that allows me to turn on/off digital outputs and read analogue inputs. the designers have made the task of communicating with the chip very easy with the use of a dll (called wsp.dll). The dll has 3 main functions that allow me to communicate with the chip.

1. InitWasp() - no parameter inputs, returns Boolean value

2. SetOutputs() - one integer parameter passed by value, returns integer value

3. ReadInputs() - one parameter which is a reference to an integer and returns an integer value. The reference to the integer is actually the reference to the first integer in an integer array, with the subsequent 3 array values also being used to store analogue results.

The problem that I am having is I can't get the function ReadInputs() to work because I can not figure out how to define it in Perl. I have been using Win32::API to try and accomplish this. The working code in perl for InitWasp() and SetOutputs() is as follows.

use Win32::API; #start up # Win32::API->Import("wsp", "int InitWasp()"); Win32::API->Import("wsp", "int SetOutputs(int a)"); #how functions are called # InitWasp(); SetOutputs(1);

The designers of the chip have supplied an example program that works in visual basics and is as follows

'connect to dlls Declare Function InitWasp Lib "wsp.dll" () As Boolean Declare Function SetOutputs Lib "wsp.dll" (ByVal outputs As Integer) A +s Integer Declare Function ReadInputs Lib "wsp.dll" (ByRef analogue As Integer) +As Integer 'how functions are called InitWasp() ' initialize the wasp board for USB comms SetOutputs(8) Dim analogue(4) As Integer Dim x As Double ReadInputs(analogue(0)) x = analogue(1)

If you could please show me how to define ReadInputs() in perl and how to call the function it would be much appreciated. I have been trying to get this to work for weeks and can not figure it out.

Also I don’t know if I have defined InitWasp() and SetOutputs() completely correct because the return value seems to be gibberish, they do talk to the chip correctly though so this is not a big issue at all.

The last bit of information I would like to give you is the header file (wd.h) that the chip designers have supplied is as follows. I don’t know if this will come in as any use since my Perl program did not use the header file. (Maybe there is an easier method)

// Header file for use with wsp.dll typedef bool (*Type_InitWasp)(); typedef bool (*Type_ReadInputs)(int *analogue); typedef bool (*Type_SetOutputs)(int digital);

Replies are listed 'Best First'.
Re: Win32::API cant define function
by ikegami (Patriarch) on Mar 28, 2010 at 22:36 UTC

    The reference to the integer is actually the reference to the first integer in an integer array, with the subsequent 3 array values also being used to store analogue results.

    For functions that require blocks of memory, use a string of the appropriate size.

    my $read_inputs = Win32::API->new("wsp", "ReadInputs", "P", "I"); sub ReadInputs { my $buf = "\x00" x (4 * 32/8); my $rv = $read_inputs->Call($buf); return ($rv, unpack('l4', $buf)); }

    Update: Fixed name of function. Changed "->()" to "->Call()"

      Thank you for your feed back but I still can not get it to work. I am kind of a nubie when it comes to Perl. The function that reads in is actually called ReadInputs not SetOutputs but I guess that was just a typo.

      I have pasted the code I am trying to get to work below. The code is suppost to print out what ReadInputs has read every second. The error that I am getting in command prompt is "Not a Code reference at line 20" and it's talking about "my $rv = $read_inputs->($buf);"

      use strict; use Win32::API; Win32::API->Import("wsp", "int InitWasp()"); my $read_inputs = Win32::API->new("wsp", "ReadInputs", "P", "I"); InitWasp(); #connect to WASP USB board #constant input read in # while(1){ print ReadInputs()."\n"; sleep(1); } #Subroutines # sub ReadInputs{ my $buf = "\x00" x (4 * 32/8); my $rv = $read_inputs->($buf); return ($rv, unpack('l4', $buf)); }

        Try:

        my $rv = $read_inputs->Call ($buf);

        Oh, and note that ReadInputs returns a list of values so print will print them concatenated together without any white space. You could:

        my @values = ReadInputs(); print "@values\n";

        to at least get a space between each value. Note that the first value is the 'bool' result of the call and that the following values are the ADC input values.


        True laziness is hard work