sgv_81 has asked for the wisdom of the Perl Monks concerning the following question:
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:
I've tried to define the following structure with Win32::API::Struct:typedef struct cRefStr { size_t length; char const* data; } cStrRef;
The complete perl code is:Win32::API::Struct->typedef(CSTRREF =>qw{int n; char* buffer});
This breaks with a "Segmentation fault (core dumped)" error.# 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);
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:
Any suggestion?#### 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";
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Low-level version of Win32::API::Struct
by BrowserUk (Patriarch) on Aug 01, 2012 at 12:06 UTC | |
by sgv_81 (Novice) on Aug 01, 2012 at 16:21 UTC | |
by bulk88 (Priest) on Aug 01, 2012 at 17:32 UTC | |
|
Re: Low-level version of Win32::API::Struct
by Anonymous Monk on Aug 01, 2012 at 11:06 UTC | |
|
Re: Low-level version of Win32::API::Struct
by bulk88 (Priest) on Aug 01, 2012 at 17:04 UTC | |
by sgv_81 (Novice) on Aug 02, 2012 at 07:12 UTC | |
by bulk88 (Priest) on Aug 02, 2012 at 16:01 UTC |