This an update to previous posts, generally things are almost there but there are a couple of issues, that remain, if anyone has any experience of this.
The following function uses a component in the DLL to extract the version information from the DLL.
To explain a little on the development.
I did have a var statement in front of the 'Buffer' parameter as the function uses this to load the getver component with the required filename it will throw an exception if it cannot find the target file.
I added the 'if fileexists' to trap this.
VB does not like the 'var' at all but I have been told that you don't need it in this situation and indeed the function works fine when called from Delphi!!
The problem here is that our customer created a special data type that handles making a VB string out of values returned in this way as this (and other) functions do.
But he does not know how to 'load' the string to be passed in.
Here the parameter V should be a 'single' as it is in the 'Writing' version.
But again he does not know how to access the 'var' parameter unless it is a string!!.
Steve [The sane]: Delphi a feersum engin indeed.
The following function uses a component in the DLL to extract the version information from the DLL.
To explain a little on the development.
I did have a var statement in front of the 'Buffer' parameter as the function uses this to load the getver component with the required filename it will throw an exception if it cannot find the target file.
I added the 'if fileexists' to trap this.
VB does not like the 'var' at all but I have been told that you don't need it in this situation and indeed the function works fine when called from Delphi!!
The problem here is that our customer created a special data type that handles making a VB string out of values returned in this way as this (and other) functions do.
But he does not know how to 'load' the string to be passed in.
Code:
// NOTE VB implementation of passing the filename in to load the getver component has not as yet been found
function EthernetGetDLLVersion(Buffer: PChar): Integer; stdcall;
var MaxLen: integer;
S: string;
begin
if Initalised then
begin
if fileexists(Buffer) then
with DataModule2 do
begin
getver.fileName := Buffer;
s := Getver.fileName;
MaxLen := GetDLLVersionLength;
if (Buffer <> nil) and (MaxLen > 1) then
begin
StrLCopy(Buffer, PChar(GetVer.VersionStrings[2]), MaxLen);
Result := 0;
end
else
Result := 17;
end
else
begin
S := 'Cannot find file '+ S;
StrLCopy(Buffer, PChar(S), Length(S));
Result := 18;
end
end
else
begin
StrLCopy(Buffer, PChar('DLL is not initalised'), Length('DLL is not initalised'));
Result := 19;
end;
end;
Here the parameter V should be a 'single' as it is in the 'Writing' version.
But again he does not know how to access the 'var' parameter unless it is a string!!.
Code:
// IP = string representation of the IP address e.g. '169.20.10.0'
// IEEE conversion functions are in IEE/IEECalc.pas
// NOTE Working implementation (tested with VB)
// Parameter V: Pchar returns the data value as a string No way could be found to access
// this values as var parameter unless it was string !!!!
function EthernetRead(IP: pchar; Card: integer; Channel: integer; Par: integer; V: Pchar): integer; stdcall;
var Vals: array [1..4] of byte;
StringVal: string;
a, E, Counter: integer;
Value: single;
begin
// extract the data to the buffer
E := ReadFrom(IP, 8000, Card);
if E > 0 then
begin
result := E;
exit;
end;
// wait for response
DataRxd := False;
DataUnit3.Timeout := False;
DataModule2.Response.Enabled := True;
// Response timer to handle next part
// wait for it to complete
Counter := 0;
// so might this needs to run longer than the timer
for a := 0 to TimeConstant do
begin
if DataRxd then break;
inc(counter);
end;
if DataUnit3.Timeout then
begin
Result := 15; // timed out waiting for data receive
exit;
end
else
// dont leave the time running
DataModule2.Response.Enabled := False;
// now extract the required data from the buffer
if par <> 100 then
for a := 1 to 4 do
vals[a] := ReadData((Channel * 17) + Par + a);
Value := 0;
case par of
0 : Value := Vals[1]; // Configuration
1,3 : Value := Vals[1] or (Vals[2] shl 8);
5, 9,13: begin
StringVal := GetIEEEValue(vals[1], vals[2], vals[3], vals[4]);
Value := IeeeToDecimal(StringVal);
end;
100 : Value := ReadData(0); // get the card type
200..207: Value := ReadData(Par - 199);
end;
StringVal := FloatToStrF(Value, FfFixed,3,4);
StrLCopy(V, PChar(StringVal), Length(StringVal));
// if the returned result is none zero then the IEEE value was invalid
Result := 0;
end;
Steve [The sane]: Delphi a feersum engin indeed.