an unnamed file was not found

Haben Sie Fragen zur Bedienung bestimmter Features von MemBrain? Sind Sie nicht sicher, welches Häkchen was bewirkt? Möchten Sie wissen, ob eine bestimmte Funktionalität in MemBrain vorhanden ist oder nicht?

Dann stellen Sie Ihre Fragen hier!
Tuefftler
Posts: 25
Joined: Mon 9. Dec 2013, 19:40

Re: an unnamed file was not found

Post by Tuefftler »

Vielen Dank für Deine Antwort.
Ich werde es morgen gleich 'mal versuchen - vielleicht hat das ja wirklich mein Problem schon gelöst.

Wenn ich das recht verstanden habe, dann lade ich das Netz über den Aufruf der Funktion _MB_LoadNet(const char* pFileName)
und das über den MetaTrader?

Dann brauch' ich also nur die beiden folgenden Zeilen um das Netz zunächst mal einfach nur in den Metatrader zu bekommen?
string pFileName = "c:\programme\membrain\netze\aktuell.mbn" ;
_MB_LoadNet(const char* pFileName) ;

Das wär' ja einfach. Dann bekäme ich mit ein paar Rückfragen bei Dir den Rest sicher auch noch hin.

Viele Grüße
Harry
User avatar
TJetter
Posts: 346
Joined: Sat 13. Oct 2012, 12:04

Re: an unnamed file was not found

Post by TJetter »

Tuefftler wrote:Wenn ich das recht verstanden habe, dann lade ich das Netz über den Aufruf der Funktion _MB_LoadNet(const char* pFileName)
und das über den MetaTrader?
Korrekt, wobei der Ausdruck <pFileName> der Name des übergebenen Parameters ist und <const char*> den Datentyp des Parameters angibt, in diesem Fall ein Pointer auf einen C-String. Das ist in 'C' die übliche Art, konstante Strings anzugeben. C kennt keine Strings, sondern nur Arrays aus Charactern, die mit einer binären '0' abgeschlossen sind. Ein Pointer auf so einen Array wird als C-String bezeichnet.
Tuefftler wrote:Dann brauch' ich also nur die beiden folgenden Zeilen um das Netz zunächst mal einfach nur in den Metatrader zu bekommen?
string pFileName = "c:\programme\membrain\netze\aktuell.mbn" ;
_MB_LoadNet(const char* pFileName) ;
Fast: Du musst nur den Namen des Parameter übergeben, nicht auch noch seinen Typ. Also:

Code: Select all

string fileName = "c:\programme\membrain\netze\aktuell.mbn" ;
_MB_LoadNet(fileName) ;
Ich vermute, dass MetaTrader so schlau ist, die String-Variable 'fileName' bei der Übergabe an eine Dll-Funktion automatisch in einen C-String umzuwandeln. EInfach mal ausprobieren bzw. am Beispiel der anderen DLL, für die Du das Script hier gepostet hast, abkupfern. Da wurden auch Strings an die DLL übergeben, soweit ich das noch im Kopf habe.

Zwei DInge noch:
1.) Du solltest den Rückgabewert von _MB_LoadNet prüfen (ein Integer). er muss 0 sein, wenn die Funktion erfolgreich war.
2.) Evtl. musst Du beim Pfad folgende Syntax verwenden:

Code: Select all

string pFileName = "c:\\programme\\membrain\\netze\\aktuell.mbn" ;
Das hängt aber von der Scriptsprache von MetaTrade ab, und die kenne ich nicht. In C leitet ein '\' zunächst mal ein Steuerzeichen ein. Wenn man das Zeichen '\' in einem String haben will, muss man '\\' schreiben. Einfach mal ausprobieren.

Viel Erfolg und Grüße
Thomas Jetter
Tuefftler
Posts: 25
Joined: Mon 9. Dec 2013, 19:40

Re: an unnamed file was not found

Post by Tuefftler »

ok, vielen Dank - ich denke Deine letzte Antwort hat mir nochmal 'ne Menge gebracht.

Ja, das mit den Doppel-Backslashes klingt plausibel, denn das habe ich gerade vorhin in einem anderen Script
auf der Metatrader Download-Page gesehen, und mich gewundert, was das sein soll. Aber jetzt ist es mir klar.

