I'm working with Win32::API against a Win32 dll. My machine is 64 b and I'm using Cygwin. I'm trying to create a struct defined in C as:
typedef struct cRefStr
{
size_t length;
char const* data;
} cStrRef;
I've tried to define the following structure with Win32::API::Struct:
Win32::API::Struct->typedef(CSTRREF =>qw{int n; char* buffer});
The complete perl code is:
# Sub all
# cTblAtKey -> findInTableByKey
# cTbl -> myTable
# cCell -> myCell
# ctbl_v2 -> myDll
my $aKey = "UserName";
print $aKey."\n";
my $lengthaKey = length($aKey);
print $lengthaKey."\n";
Win32::API::Struct->typedef(CSTRREF =>qw{int n; char* buffer});
my $structParameter = Win32::API::Struct->new('CSTRREF');
$structParameter->{n}=$lengthaKey;
$structParameter->{buffer}=$aKey;
# C function defined as:
# myCell* findInTableByKey(myTable that, struct cRefStr key, unsigned
+offset);
# with:
# struct myCell {
# unsigned char opaque[10];
#};
my $aKeyFunc = Win32::API->new("myDll.dll",'findInTableByKey', 'NSN','
+C','_cdecl');
if(not defined $aKeyFunc)
{
die "Couldn't load the function findInTableByKey from the dll";
}
$cellPtr = $aKeyFunc->Call($outputTable,$structParameter,0);
This breaks with a "Segmentation fault (core dumped)" error.
I've managed to use other functions of the same dll against $outputTable (this was the thread) and I know it is a valid parameter. So I've determined that the issue is with the Struct. I'm trying to substitute $structParameter by its low-level version as suggested in the Win32::API doc, this is using something like pack('NC',$size,$aKey).
I've tried to use a simplified example to understand how this would work. The code in the Win32::API doc, to test struct works as expected:
#### define the structure
Win32::API::Struct->typedef( POINT => qw{
LONG x;
LONG y;
});
#### import an API that uses this structure
my $getCursor = new Win32::API('user32', 'GetCursorPos','S','N');
#### create a 'POINT' object
my $pt = Win32::API::Struct->new('POINT');
#### call the function passing our structure object
$getCursor->Call($pt);
#### and now, access its members
my ($x, $y) =($pt->{x}, $pt->{y});
print "The cursor is at: $x, $y\n";
However the low-level version suggested in the same doc, throws an error: "Can't call method 'Pack' on an undefined value at ./TestStruct.pl line 27". The broken code:
#### import an API that uses this structure
my $getCursor = new Win32::API('user32', 'GetCursorPos','S','N');
#### create a 'POINT' object
$lpPoint=pack('LL',0,0);
#### call the function passing our structure object
$getCursor->Call($lpPoint);
#### and now, access its members
my ($x,$y) = unpack('LL',$pt);
print "The cursor is at: ".$x.", ".$y."\n";
Any suggestion?