mtbf40 Posted January 11, 2012 Report Posted January 11, 2012 (edited) Hallo an alle Free-Pascaler, habe folgendes Problem:ich möchte eine dll etwickeln die mir alle Trades aus der History in eine GUI schreibt. Mit den Daten möchte ich dann weiterarbeiten. zu Testzwecken habe ich bis jetzt folgendes: DLL:library orderhist; {$mode objfpc}{$H+} uses Classes { you can add units after this }; type TOrderHist = array[0..7] of string; // function parameters declared as var will accept pointers. procedure VarsByReference(var oh: TOrderHist) ; stdcall; var Datei : TextFile; begin // now let's make some changes to the variables Assign (Datei, 'C:/Tools/mt4log.log'); ReWrite (Datei); writeln(Datei,oh[7]); close(Datei); end; exports VarsByReference; begin end. MT4://#include <common_functions.mqh> #import "orderhist.dll" void VarsByReference(string& oh[]); #import int start() { // retrieving info from trade history int k,i,hstTotal=HistoryTotal(); int HistoryOrderType; int HistoryOrderTicket; int HistoryOrderCloseTime; double HistoryOrderClosePrice; int HistoryOrderOpenTime; double HistoryOrderOpenPrice; double HistoryOrderOpenProfit; double HistoryOrderOpenStopLoss; string HistoryOrder[8]; for(i=0;i<hstTotal;i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Access to history failed with error (",GetLastError(),")"); break; } HistoryOrder[0]=OrderCloseTime(); HistoryOrder[1]=OrderClosePrice(); HistoryOrder[2]=OrderOpenTime(); HistoryOrder[3]=OrderOpenPrice(); HistoryOrder[4]=OrderProfit(); HistoryOrder[5]=OrderStopLoss(); HistoryOrder[6]=OrderTicket(); HistoryOrder[7]=OrderSymbol(); int count=ArraySize(HistoryOrder); for(k=0; k<count; k++) { //log("OrderHistoryOutput_"+k,HistoryOrder[k]); Print("blabla_"+k); } VarsByReference(HistoryOrder); } } Resultat:die DLL legt zwar die log-Datei an!! schreibt aber nur irgend welche Zeichen rein und blässt die Datei auf 100'erte MB's auf - ich muß dann schleunigst MT4 schließen, sonst legt die mir noch den Server lahm. Das mql-Skript läuft als Script im MT4. Wer weiß was hier schief läuft?? ProgrammIDE ist Lazarus Edited January 11, 2012 by mtbf40
Bull68 Posted January 11, 2012 Report Posted January 11, 2012 Hi, ich würde mir erstmal "hstTotal" anzeigen lassen, vllt läuft da schon was schief und die Schleife wird zu gross. Also erstmal schauen, ob die Schleife korrekt arbeitet. Dann könnte bei der Übergabe des Strings was schief laufen. Muss man Step bei Step eingrenzen.
mtbf40 Posted January 11, 2012 Author Report Posted January 11, 2012 Hi, ich würde mir erstmal "hstTotal" anzeigen lassen, vllt läuft da schon was schief und die Schleife wird zu gross. Also erstmal schauen, ob die Schleife korrekt arbeitet. Dann könnte bei der Übergabe des Strings was schief laufen. Muss man Step bei Step eingrenzen. die Schleife funktioniert - habe mir das mit dem Logging ausgeben lassen - über <common_functions.mqh>was ich jetzt gesehen habe ist, die DLL schreibt nur Space-Zeichen (Hex 20)
Bull68 Posted January 11, 2012 Report Posted January 11, 2012 OK, dann schreib in HistoryOrder[7] mal was anderes rein, weil nur der String wird ja in die Datei geschrieben. HistoryOrder[7] = "Test" //HistoryOrder[7]=OrderSymbol(); oder sowas, wenn dann nur Leerzeichen drin stehen, stimmt was mit "OrderSymbol()" nicht, bzw mit dem Ticket.
Der Wolf Posted January 11, 2012 Report Posted January 11, 2012 Hallo an alle Free-Pascaler, habe folgendes Problem:ich möchte eine dll etwickeln die mir alle Trades aus der History in eine GUI schreibt. Mit den Daten möchte ich dann weiterarbeiten. Bin kein Free-Pascaler.Hätte evtl. einen anderen Lösungsansatz: erstmal eine .csv-Datei mit Hilfe der MQL-Filefunktionen erzeugen. Danach manuell die Pascal-DLL aufrufen, die die .csv-Datei einliest. Erst wenn das klappt dann evtl. Erweitern auf direkten Aufruf der DLL aus dem MQL-Skript.
wh Posted January 11, 2012 Report Posted January 11, 2012 Ich bin mal zu faul ne Erklärung zu schreiben.Ich denke 7bit kann das ein wenig besser. http://www.forexfactory.com/showthread.php?t=219576 Schaue mal nach 32bit und 64bit.Schaue mal nach passing value by reference.Value kann in diesem Fall ein Integer, Double, String bzw. auch ein Array sein. Schaue auch mal hier: http://www.lazarus.freepascal.org/index.php?topic=13607.0 und http://wiki.lazarus.freepascal.org/Passing_Pascal_Types_to_C_Routines. 1
mtbf40 Posted January 11, 2012 Author Report Posted January 11, 2012 erst einmal Danke für die Antworten - muß jetzt erst einmal alles sondieren - wo ich wahrscheinlich das Problem sehe ist, das die dll eine 64bit-compillierte ist. Muß jetzt mal die 32bit Version von Lazarus installieren, denn auf meinem Laptop und auf dem MT4 Server laufen jeweils Win7 64bit mit Lazarus 64bit FALLS jemand eine Lösung "geschrieben" hat - möge er sie nur für sich behalten!!
mtbf40 Posted January 13, 2012 Author Report Posted January 13, 2012 so - habe jetzt Lazarus-Versionen für 32bit und 64bit parallel installiert!DLL 32bit kompilliert und peng Datei >1GB was ich bis jetzt herausgefunden habe ist folgendes: die meisten Konstrukte von DLL<-> MT4 laufen so: MT4 ruft Funktion aus DLL auf-> DLL macht was -> gibt Ergebnis zurück an MT4ich möchte aber dies machen: MT4 ruft Funktion aus DLL auf-> DLL macht was -> schreibt Ergebnisin eine Datei Ich habe keinen blassen Schimmer warum er nur 0x20 Zeichen reinschießt. Habe das ganze mal mit dem Procmon (Sysinternals) verfolgt - da sieht man wie die Zeichen in nano-Sekunden reinschießen. Ich muß dann MT4 schließen um nicht meinen Server lahm zu legen. Ich habe den Eindruck das der MT4 das Skript "hält", obwohl es ja ein Skript ist und nur einmal aufgerufen wird und das wars dann. Denn das Skript wird erst geschlossen, wenn ich MT4 (terminal.exe) schließe - und zwar als letzte Aktion!!!Würde ja gern mal einen Screenshot zeigen - kann aber nix hochladen Fehler 407
Vola Posted January 13, 2012 Report Posted January 13, 2012 Würde ja gern mal einen Screenshot zeigen - kann aber nix hochladen Fehler 407Da wir uns ja im rechtsfreien Raum bewegen (kein Mod anwesend)Was für einen Datei Typ willst du hochladen ? jpeg, PNG usw. geht bei mir einwandfrei.
mtbf40 Posted January 13, 2012 Author Report Posted January 13, 2012 (edited) Da wir uns ja im rechtsfreien Raum bewegen (kein Mod anwesend)Was für einen Datei Typ willst du hochladen ? jpeg, PNG usw. geht bei mir einwandfrei. png-File - 299k mt4_dll.pngDas hochladen dieser Datei wurde übersprungen. (Fehler IO) Edited January 13, 2012 by mtbf40
Vola Posted January 13, 2012 Report Posted January 13, 2012 Hmm, da müssen andere ran, ich könnte den identischen Dateinamen hochladen.
mtbf40 Posted January 13, 2012 Author Report Posted January 13, 2012 (edited) Hmm, da müssen andere ran, ich könnte den identischen Dateinamen hochladen. bin mal auf einen anderen rechner gegangen... man beachte den Zeitsprung!! mit Pfeil markiert.. Edited January 13, 2012 by mtbf40
wh Posted January 13, 2012 Report Posted January 13, 2012 Dez Hex Okt ASCII32 0x20 040 SP Code 0x20 (SP) ist das Leerzeichen.Da geht immer noch etwas schief.Es gibt zwei Ansätze Daten zws. zwei unterschiedlichen Systemen zu schaufeln. Pass By Reference : In Pass by reference address of the variable is passed to a function. Whatever changes made to the formal parameter will affect to the actual parameters - Same memory location is used for both variables.(Formal and Actual)- - it is useful when you required to return more then 1 values Pass By Value: - In this method value of the variable is passed. Changes made to formal will not affect the actual parameters. - Different memory locations will be created for both variables. - Here there will be temporary variable created in the function stack which does not affect the original variable. Metatrader ist 32bit und es wird wohl keine 64bit Version geben. Wenn dem nicht so ist, nehme ich diese Aussage zurück.Du mußt auf jedem Fall Pascal mit 32bit kompelieren. Warum schreibt du dir nicht erstmal eine kleine C-Anwendung. Metatrader ist, glaube ich, in Delphi geschrieben. Vielleichtauch mal ein kleines Delphi Programm. Beispiele gibt es sicher im Netz.
mtbf40 Posted January 13, 2012 Author Report Posted January 13, 2012 Metatrader ist 32bit und es wird wohl keine 64bit Version geben. Wenn dem nicht so ist, nehme ich diese Aussage zurück.Du mußt auf jedem Fall Pascal mit 32bit kompelieren. ist doch alles mit 32bit kompiliert !! Warum schreibt du dir nicht erstmal eine kleine C-Anwendung. Metatrader ist, glaube ich, in Delphi geschrieben. Vielleichtauch mal ein kleines Delphi Programm. Beispiele gibt es sicher im Netz. Wenn Metatrader in Delphi programmiert ist, sollte es auf jeden Fall reibungslos funktionieren, denn Freepascal (Lazarus) ist nahezu Delphi kompatibel!
Bull68 Posted January 13, 2012 Report Posted January 13, 2012 "HistoryOrder" würde ich mal als "static" deklarieren, ist aber nur ein Versuch, weil Du ja dennoch verschieden Zeigerformate hast (32bit zu 64bit).
RAiNWORM Posted January 15, 2012 Report Posted January 15, 2012 Wer weiß was hier schief läuft??1. Dein rewrite überschreibt die Datei immer wieder. Wahrscheinlich willst du doch die Datei ergänzen, oder?2. Die String-Typen sind nicht kompatibel. Und ein Array von Strings ist eine ganz andere Hausnummer (Zeiger auf eine Liste von Zeigern). Ich habe etwa einen Monat gebraucht, um Strings auszutauschen (Delphi-DLL) und ich bezeichne mich eigentlich als recht guten Programmierer. Was ist ein String? Die Variable beinhaltet einen Zeiger auf das erste Byte. Jedes Byte repräsentiert einen character. Der String endet mit Byte-Wert 00. Blöd ist nur, dass Free Pascal oder Delphi unter dem Typ String etwas vollkommen anderes verstehen. Das erste Byte ist hier die Länge des Strings. Dann folgen die Characters. Seit einigen Versionen werden die jedoch Unicode gespeichert, sodass ein Zeichen einem Byte ist. Lösung:Übergib einen Zeiger auf das erste Zeichen. Dies wird durch den "normalen" string-Typ von MT4 veranlasst. Auf DLL-Seite empfängst du diesen Zeiger und baust dir deinen String byteweise selbst zusammen. Danach kannst du frei agieren. Das mit dem String-Array würde ich lassen, da es noch komplexer wird und auch anderweitig abbildbar wäre. Möchtest du selber probieren oder Codebeispiele? 2
mtbf40 Posted January 15, 2012 Author Report Posted January 15, 2012 1. Dein rewrite überschreibt die Datei immer wieder. Wahrscheinlich willst du doch die Datei ergänzen, oder?2. Die String-Typen sind nicht kompatibel. Und ein Array von Strings ist eine ganz andere Hausnummer (Zeiger auf eine Liste von Zeigern). Ich habe etwa einen Monat gebraucht, um Strings auszutauschen (Delphi-DLL) und ich bezeichne mich eigentlich als recht guten Programmierer. Was ist ein String? Die Variable beinhaltet einen Zeiger auf das erste Byte. Jedes Byte repräsentiert einen character. Der String endet mit Byte-Wert 00. Blöd ist nur, dass Free Pascal oder Delphi unter dem Typ String etwas vollkommen anderes verstehen. Das erste Byte ist hier die Länge des Strings. Dann folgen die Characters. Seit einigen Versionen werden die jedoch Unicode gespeichert, sodass ein Zeichen <> einem Byte ist. Lösung:Übergib einen Zeiger auf das erste Zeichen. Dies wird durch den "normalen" string-Typ von MT4 veranlasst. Auf DLL-Seite empfängst du diesen Zeiger und baust dir deinen String byteweise selbst zusammen. Danach kannst du frei agieren. Das mit dem String-Array würde ich lassen, da es noch komplexer wird und auch anderweitig abbildbar wäre. Möchtest du selber probieren oder Codebeispiele? danke für die Hinweise. habe jetzt mal folgendes versucht:Änderungen in DLL: cdecl deklariert und Type PChar Änderungen in MT4: HistoryOrder[0]="Test"; HistoryOrder[1]="Test1"; library orderhist; {$mode objfpc}{$H+} uses Windows,Classes { you can add units after this }; type TOrderHist = array[0..7] of PChar; // function parameters declared as var will accept pointers. //procedure VarsByReference(var oh: TOrderHist) ; stdcall; procedure VarsByReference(var oh: TOrderhist) ; cdecl; var Datei : TextFile; begin // now let's make some changes to the variables Assign (Datei, 'C:/Tools/mt4log.log'); ReWrite (Datei); writeln(Datei,oh[1]); close(Datei); end; exports VarsByReference; begin end. Resultat: die DLL schreibt jetzt zumindest Test!! rein - trotzdem alles merkwürdig - vor allem: wieso "funktioniert" es plötzlich mit cdecl?? Fazit: würde gern mal ein paar Code-Schnipsel bekommen mtbf40
wh Posted January 15, 2012 Report Posted January 15, 2012 Schaue mal hier: http://de.wikibooks.org/wiki/Programmierkurs:_Delphi:_Pascal:_Zeiger Zeiger verweist anders auf deinen Speicher.
RAiNWORM Posted January 16, 2012 Report Posted January 16, 2012 Fazit: würde gern mal ein paar Code-Schnipsel bekommen Dann bastel mal hier mit. MT4: #import "meine.dll" void an_dll(string send); #import //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { string strSend; strSend = Symbol()+";"+Bid+";"+Ask+";"+TimeToStr(TimeCurrent(), TIME_DATE|TIME_SECONDS); an_dll(strSend); return(0); } //+------------------------------------------------------------------+ Delphi (ich hoffe, es passt auch für FreePascal) uses ... type Tbytes = array [0..200] of byte; procedure an_dll(cc : Tbytes); stdcall; var strText : String; ii : integer; begin strText := ''; for ii := 0 to 200 do begin strText := strText + chr(cc[ii]); if cc[ii] = 00 then break; end; try MessageDlg(strText, mtWarning, [mbOK], 0); except on e : exception do begin MessageDlg(e.Message, mtError, [mbOK], 0); end; end; end; exports an_dll; begin ; end. Das wäre ein Beispiel für call by value mit statischer Speicherreservierung für die Übergabe und simpler Umsetzung. Ist übrigens auch ein schönes Beispiel, wie Exploits entstehen können (Übergabe von mehr als 200 Byte und dadurch Überschreiben des Speichers mit Malware-Code).
mtbf40 Posted January 16, 2012 Author Report Posted January 16, 2012 (edited) Dann bastel mal hier mit. Das wäre ein Beispiel für call by value mit statischer Speicherreservierung für die Übergabe und simpler Umsetzung. Ist übrigens auch ein schönes Beispiel, wie Exploits entstehen können (Übergabe von mehr als 200 Byte und dadurch Überschreiben des Speichers mit Malware-Code). Danke RAiNWORM für den Code! wenn mal alles auf Anhieb klappen würde - jetzt findet das -Programm (Lazarus) den Identifier <MessageDlg> nicht mache für heute Schluß - morgen ist auch noch ein Tag fürs "blöd" werden Edited January 16, 2012 by mtbf40
RAiNWORM Posted January 17, 2012 Report Posted January 17, 2012 wenn mal alles auf Anhieb klappen würde - jetzt findet das -Programm (Lazarus) den Identifier nicht In Delphi müsste man dazu die Unit Dialogs in die uses oben aufnehmen. Die Funktion sollte einfach den übergebenen String in einer Messagebox ausgeben. Kannst du nach Belieben ersetzen.
mtbf40 Posted January 17, 2012 Author Report Posted January 17, 2012 Dann bastel mal hier mit. MT4: #import "meine.dll" void an_dll(string cc); //<----- 1. Änderung statt send <-> cc #import //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { string strSend; strSend = Symbol()+";"+Bid+";"+Ask+";"+TimeToStr(TimeCurrent(), TIME_DATE|TIME_SECONDS); an_dll(strSend); return(0); } //+------------------------------------------------------------------+ Delphi (ich hoffe, es passt auch für FreePascal) uses ... type Tbytes = array [0..200] of byte; procedure an_dll(cc : Tbytes); stdcall; var strText : String; ii : integer; begin strText := ''; for ii := 0 to 200 do begin strText := strText + chr(cc[ii]); if cc[ii] = 00 then break; end; try MessageDlg(strText, mtWarning, [mbOK], 0); except on e : exception do begin MessageDlg(e.Message, mtError, [mbOK], 0); end; end; end; exports an_dll; begin ; end. Das wäre ein Beispiel für call by value mit statischer Speicherreservierung für die Übergabe und simpler Umsetzung. Ist übrigens auch ein schönes Beispiel, wie Exploits entstehen können (Übergabe von mehr als 200 Byte und dadurch Überschreiben des Speichers mit Malware-Code). so!!! habe jetzt alles zum laufen bekommen - dll kompiliert mt4-Skript erstellt und PENG Error in MT4 function 'an_dll' call from dll 'meine.dll' critical error - bekommst Du auch diesen Fehler?? habe im mt4-Skript eine Änderung gemacht: siehe oben - Variable send mit cc ersetzt - muss nicht der gleiche Name für die Variable im mt4-Skript und in der dll existieren?
mtbf40 Posted January 17, 2012 Author Report Posted January 17, 2012 update: die dll hat es sich anders überlegt und produziert nun keinen Fehler mehr!! warum auch immer... ABER: es popt kein Message-Dialog auf ... bin weiter am ausprobieren
wh Posted January 17, 2012 Report Posted January 17, 2012 update: die dll hat es sich anders überlegt und produziert nun keinen Fehler mehr!! warum auch immer... ABER: es popt kein Message-Dialog auf ... bin weiter am ausprobieren Setze mal nur zum Test in deine GUI ein. var buttonSelected : Integer; begin // Show a custom dialog buttonSelected := MessageDlg('Custom dialog',mtCustom, [mbYes,mbAll,mbCancel], 0); // Show the button type selected if buttonSelected = mrYes then ShowMessage('Yes pressed'); if buttonSelected = mrAll then ShowMessage('All pressed'); if buttonSelected = mrCancel then ShowMessage('Cancel pressed'); end;
mtbf40 Posted January 17, 2012 Author Report Posted January 17, 2012 die Messages funktionieren - was ich jetzt festgestellt habe ist, das mt4-Skript ruft die Funktion aus der DLL überhaupt nicht auf - ich //#include <common_functions.mqh> #import "meine.dll" void an_dll(string cc); #import //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { string strSend; strSend = Symbol()+";"+Bid+";"+Ask+";"+TimeToStr(TimeCurrent(), TIME_DATE|TIME_SECONDS); //log("StrSend_"+strSend); return(0); } dazu habe ich die Bestätigung eingeschaltet das ich DLL-Aufrufe betätigen muß - und da kommt nix mit "klick mal ok" entweder steckt da der Teufel dahinter oder PH!!
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now