Super!

Viele Grüße
Harry
Tuefftler
Posts: 25
Joined: Mon 9. Dec 2013, 19:40

Re: an unnamed file was not found

Post by Tuefftler »

Hallo Thomas,

falls Dir 'mal wieder jemand mit dem MetaTrader4 kommt, dann habe ich hier die Lösung zur Anbindung von MetaTrader4 (Version 4.00 Build 509 vom 24. Juni 2013) an Membrain:
Offenbar darf man im MetaTrader4 also nicht die MembrainDLL.dll-Funktionsnamen verwenden, sondern die Aliasse, wie sie in Deinem DLL-Beispiel
namens "VBA DLL-Beispiel" ersichtlich sind. Dieses "VBA DLL-Beispiel" ist im Download-Bereich des Membrain User-Forums downloadbar.


Da ich den Zugang vom MetaTrader4 auf die MembrainDLL.dll doch nicht alleine hinbekommen habe, habe ich im MetaTrader-Forum
einen DLL-Experten darum gebeten sich die Sache 'mal anzuschauen und er hat erfreulicherweise die Lösung gefunden (Man bin ich erleichtert!).
Er schreibt mir folgendes zurück und hat wohl völlig recht mit seinen geäußerten Vermutungen:

The issue is that the function names exported by MembrainDll.dll are not what you think they are. For example, the correct exported function name is __MB_GetVersionInfo@8, not MB_GetVersionInfo. It looks as though the DLL can be used from an environment such as MT4, but is designed to be used from an environment such as C++, with .h and .lib files which hide translations such as MB_GetVersionInfo to __MB_GetVersionInfo@8
To check the actual exported function names, try using a tool such as http://www.dependencywalker.com/.
N.B. This DLL will almost certainly not be usable in the next version of MT4, or not entirely usable, because the next MT4 version will require DLLs to accept Unicode strings instead of Ansi strings.


Der Quelltext, den ich hier poste, ist von mir getestet und funktioniert einwandfrei.
Mit späteren MetaTrader4-Versionen wird's allerdings ziemlich sicher nicht mehr funktionieren - schreibt er oben - weil diese nur noch Unicode-Strings und keine ANSI-Strings mehr unterstützen-
außer Deine DLL könnte später auch Unicode-Strings verarbeiten:



//+------------------------------------------------------------------+
//| membrain_test.mq4 |
//| |
//| |
//+------------------------------------------------------------------+
#property copyright ""
#property link ""




#property indicator_separate_window



#import "MemBrainDll.dll"
int __MB_GetVersionInfo@8(string pInfo, int maxLen); // hier ist der Alias zu verwenden - ALSO NICHT: int MB_GetVersionInfo(string pInfo, int maxLen);
#import




//+------------------------------------------------------------------+
int init()
{
return(0);
}

//+------------------------------------------------------------------+
int deinit()
{
return(0);
}

//+------------------------------------------------------------------+
int start()
{
string pInfo = " ";
int liMB_GetVersionInfo = __MB_GetVersionInfo@8(pInfo, StringLen(pInfo));
Print(pInfo); // Die Funktion "Print()" zeigt den gewünschten Text auf der Registerkarte "Experten" an, sofern man im Metatrader 4 im Menü "Ansicht" die Option "Terminal" aktiviert hat.




return(0);
}

//+------------------------------------------------------------------+




Viele Grüße
Harry
User avatar
TJetter
Posts: 346
Joined: Sat 13. Oct 2012, 12:04

Re: an unnamed file was not found

Post by TJetter »

Hallo Harry,

