В соседней теме Событие с невизуального компонента подымал вопрос как отловить событие у невизуального компонента. Начал переносить все в DLL-ку и встал, уже неделю не хочет работать как надо. Собственно код: Код | library Fakel;
uses SysUtils, Classes, Forms, DateUtils, ModLink, SharedTypes in 'SharedTypes.pas';
const _NAME = 'Fakel'; _VERSION = 1; _TYPE = dtFile; _OPTIONSCOUNT = 1; HEX:ARRAY['A'..'F'] OF INTEGER=(10,11,12,13,14,15);
var ModbusConnection1: TModbusConnection; ModbusClient1: TModbusClient; ModuleOptions: TOptions; datet: TDateTime;
function LayerFunc(Bin: string): Single; var SomeVar: Byte; begin SomeVar := StrToInt(Bin[1]); end; function IntToBinFloat(Value: Integer; var Float: Single): string; var i: Integer; begin Result := ''; for i := 31 downto 0 do if Value and (1 shl i) <> 0 then Result := Result + '1' else Result := Result + '0'; Float := LayerFunc(Result); end;
function HexToFloat(Hex: string): Single; begin try IntToBinFloat(StrToInt('$' + Hex), Result); except Result := 0.0 end; end;
Function HexToInt(HexValue:String):Integer; var Int,i:integer; begin Result:=-1; Int:=0; for i:=1 TO Length(HexValue) DO IF HexValue[i] < 'A' THEN begin Int:=Int * 16 + ORD(HexValue[i]) - 48; Result:=int; end ELSE begin Int:=Int * 16 + HEX[HexValue[i]]; Result:=int; end; end;
function GetData: TDeviceData; stdcall; var dp: TDeviceDataItem; str:string; datet: TDateTime; begin datet:=now; ModbusClient1.ReadHoldingRegisters(4096, 60); // Запрос начиная с адреса 4096 регистров 60 штук Result := TDeviceData.Create(True); dp := TDeviceDataItem.Create; dp.Name := 'Параметр'; dp.Value := Random(10); Result.Add(dp);
dp := TDeviceDataItem.Create; dp.Name := 'Время, мсек.'; dp.Value := inttostr(MilliSecondsBetween(now,datet)); Result.Add(dp); end;
procedure Initialize(Options: TOptions); stdcall; begin ModbusConnection1:=TModbusConnection.Create(Nil); ModbusClient1:=TModbusClient.Create(Nil); ModbusConnection1.Port:='COM3'; ModbusConnection1.BaudRate:=br115200; ModbusConnection1.DataBits:=db8; ModbusConnection1.Parity:=psEven; ModbusConnection1.StopBits:=sb1; ModbusConnection1.Open; ModbusClient1.Connection:= ModbusConnection1; ModbusClient1.OnHoldingRegistersRead:=ModbusClient1.OnHoldingRegistersRead; end;
procedure SetOptions(Options: TOptions); stdcall; begin if _OPTIONSCOUNT > 0 then ModuleOptions := Options; end;
function GetModuleInfo: TModuleInfo; stdcall; begin Result := TModuleInfo.Create; with Result do begin Name := _NAME; Version := _VERSION; DeviceType := _TYPE; OptionsCount := _OPTIONSCOUNT;
Options[1] := 'COM порт'; OptionsTypes[1] := otComPort; OptionsValues[1] := 'COM3'; OptionsCount := 1; end; end;
{$R *.res}
exports GetModuleInfo, GetData, Initialize, SetOptions;
begin end.
|
Порт открывается 100% (снифер об этом сообщает). Но строчка Код | ModbusClient1.ReadHoldingRegisters(4096, 60);
|
не хочет выполнятся, точнее все, что после нее, так как если ее закомментировать, то все работает дальше. т.е. в программе я вижу как приходят данные рандомные отсюда: Код | dp.Name := 'Параметр'; dp.Value := Random(10);
|
Опять же, если вынести строку запроса данных в процедуру инициализации, то работает, но 1 раз: Код | procedure Initialize(Options: TOptions); stdcall; begin ModbusConnection1:=TModbusConnection.Create(Nil); ModbusClient1:=TModbusClient.Create(Nil); ModbusConnection1.Port:='COM3'; ModbusConnection1.BaudRate:=br115200; ModbusConnection1.DataBits:=db8; ModbusConnection1.Parity:=psEven; ModbusConnection1.StopBits:=sb1; ModbusConnection1.Open; ModbusClient1.Connection:= ModbusConnection1; ModbusClient1.OnHoldingRegistersRead:=ModbusClient1.OnHoldingRegistersRead; ModbusClient1.ReadHoldingRegisters(4096, 60); end;
|
Собственно, все приплыл. Прошу помощи. Во всех случаях программа компилируется.
|