Thread Win32::API::Struct Daten werden nicht übernommen (9 answers)
Opened by hummer at 2015-06-11 12:53

hummer
 2015-06-11 12:53
#181320 #181320
User since
2013-06-12
22 Artikel
BenutzerIn
[default_avatar]
Hallo Forum,
nach langer Perl-Pause muss ich mich wieder einem kleinem Projekt widmen und hoffe ihr könnt mir helfen.

anbei mein Problem.
Ich werde eine Verbindung mit einer SPS herstellen. Hierzu habe ich eine DLL, welche entsprechende Funktionen mir zur verfügung stellt. Anbei liegen mir auch entsprechende C-Code zur verwendung bei.
Ich würde aber gen bei Perl bleiben und diesen C-Code entsprechend in Perl umsetzen.

Mit Win32::API konnte ich eine Verbindung zur DLL herstellen.

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
use strict;
use warnings;
use v5.10;
use Win32::API;


Win32::API->Import('AdsDll.dll', 'LONG AdsGetDllVersion()') or die "$!";

my $pt = AdsGetDllVersion() or die "AdsGetDllVersion failed: $^E";
say $pt;

####Ergebnis seitens DLL Codiert
123456


So nun ist der Code aber Codiert, und gibt mir in diesem Datentyp "LONG" die Revision, Vision und Bild Nummer raus.
im C-Beispiel liegen hier noch entsprechende Headefiles bei.

Code: (dl )
1
2
3
4
5
6
7
8
typedef	struct 
{
unsigned char version;
unsigned char revision;
unsigned short build;
} AdsVersion;

typedef AdsVersion* PAdsVersion;



Wie kann ich nun die Dtructur in Perl umsetzen und dann den Wert übergeben, sodass ich entsprechend die einzelnen entcodierten Werte bekomme?

in C sieht das folgendermaßen aus:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
void main()
{
long nTemp;
AdsVersion* pDLLVersion;

nTemp = AdsGetDllVersion();
pDLLVersion = (AdsVersion *)&nTemp;
cout << "Version: " << (int)pDLLVersion->version << '\n';
cout << "Revision: " << (int)pDLLVersion->revision << '\n';
cout << "Build: " << pDLLVersion->build << '\n';
cout.flush();
getch();
}


in Perl habe ich folgendes Probiert:
anlegen einer Structur:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
use strict;
use warnings;
use v5.10;
use Win32::API;
use Win32::API::Struct;
use Data::Dumper;

BEGIN{


}

Win32::API::Struct->typedef(
'POINT', qw (
UCHAR version;
UCHAR revision;
USHORT build;
)
) or die "Typdef error $!\n";



my $pt = Win32::API::Struct->new('POINT');



Soweit so gut, mit
Code: (dl )
say $pt->sizeof();
bekomme ich dann auch eine Größe raus, welche um 1 größer ist als der Inhalt, also 4

weiter habe ich folgendes probiert:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
use strict;
use warnings;
use v5.10;
use Win32::API;
use Win32::API::Struct;
use Data::Dumper;

BEGIN{}

Win32::API::Struct->typedef(
'POINT', qw (
PCHAR version;
PCHAR revision;
PSHORT build;
)
) or die "Typdef error $!\n";



my $pt = Win32::API::Struct->new('POINT');
say $pt->sizeof();

Win32::API->Import('AdsDll.dll', 'LONG AdsGetDllVersion()') or die "$!";

$pt = AdsGetDllVersion('POINT') or die "AdsGetDllVersion failed: $^E";
say $pt->version;


Ergebnis:
Wrong number of parameters: expected 0, got 1.

Verwende ich nur dies:
Code: (dl )
$pt = AdsGetDllVersion() or die "AdsGetDllVersion failed: $^E";

bekomme ich folgende Fehlermeldung:
Can't locate object method "version" via package "196638" (perhaps you forgot to
load "196638"?) at P:\Perl\01_Dll_01.pl line 26.


Was mache ich falsch, wie kann ich das oben genannte ergbnis aus Code1 in die Struktur packen, damit ich die Werte bekomme,
ist es Sinnvoll die Headerdatei des C-Code in Perl einzubinden?

Vielen Dank für eure Hilfe.

Gruß

View full thread Win32::API::Struct Daten werden nicht übernommen