das ist klasse, Danke für den Post!
Magst Du ihn vielleicht anderswo im Forum nochmal neu anlegen, mit entsprechendem Titel?
Wir sind in diesem Thread ja nun doch ein wenig vom eigentlichen Ausgangspunkt ('an unnamed file was not found') abgewichen...
Glaube kaum, dass unter diesem Titel jemand Hilfe zur EInbindung der DLL in MetaTrader4 sucht ;-)
Tuefftler wrote:Mit späteren MetaTrader4-Versionen wird's allerdings ziemlich sicher nicht mehr funktionieren - schreibt er oben - weil diese nur noch Unicode-Strings und keine ANSI-Strings mehr unterstützen-
außer Deine DLL könnte später auch Unicode-Strings verarbeiten:
Gute Info, werde drüber nachdenken, was sich da in Zukunft machen lässt.
Tuefftler wrote:string pInfo = " ";
int liMB_GetVersionInfo = __MB_GetVersionInfo@8(pInfo, StringLen(pInfo));
Interessant, dass das funktioniert. Hätte ich nicht gedacht, und zwar aus folgendem Grund:
Der String, den Du anlegst, wird mit "" initialisiert und müsste dementsprechend die Länge 0 haben. Wenn Du aber der Funktion MB_GetVersionInfo (bzw. __MB_GetVersionInfo@8) als maximale Länge des zurückzugebenden Strings (zweiter Parameter) eine 0 übergibst, dann müsste sie eigentlich mit -1 (Fehler) zurückkehren.
Die Funktion StringLen scheint also nicht 0 für die Länge zurückzugeben, aber was dann?

Viele Grüße
Thomas Jetter
Tuefftler
Posts: 25
Joined: Mon 9. Dec 2013, 19:40

Re: an unnamed file was not found

Post by Tuefftler »

Hallo Thomas,

1.
ja, Du hast recht, der String pInfo darf nicht leer sein, sonst geht es nicht.
In meinem Beispielscript ist er auch nicht leer, sondern enthält 1 Leerzeichen - ist allerdings schwer zu erkennen, dass der String nicht leer ist.
Deshalb kommt als Print-Ausgabe im MetaTrader auch nur ein Zeichen, nämlich das "M".
Wenn man den Leerstring pInfo länger macht, dann kommt auch mehr von dem VersionsInfo-String im MetaTrader an.
Mir hatte das "M" als Lebenszeichen aber erst 'mal gereicht.

2.
ja, ich werde das Thema nochmal neu anlegen und werde den pInfo-String dann auch so lang machen,
dass der ganze String im MetaTrader geprintet wird.

3.
ich hab' leider zu früh gejubelt, denn den VersionsInfo-String bekomme ich zwar aus der DLL raus,
aber ich bekomme kein Netz rein. Ich habe leider keine Ahnung was da schon wieder nicht passt.
Vielleicht siehst Du mit geübtem C-Programmierer-Auge auf den ersten Blick was es sein könnte:

int init()
{

int successfull = 0 ; // = -1 if not successfull ;
int maxLen = 41;
int success ;



string VersionsInfo = " ";
success = __MB_GetVersionInfo@8(VersionsInfo, maxLen) ;
if(success == successfull) Print(VersionsInfo) ;
if(success != successfull) return(0) ;
Sleep(5000) ;



string FileName = "c:\\aktuell.mbn" ;


success = __MB_LoadNet@4(FileName);
Sleep(5000) ;
if(success == successfull) Print("Load Net successfull") ;
if(success != successfull)
{
Print("Load Net not successfull") ;
return(0) ;
}

return(0);
}



Viele Grüße
Harry
User avatar
TJetter
Posts: 346
Joined: Sat 13. Oct 2012, 12:04

Re: an unnamed file was not found

Post by TJetter »

Hallo,

Die folgenden Zeilen sind böse:

Code: Select all

int maxLen = 41;
int success ;



string VersionsInfo = " ";
success = __MB_GetVersionInfo@8(VersionsInfo, maxLen) ;
Und zwar deshalb:
Du legst einen String mit der Länge 1 an. Dann erlaubst Du der DLL über einen Pointer auf diesen String bis zu 41 Zeichen rein zu kopieren.
Das kann böse enden, weil die DLL damit wild in undefinierte Speicherbereiche schreiben kann.
Die richtige Herangehensweise wäre folgende:

Code: Select all

int success ;

string VersionsInfo = "---------------------------------------PLACEHOLDER_DUMMY-------------------------------------------------- ";
success = __MB_GetVersionInfo@8(VersionsInfo, StringLen(VersionsInfo)) ;
Damit reservierst Du über den Dummy-Inhalt ausreichend Länge (Speicher) und erlaubst der DLL automatisch immer nur maximal so viele Zeichen in den String zu kopieren, wie es auch seiner Größe entspricht. Wenn der Dummy Text länger ist, als das was zurückkommt, macht das nichts, die DLL setzt am Ende Ihres kopierten Textes ein String-Ende Zeichen (binäre 0).

