http://www.perlmonks.org?node_id=959112

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

Dear Perl Monks,

I need a help in Win32::API

I am working on a hardware test automation, The interface to hardware is USB-I2C and we have a C DLL which exports set of functions to communicate with hardware.

I am trying to import the C DLL via Win32::API module so i can automate some test cases via perl. Right now, I could able to read & write to particular memory address using the exported APIs in DLL

I have a problem with one API , Which is i2cGetDeviceAddress , it returns unsigned char. I could not able to properly use Win32::API to get the data from this API. This API is working well in C code

I have given API prototype in C , C code and its output and my perl code

Please help me to use 'unsigned char' with Win32::API module.

use Win32::API; #C proptype # typedef unsigned char __stdcall i2cGetDeviceAddress_type(); # extern i2cGetDeviceAddress_type *i2cGetDeviceAddress; #C++ Prototype # extern "C" Byte __stdcall i2cGetDeviceAddress(void); # C Code # printf ("\n \n DEV: %d , %c , %x ", i2cGetDeviceAddress(),i2cGetDevi +ceAddress(),i2cGetDeviceAddress()); # # Output: DEV: 70 , F , 46 #Perl Code # When i use 'char' as a return type , API is not returning anything # my $i2cGetDeviceAddressFunc = Win32::API->new('CrdI2C32', 'char i2cG +etDeviceAddress()') or warn "\n ERROR: Can not import API:i2cGetDevic +eAddress , $^E ,"; # When i use 'unsigned char' as a return type, I get, Win32::API::pars +e_prototype: WARNING unknown output parameter type 'unsigned' #my $i2cGetDeviceAddressFunc = Win32::API->new('CrdI2C32', 'unsigned c +har i2cGetDeviceAddress()') or warn "\n ERROR: Can not import API:i2c +GetDeviceAddress , $^E ,"; # So, I used INT , The following way is working for some other API but + not this API :( my $i2cGetDeviceAddressFunc = Win32::API->new('CrdI2C32', 'INT i2cGetD +eviceAddress()') or warn "\n ERROR: Can not import API:i2cGetDeviceAd +dress , $^E ,"; my $ret = 0; $ret = $i2cGetDeviceAddressFunc->Call(); $ret = unpack ('C*',pack ("i",$ret)); print "\n $ret "; # prints 152 $ret = sprintf ("0x%X",$ret); print "\n $ret"; #prints 0x98 but i wanted 0x46

Update:
OS: Windows 7 Perl: Active Perl 5.12 , x86 flavour (MSWin32-x86-multi-thread)

UPDATE: Problem is solved

The above code itself is fine. I was confused with API call sequence. When I call I2CWrite API and then i2cGetDeviceAddress , It is providing correct output (i.e 70)

Thanks a Lot to BrowserUk his suggestion was useful to me to implement some other API using Win32::API

Thanks to tye for the $ret &= 0xFF; tip. I did not know this, That is why i am using complex pack & unpack