Thread Win32::API Übergabe Structuren an Dll (5 answers)
Opened by hummer at 2015-07-29 18:52

hummer
 2015-07-29 18:52
#181688 #181688
User since
2013-06-12
22 Artikel
BenutzerIn
[default_avatar]
Hallo Forum,

ich benötige noch einmal eure Hilfe im Umgang mit DLL und der Übergabe von Strukturen.

Einleitend, möchte ich euch gern erst einmal den C-Code vorlegen, welcher mit zur Verfügung steht.

C-Main
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void main()
{
long nErr, nPort;
AmsAddr Addr;
PAmsAddr pAddr = &Addr;
DWORD dwData;

// Kommunikationsport auf dem ADS Router öffnen
nPort = AdsPortOpen();
nErr = AdsGetLocalAddress(pAddr);
if (nErr) cerr << "Error: AdsGetLocalAddress: " << nErr << '\n';

// TwinCAT2 RTS1 Port = 801
pAddr->port = 801;
}


Dieser Code benutz folgende C-Struct
Code: (dl )
1
2
3
4
5
6
7
8
typedef struct {
AmsNetId netId;
USHORT port;
} AmsAddr, *PAmsAddr;

typedef struct {
UCHAR b[6];
} AmsNetId, *PAmsNetId;



So, nun möchte ich gern mein Programm dazu veranlassen, die Funktion AdsGetLocalAddress aufzurufen, die Parameter zu übergeben, und die Werte in einen z.B. Hash oder String + Array zu speichern.

Die Funktion bekommt den Struct übergeben, in welche sie zwei Werte Speichert. Zum einen speichert die den Port, welcher geöffnet wurde, zum anderen die NetId.
Als Rückgabewert bekomme ich den Fehlercode, ob die Funktion erfolgreich war oder ein Fehler vorliegt.

Meine Versuche mit der Dll waren bisher erfolgreich, wenn es um die Datenabfrage ging, aber leider nicht bei der Struct-Übergabe

Mein Versuch
Object:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
sub new {
my $class = shift;
my $Path2Dll = shift;

my $self = {

# Dll function Path Function IN OUT
_LocalAddr => _GetRefToDllFunction("$Path2Dll", 'AdsGetLocalAddress', 'P', 'N'),

};
bless $self, $class;
return $self
}

sub _GetRefToDllFunction {
my $refToDllFunction = Win32::API->new(@_);

if(not defined $refToDllFunction) {
die "ERROR: Trying to load $_[1] from $_[0].dll. Failure: $!\n";
}
return $refToDllFunction;
}


Soweit so gut, das einzige was hierbei noch falsch sein kann ist der Parameter, zur Übergabe 'P'

Was habe ich bisher probiert:
ich habe mit Win32:.API::Struct eine Struktur angelegt, wie diese im C-Code

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
_LocalAddr => _GetRefToDllFunction("$Path2Dll", 'AdsGetLocalAddress', 'S', 'N'),
...
Win32::API::Struct->typedef(
AmsNetId => qw(
UCHAR b[6];
)
);

Win32::API::Struct->typedef(
AmsAddr => qw(
AmsNetId netId;
USHORT port;
)
);

Win32::API->Import("$self->{_Path2Dll}" => 'LONG AdsGetLocalAddress(LPAmsAddr pt)');

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

AdsGetLocalAddress($pt);

Fehler:
Use of uninitialized value in pack at C:/Perl/lib/Win32/API/Struct.pm line 317.
Use of uninitialized value in pack at C:/Perl/lib/Win32/API/Struct.pm line 317.
Win32::API a function was called with the wrong prototype and caused a C stack inconsistency EBP=28f8a0 ESP=28f89c


ich habe die jeweiligen Parameter gepackt:
Code: (dl )
1
2
3
4
5
6
7
8
9
sub GetLocalAddr {
my $self = shift;
my @AmsNetId = (0,0,0,0,0,0);
my $Port = 0;

my $Param = pack ('C6 S', @AmsNetId,$Port);

my $Result = $self->{_LocalAddr}->Call($Param);
}

Fehler:
Win32::API a function was called with the wrong prototype and caused a C stack inconsistency EBP=28f8a0 ESP=28f89c


Kann mir jemand helfen, wie ich hierbei am besten vorgehe kann.

Vielen Dank

View full thread Win32::API Übergabe Structuren an Dll