wspoldzielenie pamieci

O jezykach programowania w platformach i nie tylko.
mlody87
Gaduła
Gaduła
Posty: 192
Rejestracja: 14 cze 2012, 13:19

Re: wspoldzielenie pamieci

Nieprzeczytany post autor: mlody87 »

Tak, Init daje w OnCreate formy i trzymam uchwyt w zmiennej globalnej.
Obrazek

dulf
Pasjonat
Pasjonat
Posty: 399
Rejestracja: 24 kwie 2010, 15:13

Re: wspoldzielenie pamieci

Nieprzeczytany post autor: dulf »

Problem jest z konwencją wywołania ,stos się wali po wyjściu z OnClick .
Nie znam pascala , widzę że masz zadeklarowane stdcall , nie wiem czy ? takie deklaracje wystarczą do załadowania poprawnego Fun ?
U mnie taki błąd występuje gdy wskaźniki do funkcji deklaruję bez dyrektywy __stdcall ,jeśli jednak deklaracje wskaźników są prawidłowe co do typów funkcji wszystko działa .
Tylko Builder C++ nie umozliwia ładowania dynamicznego funkcji w ten sposób .Muszę ładować przez LoadLib i GetProc Adres .
Nie wiem jak to rozwiązać u ciebie , może spróbuj statycznie połączyć .dll , tylko do tego trzeba chyba plik def i nagłówkowy .
Nie znam się.
W każdym razie to chodzi u mnie ,coś masz z konwencją wywołania u siebie w aplikacji nie tak .
Kod który działa u mnie :

Kod: Zaznacz cały

#include "AppFMapp.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

typedef bool __stdcall(*wsk_Init)(LPCSTR name,int len_str,int len_dbl);
typedef void __stdcall(*wsk_Deinit)(void);
typedef bool __stdcall(*wsk_WriteStrBuff)(const char* s);
typedef LPCSTR __stdcall(*wsk_ReadStrBuff)(void);
typedef bool __stdcall(*wsk_WriteDblBuff)(double d[],int len);
typedef bool __stdcall(*wsk_ReadDblBuff)(double*d,int len);

wsk_Init         Init ;
wsk_Deinit       Deinit ;
wsk_WriteStrBuff WriteStrBuff ;
wsk_ReadStrBuff  ReadStrBuff ;
wsk_WriteDblBuff WriteDblBuff ;
wsk_ReadDblBuff  ReadDblBuff ;

HINSTANCE hLib ;

const int size_str = 512 ;
const int size_dbl = 1024 ;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
         hLib = LoadLibrary("filemapp.dll");

         if(NULL ==hLib)
         {
            ShowMessage("Error Load .dll");

         }else{

                 Init = (wsk_Init)GetProcAddress(hLib,"Init");

                 if(Init == NULL)
                 {
                     ShowMessage("Error Init");

                 }else{
                         if(false == Init("filemem",size_str,size_dbl))  //wywo.Init
                         // nadanie odpowiednich rozmiarow plikowi
                         {
                            ShowMessage("Error Call Init");
                         }
                      }

                 Deinit = (wsk_Deinit)GetProcAddress(hLib,"Deinit");

                 if(Deinit == NULL)
                 {
                     ShowMessage("Error Deinit");

                 }

                 WriteStrBuff = (wsk_WriteStrBuff)GetProcAddress(hLib,"WriteStrBuff");

                 if(WriteStrBuff == NULL)
                 {
                     ShowMessage("Error WriteStrBuff");

                 }
                 WriteDblBuff = (wsk_WriteDblBuff)GetProcAddress(hLib,"WriteDblBuff");

                 if(WriteDblBuff == NULL)
                 {
                     ShowMessage("Error WriteStrBuff");

                 }

              }


}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
        Deinit();
}
//---------------------------------------------------------------------------

const int LEN_DBL = size_dbl ;
double Dbl_Buff[LEN_DBL] ;
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
     Dbl_Buff[0] = 123;                      // pierwsza pozycja w tablicy
     Dbl_Buff[LEN_DBL-1] = 888;      // ostatnia


          WriteStrBuff("Ala ma Kota");
          WriteDblBuff(Dbl_Buff,LEN_DBL);
}
//---------------------------------------------------------------------------
Można ominąć całkiem .dll tylko wtedy musiałbyś poprostu przepisać sobie funkcje z dll na pascala i normalnie używać je jak inne ,zwykłe funkcje w programie .
To tez działa w aplikacji ,bez .dll :

Kod: Zaznacz cały

#include <vcl.h>
#pragma hdrstop

