MT4 DLL-geheugenvervuiling
Page 1 of 635 123 ... LastLast
Results 1 to 10 of 41

Thread: MT4 DLL-geheugenvervuiling

  1. #1
    Hallo jongens,

    Ik heb een intermitterende (heb een liefde die degenen) met een EA en een DLL-ive geschreven. De EA werkt op 5 verschillende paren, maar de informatie die wordt doorgegeven aan de DLL is in essentie dezelfde, zij het verschillende, werkelijke waarden.

    Het probleem dat ik heb is dat gegevens van het ene paar worden opgehaald door de EA op een ander paar. Ik stuur bijvoorbeeld naar de EA-gegevens om de juiste lotgrootte te berekenen, als ze individueel worden uitgevoerd, werken ze prima, soms als ze allemaal tegelijk worden uitgevoerd, krijgen ze allemaal dezelfde lots.

    Ik lees ergens hier dat wanneer je vanuit meerdere kaarten toegang hebt tot een enkele DLL zoals deze, je feitelijk dezelfde geheugenruimte deelt, wat de conclusie was die ik heb bereikt, het is bijna willekeurig wat de gegevens zijn die ik in de array nodig heb om te schrijven opgepikt worden door de DLL. Oh op dat punt im met behulp van verwijzingen. hier is de DLL-verklaring:

    #import xxx.dll
    bool f1 (string arr1 [10], double arr2 [40], double rates1 [2000] [6], double rates2 [2000] [6]);
    dubbele f2 (string arr1 [10], dubbele arr2 [40], dubbele rates1 [2000] [6], double rates2 [2000] [6]);

    Heb ik gelijk in mijn idee van wat het probleem is, zo ja, is er dan een redelijke oplossing anders dan het DLL-proces voor elk paar te verdubbelen?

    bij voorbaat dank

  2. #2
    Ik denk dat je diagnose dood is. Ik veronderstel dat het schrijven van gegevens voor het scheiden van. CSV-bestanden niet beter is dan het hebben van afzonderlijke DLL's. Een ander idee zou zijn om een ??????booleaanse parameterwaarde als een semafoor te laten werken en als deze op bezet is ingesteld, wordt een andere EA geblokkeerd. Zodra de eerste EA klaar is, wordt deze gereset naar gereed en krijgt de andere toegang tot het DLL-bestand. MT4 is niet echt goed in het afhandelen van evenementen, maar ik veronderstel dat er misschien een manier is om dit ook te implementeren. Het hangt allemaal af van hoe vaak de DLL-code wordt aangeroepen (zoals voor elke nieuwe balk of nieuw vinkje of eenmaal per activering) en de waarschijnlijkheid van meerdere toegangen.

  3. #3
    Gebruik een c .exe die een gedeelde geheugenruimte opzet en vervolgens toegang tot de gedeelde geheugenruimte via uw dll-oproep van metatrader. Voor meerdere paren moet u waarschijnlijk meerdere arrays voor gedeeld geheugen instellen, die elk toegankelijk zijn via afzonderlijke dll's. Ik heb dit gedaan en het werkte voor mij.

  4. #4
    Helaas bent u onduidelijk over uw implementatie. Zoals ik het begrijp: 1) geeft EA gegevens door aan DLL (door verwijzing? (Verwijzingen)) 2) Uw DLL-kopie�n? deze gegevens in zijn eigen variabelenalloed memory 3) je DLL gebruikt deze data nu in zijn eigen variabelen om de waarden te berekenen om terug te keren naar MT4 4) Je DLL retourneert waarden naar je EA (door referentie? (pointers)) Als dit het geval is waarom codeer je je dll niet om aparte sets arrays te gebruiken. Je kunt toch niet verwachten dat een enkele loion 5 taken uitvoert wanneer die taken uit verschillende threads lopen! dus in uw dll 1) voeg een nieuwe dimensie toe aan uw arrays (��n voor elk paar ( een paar) -of dynamisch deze beheren) 2) voeg een initialisatiefunctie toe waarbij uw MT4 EA een unieke ID aanvraagt ??????en retourneert die kan worden gebruikt om referentie zijn eigen array-set. EG. EA-code # import # dubbele f2 (Int ID, string arr1 [10], double arr2 [40], double rates1 [2000] [6], double rates2 [2000] [6]);/Global int myid .. .. myid = Request_DLL_ID (); als myid = -1 dan fout f2 (myid, string arr1 [10], double arr2 [40], dubbele rates1 [2000] [6], double rates2 [2000] [6]); Het ID-nummer dat door uw DLL wordt geretourneerd, is misschien slechts een uniek nummer met een bijbehorende opzoeklijst om een ??????echte array-dimensie toe te voegen of de werkelijke array-dimensie zelf te zijn.

  5. #5

    Quote Originally Posted by ;
    Heb ik gelijk in mijn idee van wat het probleem is, zo ja, is er dan een redelijke oplossing anders dan het DLL-proces voor elk paar te verdubbelen?
    Er zijn twee oplossingen voor dit probleem, geen van deze impliceert het dupliceren van de dll. 1.) alle parameters doorgeven aan alle functies * altijd * als functieargumenten voor alle functies in de dll, zodat er helemaal geen globale variabelen in de DLL voorkomen. Geef alleen verwijzingen door naar grotere datastructuren, dingen zoals dubbele foo [] van mql, zodat je niet teveel gegevens hebt om te pushen en uit de stapel te springen bij elke functieaanroep. 2.) zet al uw functies van de dll en de globale gegevens die het deelt in een klasse en op init () van uw EA-aanroep een functie in de dll die een nieuwe objectinstantie uit deze klasse zal maken en een verwijzing naar deze instantie retourneert . U kunt deze 32-bits pointer veilig in een 32-bit int-variabele casten die naar mql4 wordt teruggestuurd en in uw EA wordt opgeslagen. De API van uw dll moet nu bestaan ??????uit functies die dit gehele getal als eerste parameter accepteren. Voor elke methode die u op uw object wilt gebruiken, schrijft en exporteert u een wrapper die de aanwijzer naar het object als eerste parameter accepteert. Je EA zal deze wrapper-functies oproepen met een eigen int-nummer en de wrapper-functies in de dll werpen de int terug in de aanwijzer naar het object dat bij die EA hoort en roepen vervolgens de corresponderende methoden op dat object aan. De eerste (helemaal geen globale variabelen) is gemakkelijker te implementeren. De tweede wordt aanbevolen voor meer complexe dingen, in deze gevallen gebruik je echter OOP. Aangezien dit alleen zal worden gebruikt op 32bit-vensters, is het volkomen veilig om de aanwijzingen door te geven. Als u om welke reden dan ook geen pointers wilt casten en doorgeven tussen dll en EA, kunt u ook een soort hash-tabel of dynamische array gebruiken of wat dan ook uw runtime-bibliotheek of -toolkit te bieden heeft om de aanwijzer op te slaan object in de dll zelf en geef iets meer draagbaar (een string of een handvat) door als sleutel van en naar de EA. Dit zou natuurlijk de prestaties be�nvloeden.

  6. #6
    Als u besluit om de eerste route te gaan (waarbij u alle paramters altijd als functieargumenten doorgeeft), is het een goede gewoonte om vanaf het allereerste begin het volgende te doen: Stel u voor dat uw EA de volgende (fictieve) externe instellingen heeft: Code extern dubbele ex_foo; externe dubbele ex_bar; externe dubbele ex_periode; externe dubbele ex_gamma; externe dubbele ex_delta; en de volgende globale variabelen die kunnen veranderen tijdens de werking en die ook nodig zijn voor veel van de functies: Ingevoegd Code double last_high; dubbele last_low; Doe het volgende: definieer benoemde constanten voor de indices zoals deze: Ingevoegde code #define I_FOO 0 #define I_BAR 1 #define I_PERIOD 2 #define I_GAMMA 3 #define I_DELTA 4 #define I_LAST_HIGH 5 #define I_LAST_LOW 6 # 91; color = SeaGreen # 93;/de max. grootte van de array # 91;color # 93; #define I_SIZE 7 en een globale array ingevoegde code double global # 91; I_SIZE # 93 ;; int init () {# 91; color = SeaGreen # 93;/externals # 91;color # 93; global # 91; I_FOO # 93; = ex_foo; global # 91; I_BAR # 93; = ex_bar; global # 91; I_PERIOD # 93; = ex_period; global # 91; I_GAMMA # 93; = ex_gamma; global # 91; I_DELTA # 93; = ex_delta; # 91; color = Zeegroencolor # 93;/initialiseer andere globalen # 91;color # 93; global # 91; I_LAST_HIGH # 93; = 0; global # 91; I_LAST_LOW # 93; = 0; } roep uw functies op in de dll Inserted Code int result = dllfunc (globals, ...); en in de dll hebt u dezelfde constanten gedefinieerd als hierboven kunt u eenvoudig het volgende doen. (voor dit voorbeeld nemen we aan dat het dll in pascal is, dus het wordt hier niet te saai
    . Het heeft geen invloed op het probleem dat we proberen op te lossen, het is van toepassing op alle talen. Als u al C code kunt lezen, kunt u intu�tief de veel eenvoudigere (object-) pascalcode lezen en begrijpen, en het concept probleemloos in de door u gewenste taal vertalen) Ingevoegde Code # 91; b # 93; bibliotheek # 91;b # 93; myholygrail; # 91; b # 93; const # 91;b # 93; I_FOO = 0; I_BAR = 1; I_PERIOD = 2; I_GAMMA = 3; I_DELTA = 4; I_LAST_HIGH = 5; I_LAST_LOW = 6; I_SIZE = 7; # 91; b # 93; type # 91;b # 93; TGlobals = array # 91; 0..I_SIZE-1 # 93; van dubbel; # 91; b # 93; functie # 91;b # 93; dllfunc (# 91; b # 93; var # 91;b # 93; global: TGlobals; ...): integer; STDCALL; # 91; b # 93; var # 91;b # 93; foo: dubbel; hoog: dubbel; # 91; b # 93; # 91 beginnen;b # 93; foo: = global # 91; I_FOO # 93 ;; # 91; color = Zeegroencolor # 93;/doe wat dingen # 91;kleur # 93; global # 91; I_LAST_HIGH # 93; : = hoog; # 91; color = Zeegroencolor # 93;/doe nog wat meer dingen # 91;kleur # 93; # 91; color = Zeegroencolor # 93;/... # 91;color # 93; # 91, # 93 b, uiteinde; # 91;b # 93; # 91; b # 93; # 91 uitvoert;b # 93; dllfunc; # 91, # 93 b; beginnen # 91;b # 93, # 91, # 93 b; einde. # 91;b # 93; De reden hiervoor is dat je later meer parameters, meer globale variabelen aan deze array kunt toevoegen en het enige dat je moet veranderen, is de definitie van deze constanten. De code zal altijd leesbaar zijn, je zult nooit letterlijke getallen gebruiken zoals global [42], always global [I_SOMETHING] en het hoeft je niet te schelen of het zich daadwerkelijk op positie 42 of ergens anders bevindt.

  7. #7
    Hallo jongens, Bedankt voor al je reacties, het is geweldig om een ??????community te hebben met zulke deskundige mensen die bijdragen. 7bit: als ik je goed begrijp, zeg je dat het echte probleem is dat ik de arrays op positie riep, bijvoorbeeld arr2 [25] in plaats van elk element afzonderlijk expliciet te defini�ren en ernaar te verwijzen? het DLL-bestand heeft geen algemene variabelen binnen zichzelf, alle variabelen die daaraan worden doorgegeven, zijn alleen lokaal voor de functie. RangeBound: Wat het doen is het maken van een dubbele array binnen MT4, krijgt dit toegang tot de DLL door middel van een aanwijzer. De functie kijkt naar sommige elementen ervan, doet wat wiskunde en schrijft vervolgens naar een ander element in diezelfde array de outputwaarde, in dit geval lotsize. Diezelfde outputwaarde (arr2 [19]) wordt voor alle paren gebruikt, en wat ik zie is dat een groot formaat bestemd is voor een ander paar dat ergens anders terechtkomt. Ik heb er wel eens over nagedacht om voor elk daarvan meerdere arrays te gebruiken, maar wilde precies weten waar het probleem zit, voordat ik het verder compileer. in het begin lijkt het erop dat de 7bits-oplossing eenvoudiger is, maar ik zou graag opmerkingen hierover ontvangen. Nogmaals bedankt.

  8. #8

    Quote Originally Posted by ;
    : Als ik u goed begrijp, zegt u dat het echte probleem is dat ik de arrays per positie aanroer, bijvoorbeeld arr2 [25] in plaats van elk element afzonderlijk expliciet te defini�ren en ernaar te verwijzen?
    Nee, niet echt, het draait allemaal om leesbaarheid (en dus om fouten te voorkomen). Wat ik wilde zeggen, is dat het gebruik van arr [MEANINGFUL_NAME] in plaats van arr [25] slechts een handige manier is om de code leesbaar en onderhoudbaar te houden. Op deze manier kunt u eenvoudig ALLE globalen in EEN array proppen en slechts ��n aanwijzer doorgeven en toch iets gemakkelijk leesbaar hebben zonder programmeerfouten te veroorzaken door per ongeluk de array-indices te verwarren of te vergeten de getallen op alle plaatsen te veranderen wanneer u besluit de structuur te veranderen van dat array later. overweeg deze code: Insert Code scale # 91; I_SCALE # 93; : = (prijsbereik # 91; I_HIGH # 93; - prijsbereik # 91; I_LOW # 93(pattern_size # 91; I_HIGH # 93; - pattern_size # 91; I_LOW # 93; schaal # 91; I_OFFSET # 93; : = prijsbereik # 91; I_LOW # 93; - pattern_size # 91; I_LOW # 93; * schaal # 91; I_SCALE # 93 ;; en vergelijk het met dit: ingevoegde codeschaal # 91; 0 # 93; : = (prijsbereik # 91; 1 # 93; - prijsbereik # 91; 0 # 93(pattern_size # 91; 1 # 93; - pattern_size # 91; 0 # 93; schaal # 91; # 1 93; : = prijsbereik # 91; 0 # 93; - pattern_size # 91; 0 # 93; * schaal # 91; 0 # 93 ;; Het doet hetzelfde, compileert naar dezelfde machinecode maar welke is beter leesbaar? Dezelfde code verschijnt later met een omgekeerd patroon, laag wordt hoog en hoog wordt laag, wat denk je, hoe lang moet ik daar zitten en staren naar deze twee regels als ik per ongeluk 0 en 1 verward als ik geen benoemde constanten gebruikte ? Het gaat erom mogelijke oorzaken van programmeerfouten te verminderen.
    Quote Originally Posted by ;
    het DLL-bestand heeft geen algemene variabelen binnen zichzelf, alle variabelen die daaraan worden doorgegeven, zijn alleen lokaal voor de functie.
    Dan zou je initieel geposte probleem niet moeten voorkomen, en als het voorkomt, wordt dit niet veroorzaakt door het feit dat de functies in een DLL leven. Variabelen die worden doorgegeven als argumenten en die lokaal zijn gedeclareerd voor de functie, staan ??????altijd op de stapel, wat betekent dat elke thread die deze functies op hetzelfde moment gebruikt zijn eigen ruimte heeft voor de variabelen (omdat elke thread met zijn eigen stapel zal komen) en elke EA-instantie kan worden beschouwd als een andere thread voor ons probleem). Verder, wanneer een functie wordt aangeroepen, zal deze altijd nieuwe ruimte op de stapel reserveren en wanneer een functie terugkeert, wordt de stapel altijd in exact dezelfde staat teruggebracht, net als toen de functie werd aangeroepen. Lokale variabelen kunnen eenvoudig niet per ongeluk worden voortgezet en verschijnen na de huidige functieaanroep. Er moet een andere oorzaak zijn voor het gedrag dat u waarneemt. Er moet ergens een goed verborgen vervelende programmeerfout zijn (niet noodzakelijk in de dll) in je code.

  9. #9
    Bedankt voor het antwoord. Gewoon om 100% te bevestigen dat ik niet lokaalglobaal in de war raak, hier is de DLL-functie die zorg veroorzaakt: bool get_lotsize (MqlStr * arr1, double * arr2, const RateInfo * rates1, const RateInfo * rates2, double stop_loss)/geeft lotgrootte {doubleriskvalue, pipvalue, lotsize; riskvalue = (arr2 [10] * (arr2 [7]100))arr2 [11]; pipvalue = arr2 [8]; if (arr2 [1] == 5 || arr2 [1] == 3) pipvalue * = 10; lotize = riskvalue(stop_loss * pipvalue); lotize = floor (lotizearr2 [4]) * arr2 [4]; if (lotsize lt; arr2 [5]) lotize = arr2 [5];/min. veel als (lotsize gt; arr2 [6]) lotize = arr2 [6];/max lot arr2 [19] = lotize; terugkeer (true); } gewoon kijken naar dit eigenlijk stop_loss IS een DLL globale variabele. zijn verklaard in de kopbal van DLL, zou deze variabele aanhoudend tussen alle vraag aan dat DLL zijn? Als dat zo is, hebben we het probleem gevonden

  10. #10

    Quote Originally Posted by ;
    gewoon kijken naar dit eigenlijk stop_loss IS een DLL globale variabele. zijn verklaard in de kopbal van DLL, zou deze variabele aanhoudend tussen alle vraag aan dat DLL zijn? Als dat zo is, hebben we het probleem gevonden
    een variabele gedeclareerd in de dll buiten de functies zou worden gedeeld met alle functieaanroepen van alle threads (alle EA's). Wat me hier afvraagt, is wat er gebeurt met dezelfde variabele die wordt vermeld in de argumentenlijst van de functie. Normaal gesproken zou de lokale variabele dan de prevalentie boven dezelfde variabele buiten de functie moeten hebben, maar mijn C-kennis is beperkt. Echter, of uw C-compiler dit correct zal behandelen of niet, zo'n naambotsing is altijd een probleem, waardoor programmeerfouten waarschijnlijker worden en detectie moeilijker wordt. U moet alle globale variabele declaraties verwijderen van de functies in de dll.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
This website uses cookies
We use cookies to store session information to facilitate remembering your login information, to allow you to save website preferences, to personalise content and ads, to provide social media features and to analyse our traffic. We also share information about your use of our site with our social media, advertising and analytics partners.