Страница 1 из 1

Общие данных в динамической библиотеке

СообщениеДобавлено: 01.10.2020 11:54:17
gluhow
Хотел с помощью библиотеки реализовать доступ нескольких приложений к одной плате, доступ к которой открывается в монопольном режиме, но у меня каждое приложение похоже создаёт свою копию. Упрощенно, задачу можно свести к передаче переменной
Библиотека
Код: Выделить всё
library DynLibProject;

{$mode objfpc}{$H+}

uses
  Classes
  { you can add units after this };
var
  I:Integer;
  CriticalSection:TRTLCriticalSection;

function Value:Integer;
begin
  Result:=I;
end;

Procedure SetValue(_NewValue:Integer);
begin
  EnterCriticalsection(CriticalSection);
  I:=_NewValue;
  WriteLn('SetValue. Addr=', PtrUInt(@i), ' Value=', i);
  LeaveCriticalsection(CriticalSection);
end;

exports Value, SetValue;

initialization
begin
  InitCriticalSection(CriticalSection{%H-});
  WriteLn('Init. Addr=', PtrUInt(@i), ' Value=', i);
end;

finalization
begin
  DoneCriticalsection(CriticalSection);
end;

end.


Код программы:
Код: Выделить всё
program Connect;
uses dynlibs, sysutils;

type

  TValue=function:Integer;
  TSetValue=procedure(_NewValue:Integer);

var
  LibHndl:TLibHandle;
  Value:TValue;
  SetValue:TSetValue;
  i:Integer;

begin
  LibHndl:=SafeLoadLibrary('./libdynlibproject.so');
  if LibHndl>0 then
  begin
    Value:=TValue(GetProcedureAddress(LibHndl, 'Value'));
    SetValue:=TSetValue(GetProcedureAddress(LibHndl, 'SetValue'));
  end;

  if Assigned(Value) and Assigned(SetValue) then
  begin
    while True do
    begin
      i:=Value();
      WriteLn(i);
      Inc(i);
      SetValue(i);
      Sleep(500);
    end;
  end;
end.     


Если запустить несколько экземпляром программы, то все они начнут отсчет от 0. А хотелось бы чтобы счет был общий для всех. Как это сделать? Тестировал только на linux

Re: Общие данных в динамической библиотеке

СообщениеДобавлено: 01.10.2020 12:53:41
mig-31
Что за плата, если не секрет? Я так понимаю API к драйверу платы это не умеет multithread (карты National Instruments умееют). Драйвер Линух - это всегда файл. Можно открыть только для чтения. Например драйвера для чипов подлючаемых по I2C у ARM плат создают /dev/mcp3008/ai0.
Можно написать демона или обычное приложение, которое клиенту будет посылать значение TSimpleIPCServer, TSimpleIPCClient или UDP.

Re: Общие данных в динамической библиотеке

СообщениеДобавлено: 01.10.2020 13:53:07
gluhow
Плат у меня их небольшой зоопарк (Элкус, ISPDAS в основном) и есть готовый объект который умеет работать со всеми. Не хотел бы его ковырять. Да и задача с библиотекой не в первый раз всплывает. До этого как раз решил клиент-серверным приложением.

Re: Общие данных в динамической библиотеке

СообщениеДобавлено: 01.10.2020 14:24:41
mig-31
Через динамическую библиотеку не получится. Система для каждого экземпляра программы загрузит копию библиотеки в память. Кроме клиент-серверным приложенияостаеться только вариант с написанием сосбственного драйвера. Драйвер читает состояние входов/выходов и пишет в /dev/ai0 , /dev/di0 или считывает данные из /dev/do0, /dev/ao1. Такие драйверы существуют для микросхем подключаемых по I2C, SPI.

Re: Общие данных в динамической библиотеке

СообщениеДобавлено: 01.10.2020 15:28:23
alexs