#include "App_FileMapp.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//--------------------------------------------------------------------------
PBYTE  pBuff = 0 ;
HANDLE  hFileMapp = 0;
int  SizeBuff = 0 ;
int  OffsetDbl = 0 ;
const char* ret0 ="" ;

//--------------------------------------------------------------------------
#pragma argsused
//----------------------------------------------------------------------------
HANDLE QCreateFileMapping(LPCSTR name)
{
  HANDLE h ;

    h = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,
                            0,SizeBuff,name);
         return h ;
}
//---------------------------------------------------------------------------
PBYTE QMapViewOfFile(HANDLE hFileMapping)
{
    return (PBYTE)MapViewOfFile(hFileMapping,FILE_MAP_READ|FILE_MAP_WRITE,
                   0,0,0);
}
//----------------------------------------------------------------------------
void  Deinit(void)
{
    if(pBuff)
    {
      UnmapViewOfFile(pBuff);
      pBuff = NULL ;
    }
    if(hFileMapp)
    {
     CloseHandle(hFileMapp);
     hFileMapp = NULL;
    }

}

//---------------------------------------------------------------------------
bool  Init(LPCSTR name,int len_str,int len_dbl)
{
        SizeBuff = len_str+ (len_dbl*sizeof(double));
        OffsetDbl = len_str ;

        hFileMapp = QCreateFileMapping(name);

    if(NULL!=hFileMapp)
    {
        pBuff = QMapViewOfFile(hFileMapp);

        if(pBuff!=NULL)
        {
           memset(pBuff,0,SizeBuff);
           return true ;
        }
      return false ;
    }
           return false ;
}
//---------------------------------------------------------------------------
bool  WriteStrBuff(const char* s)
{
  if(pBuff!=NULL)
  {
    lstrcpy(pBuff,s);
    return true;
  }
    return false;
}
//---------------------------------------------------------------------------
LPCSTR  ReadStrBuff(void)
{
  if(pBuff!=NULL)
  {
   if(pBuff[0]!= 0)
   {
      return pBuff ;
   }
  }
      return ret0 ;
}
//---------------------------------------------------------------------------
bool  WriteDblBuff(double d[],int len)
{
  if(pBuff!=NULL)
  {
    memcpy((pBuff+OffsetDbl),d,len*sizeof(double));
    return true;
  }
    return false;
}
//---------------------------------------------------------------------------
bool  ReadDblBuff(double*d,int len)
{
  if(pBuff!=NULL)
  {
    memcpy(d,(pBuff+OffsetDbl),len*sizeof(double));
    return true;
  }
    return false;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
          if(false == Init("filemem",512,1024))
          {
              ShowMessage("Error Init");
          }

}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
         Deinit();        
}
//---------------------------------------------------------------------------

const int LEN_DBL = 1024 ;
double Dbl_Buff[LEN_DBL] ;

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
          Dbl_Buff[0] = 123;                      // pierwsza pozycja w tablicy
          WriteStrBuff("Ala ma kota");
          WriteDblBuff(Dbl_Buff,LEN_DBL);
}
//---------------------------------------------------------------------------
Jeszcze mi tak przyszło :

Kod: Zaznacz cały

SetLength(Dbl_Buff,LEN_DBL);
O to to ustala rozmiar w bajtach CZY 'doublach' ? double ma powiedzmy 8 bajtów (w Win 32) , jeśli w bajtach to tablica będzie za krótka i nastąpi próba czytania poza nią przez fun WriteDblBuff i rzucenie wyjątku.W bajtach to będzie LEN_DBL*rozmiar_double (w C to jest operator sizeof(double))
Może zdefiniuj tablice statycznie na zewnątrz fun ?
Wykomentuj WriteDblBuff i zobacz czy same string działa . Jesli tak to będzie coś z rozmiarem tablicy żle .
Chociaż z manuala wynika że powinno byc dobrze .
Mam jeszcze wątpliwości co do drklaracji typu funkcji :

Kod: Zaznacz cały

  function WriteStrBuff(s:ShortString):boolean; stdcall; external 'filemapp.dll';
  function ReadStrBuff():ShortString; stdcall; external 'filemapp.dll';
Odpowiednikiem powinien być chyba nie ShortString tylko PChar czyli odpowiednik dla C łańcucha z zerowym ogranicznikiem .