Ich vermute. dass Du damit hinter den Kulissen etwas 'zerschießt' und deshalb der folgende Aufruf der Funktion LoadNet nicht funktioniert, denn dieser sieht erst mal OK aus.

Geht es dann?

Viele Grüße,
Thomas

PS: Warum das 'Sleep(5000)'? Der DLL-Aufruf kehrt erst zurück, wenn das Netz vollständig geladen ist, ein Sleep ist da nicht notwendig.
Thomas Jetter
User avatar
TJetter
Posts: 346
Joined: Sat 13. Oct 2012, 12:04

Re: an unnamed file was not found

Post by TJetter »

Noch eine Idee:

Könnte es an mangelnden Zugriffsrechten auf den Ordner C:\ liegen? Versuche es doch einmal aus einem anderen Ordner...

Grüße
Thomas Jetter
User avatar
TJetter
Posts: 346
Joined: Sat 13. Oct 2012, 12:04

Re: an unnamed file was not found

Post by TJetter »

Und noch eine Idee:

Vielleicht hast Du mehrere DLL-Versionen auf Deinem System rum liegen und der MetaTrader nimmt eine alte, die vom mbn-Format her nicht mehr zu Deinem Netz passt:
Durchsuche Deinen ganzen Rechner nach der MemBrain DLL-Datei. Lösche alles weg, was veraltet ist. Wenn Du die Maus im Explorer über die DLL Datei bewegst, dann siehst Du die Versionsnummer. Vergleiche diese mit dem was Du über GetVersionInfo von der DLL zurück erhältst.
Auf der Homepage im Download-Bereich findest Du die aktuelle DLL-Versions-Information, bei dem Beschreibungstext des MemBrain Download-Pakets.

Viele Grüße und Erfolg
Thomas Jetter
Tuefftler
Posts: 25
Joined: Mon 9. Dec 2013, 19:40

Re: an unnamed file was not found

Post by Tuefftler »

Hallo Thomas,

geil, jetzt geht's! Vielen Dank für Deine Korrekturen meiner Fehler und Deine Geduld.

Die DLL war überall dieselbe - und an den Berechtigungen lag es auch nicht.
Es lag tatsächlich nur an dem Dummy-String und an der Übergabe von dessen Stringlänge an die DLL.
Jetzt kann ich auch die Namen der Neuronen holen - das hatte nämlich auch nicht funktioniert, bis ich das Holen der Namen auch entsprechend
geändert habe. Den Teil des Scriptes hatte ich auch schon geschrieben, Dir aber nicht mitgeschickt.

Super!

Kann es sein, dass Neuronen-Namen nur maximal 8 Zeichen haben dürfen? Was passiert, wenn die Namen sich erst ab dem neunten
Zeichen unterscheiden? Wahrscheinlich gar nichts, weil eh alles über den Neuronen-Index geht, oder?

Schöne Feiertage wünsche ich Dir - sofern wir über die Feiertage nix membrainiges voneinander hören.
Ich experimentiere über die Feiertage weiter dran rum und mach dann, wenn ich's einigermaßen im Griff habe, ein neues Thema auf, wie "besprochen".
Wo hättest Du es denn gerne? Im Teil "Hilfe zu konkreten Projekten" oder lieber in "Rund um die Bedienung"?

Ich hätte da noch eine Frage zur Netz-Topologie: wenn man Börsendaten mit Membrain "vernudelt" und man dafür die Daten von 5 aufeinanderfolgenden Tagen verwendet, dann möchte man eventuell z.B. den Daten des aktuellsten Tages mehr "Gewicht" geben als dem davor, und diesem wiederum mehr "Gewicht" als dem davor u.s.w.
Wie bekommt man sowas sinnvoll hin?
Wäre es sinnvoll die Neuronen des aktuellsten Tages zu verfünffachen, die des Tages zuvor zu vervierfachen u.s.w. ?
Das Netz soll (nach wie vor) Zeit-invariant sein.

Viele Grüße
Harry
Post Reply