-- Dodano: pt 31-05-2013, 19:31 --
mlody87 pisze:Dzieki wielkie!:) A mozna np utworzyc dwa obszary pamieci o roznych nazwach i odwolywac sie do nich w czasie jednego ticku?
Jeszcze do tego ,to wymaga tworzenie pliku mapowanego dla każdej nowej nazwy , wiąże się to z zarządzaniem dynamicznym wskaznikami i nzwami w .dll i aplikacji tak że sprawa jest troche grubsza .W skrócie można tworzyć w aplikacji i .dll pliki powiązane z danym symbolem ,wtedy mamy full wypas ,ale nie dysponuję przenośnym uniwersalnym rozwiązniem a jedynie powiązanym ze swoją aplikacją.
http://forex-nawigator.biz/forum/import ... ml#p416729
Nie spiesz się , zawsze zdążysz stracić .

mlody87
Gaduła
Gaduła
Posty: 192
Rejestracja: 14 cze 2012, 13:19

Re: wspoldzielenie pamieci

Nieprzeczytany post autor: mlody87 »

Dzieki za pomoc. Problem na pewno jest jakis z tablica bo pisalem juz wczesniej ze z wysylaniem stringa nie ma problemow.
Jak wywoluje funkcje bez stdcall; to od razu program sie wysypuje wiec bez tego nie da rady.
Powalcze jeszcze, najwyzej sprobuje przerobic to tak zeby mozna bylo zamiast tablicy dodawac np drugi string. Da sie to jakos latwo przerobic?
Probuje sam to zmienic ale nie znam sie az tak na C i kompilator wyrzuca mi jakies bledy ;)
Obrazek

dulf
Pasjonat
Pasjonat
Posty: 399
Rejestracja: 24 kwie 2010, 15:13

Re: wspoldzielenie pamieci

Nieprzeczytany post autor: dulf »

Spróbuj z tablicą , zrób sobie dla eksperymentu tablicę o ustalonym rozmiarze statyczną double arrr 0..1024 czyjakoś tak .
NIe musisz wysyłać całej tablicy , zadeklaruj dużą tablicę i wysli tylko parę elementów , jesli problem jest z sięganiem funkcji za zakres tablicy to powinno zadziałać czyli podaj do funkcji WriteDblBuff(Dbl_Buff,LEN_DBL); że ma przepisać mniej elementów ,w końcu wysyłasz tylko jeden .A więc podaj że wyślesz np 3 :

Kod: Zaznacz cały

WriteDblBuff(Dbl_Buff,3); //  zapis do wspólnej pamięci 3 zmienne double[0] ,[1],[2] . 
AAAAAAAAAAA jeszcze !!!!!
Jaki masz system operacyjny(32/64?) i czy program który kompilujesz jesz 64 bit czy 32 bit ?

-- Dodano: sob 01-06-2013, 9:35 --
mlody87 pisze: Powalcze jeszcze, najwyzej sprobuje przerobic to tak zeby mozna bylo zamiast tablicy dodawac np drugi string. Da sie to jakos latwo przerobic?
Da się łatwo ,jak przerobię to podeślę .
Nie spiesz się , zawsze zdążysz stracić .

mlody87
Gaduła
Gaduła
Posty: 192
Rejestracja: 14 cze 2012, 13:19

Re: wspoldzielenie pamieci

Nieprzeczytany post autor: mlody87 »

system 32;) a jaka bylaby roznica?
OK zobacze dzisiaj, moze sie wreszcie uda bo na bank jest cos z ustalaniem wielkosci tablicy i czytaniem z niej ;)
Obrazek

dulf
Pasjonat
Pasjonat
Posty: 399
Rejestracja: 24 kwie 2010, 15:13

Re: wspoldzielenie pamieci

Nieprzeczytany post autor: dulf »

Pomęcz jeszcze tamtą .dll .W operowaniu danymi przydatny jest dostęp 'liczbowy' ,na stringach to będziesz musiał wszystko konwertować.
W załączniku masz inną bibliotekę strmapp.dll ,tam można utworzyć kilka stringów .Zapodajesz czytanie i pisanie po indeksach.
EA do czytania:

Kod: Zaznacz cały

#import "strmapp.dll"

  bool Init(string,int count,int len_str); //count   - ilość stringów
                                           //len_str - max długośc jednego
  void Deinit();
  bool WriteStrBuff(string,int index);
  string ReadStrBuff(int index);

#import

#define NUM_STR 20    // dostepna ilość stringów 0 do 19
#define LEN_STR 512   // długość  
//+------------------------------------------------------------------+
int init()
  {
//----
       bool ret =   Init("filemem",NUM_STR/*ilość stringów*/,LEN_STR/*maksymalna długość*/);

       if(false == ret)
       {
            MessageBox("Error Init()");
       }
//----
   return(0);
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
int deinit()
  {
//----
    Deinit();
//----
   return(0);
  }
//+------------------------------------------------------------------+
string pierwszy , drugi ;
//+------------------------------------------------------------------+
int start()
  {
//----    

          pierwszy = ReadStrBuff(0); // pierwszy

          drugi = ReadStrBuff(1); // drugi
          
          Comment(pierwszy + "  "+drugi);

//----
   return(0);
  }
Do zapisu kawałek :

Kod: Zaznacz cały

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
       WriteStrBuff("Ala ma kota 00",0) ;  // pierwszy str
       WriteStrBuff("Ala ma kota 01",1) ;  // drugi str
}
//---------------------------------------------------------------------------
W Init podajesz :

Kod: Zaznacz cały

Init("nazwa_pamięci", Ilość_stringów, Ilość_bajtów_przydzielana_na_jeden_string);
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Nie spiesz się , zawsze zdążysz stracić .

mlody87
Gaduła
Gaduła
Posty: 192
Rejestracja: 14 cze 2012, 13:19

Re: wspoldzielenie pamieci

Nieprzeczytany post autor: mlody87 »

Kurcze jak kiedys bedzie jakis zlot forumowy czy cos to wisze Ci gigantycznego browara:) Dzieki za pomoc :) O to mi wlasnie chodzilo :) Powalcze jeszcze z ta tablica bo nie lubie tak zostawiac problemow;) Jak dojde co bylo nie tak to dam znac:)
Obrazek

green7
Maniak
Maniak
Posty: 2060
Rejestracja: 16 sty 2008, 18:44

Re: wspoldzielenie pamieci

Nieprzeczytany post autor: green7 »

Strasznie się tu Panowie widzę męczycie wymyślając na nowo koło :)
Poszukajcie w necie a znajdziecie gotowce: np. tutaj: http://www.mql5.com/en/code/816 w delphi wystarczy użyć tego dlla.
dulf pisze:Odpowiednikiem powinien być chyba nie ShortString tylko PChar czyli odpowiednik dla C łańcucha z zerowym ogranicznikiem .
To zależy. Zależy czego kolega używa do kompilacji. Jeśli Borland/Codegar Delphi (a właściwie teraz Embarcadero) to od wersji Delphi 2009 gdzie wprowadzono obsługę Unicode zmieniono sposób obsługi stringów. PChar jest od tej pory typem 2 bajtowym i nie możesz go użyć do komunikacji z mql'em (ten spodziewa się znaków 1 bajtowych). Zamiast tego powinieneś mieć PAnsiChar.
Co do ShortString: ponieważ nadal jest to string jedno bajtowy to będzie działać z mql'em ale tutaj masz ograniczenie do 255 znaków.

Ogólnie Delphi 2009 zrobiło taką rozpierduchę z obsługą stringów, że ktoś kto wchodzi w to środowisko za cholerę nie połapie się o co kaman.
Green
Obrazek
Obrazek

dulf
Pasjonat
Pasjonat
Posty: 399
Rejestracja: 24 kwie 2010, 15:13

Re: wspoldzielenie pamieci

Nieprzeczytany post autor: dulf »

Y,ne męczymy ,taka tam wymiana poglądów.
Tez proponowałem koledze gotowe rozwiązania,tyle że nie namierzyłem akurat dobrego gotowca który by mógł łatwo zrozumieć.
http://forex-nawigator.biz/forum/zewnet ... ml#p584940
Więc dzięki za link.
Taki trochę bałagan z racji że jest początkujący w programowaniu,a ja nie znam Delphi to ciągniemy trochę na migi :d .
Napisałem najprostsze do użycia i zrozumienia ,przykładowe rozwiązanie łopatologiczne ,a dalej jeśli będzie miał ochotę się uczyć to sobie sam napisze coś w sposób jaki jemu pasuje.
Że tak powiem,trochę zaczął z wysokiego pułapu : ) .
Pozdrawiam.
Nie spiesz się , zawsze zdążysz stracić .

mlody87
Gaduła
Gaduła
Posty: 192
Rejestracja: 14 cze 2012, 13:19

Re: wspoldzielenie pamieci

Nieprzeczytany post autor: mlody87 »

Kazda pomoc jest super Panowie :) Jestem samoukiem (zaczynalem od htmla, php, potem pascal+delphi) wiec same zasady itp. rozumiem tylko czasami napotykam na jakis blad lub problem ktorego sam nie jestem w stanie rozwiazac hehe ;)
A parcie mam wiec jak tylko naprowadzicie mnie na dobra sciezke (co juz zrobiles Dulf) to bede drazyc temat az osiagne to co chcialem :)
Obrazek

ODPOWIEDZ