Hello,
I want to return one whole structure by function. (simple include or class)
I`ve seen that there is a way by casting the thing. https://docs.mql4.com/basis/types/casting#casting_structure
Is there another way useable now in newer versions ? - May be like that (NOT WORKING !):
It would be helpful, if I can deliver a pointer to the original structure...
Thanks for your ideas :-)
Avoid strings in structures, replace them by a fixed-length char array.
Ok, this will fix my first problem: With that I can receive a whole structure ! - Many thanks for that hint !!
On the other hand, I`m still in the smell of casting. With my code using a uchar I need two functions for writing and reading the member. So it`s only a second away from writing a simple class for handling only data-structure.
struct sTrade { uchar EaKontext[12]; long myNumber; ulong order; uchar symbol[20]; // Trade symbol name string getEaKontext(); // function forming a string for output void setEaKontext(string); // function converting a string into this uchar }; string sTrade::getEaKontext(void) { string conv; // for (int i=0;i<=12;i++) {conv+=(string)EaKontext[i];} // 2 errors here. thx gooly ! for (int i=0;i<=11;i++) {conv+=CharToString(EaKontext[i]);} // runing row ! return conv; } void sTrade::setEaKontext(string tt) { // for (int i=0;i<StringLen(tt);i++) {EaKontext[i]=StringGetChar(tt, i);} // missed the last character for (int i=0;i<=StringLen(tt);i++) {EaKontext[i]=StringGetChar(tt, i);} // correct ! } sTrade retThis() { sTrade test; //test.EaKontext = (uchar)"Content"; //string op = (string)test.EaKontext; // ERROR -> 'EaKontext' - invalid array access // because of that missing functions has to be added to the structure... test.setEaKontext("lucky ?"); string ot = test.getEaKontext(); return test; }
There is no smarter way ?
I would do define a mqh-file with the struct and all its functions:
struct sTrade { uchar EaKontext[12]; long myNumber; ulong order; uchar symbol[20]; // Trade symbol name }; string getEaKontext(sTrade &sT) { string conv; for (int i=0;i<=12;i++) {conv+=(string)EaKontext[i];} return conv; } void setEaKontext(sTrade &sT, string tt) { for (int i=0;i<StringLen(tt);i++) { sT.EaKontext[i]=StringGetChar(tt, i);} } sTrade retThis( sTrade &test ) { //test.EaKontext = (uchar)"Content"; //string op = (string)test.EaKontext; // ERROR -> 'EaKontext' - invalid array access // because of that missing functions has to be added to the structure... setEaKontext(test, "lucky ?"); string ot = getEaKontext(test); return test; }
As you can overload functions you are able to e.g. define in another mqh a function for sTrade with another struct.
What about if you define the strings globally in that mqh instead of struct-intern?
string sTrade_EAKontext, sTrade_Symbol;
PS: Are you sure that
conv+=(string)EaKontext[i];
is working? At least before b600+ we have to write:
conv =conv + (string)EaKontext[i];
I would do define a mqh-file with the struct and all its functions:
As you can overload functions you are able to e.g. define in another mqh a function for sTrade with another struct.
What about if you define the strings globally in that mqh instead of struct-intern?
PS: Are you sure that
is working? At least before b600+ we have to write:
1a) This is what I`m discussing with me. (I'm new in mql4 and MT4) A class-based-design with using structs in a module-include is not really straight. (Like a modul in VB.net) But if it fixes the issues... ok !
1b) Of course, one global variable will serve one value. But this EaKontext is going to describe much more the trading context, not the global name. On IB it`s easy to send bracket-orders. In MT4 you have to code for it. (the same with trailing-stops) This item may be helpful to check which order has which task. (Reload and changes in the orderlist are checked faster) Sure, THIS has not to be text !
2) First, the compiler was happy with the syntax ! But, you`re right. There are two errors at runtime ! I've changed it in the posting above with remarks so that there stays no false code. Thank's a lot for your skepticism :-)
(string) cast the figures to string (not wanted) So ->
string = CharToString(EaKontext[i]);
and that`s working. (checked in my build 765)
conv+=string;
Well the type cast of each single array element is now done within this function:
string = CharToString(EaKontext[i]);
To know what is faster you have to perform a speed test.
I found e.g. that
#define Pow2(a) ((a)*(a*)) ... double x = Pow2(M_LN2); // is up to 42-times faster than double y = MathPow(M_LN2,2);
Well the type cast of each single array element is now done within this function:
To know what is faster you have to perform a speed test.
I found e.g. that
faster than what ??
for (int i=0;i<=11;i++) {conv+=(string)EaKontext[i];}
Using this it comes with that: "10811799107121326300000".
for (int i=0;i<=11;i++) {conv+=CharToString(EaKontext[i]);}
returns: "lucky ?"
And this is not available: return (string)EaKontext[];
I don`t like that loop but what else ?
Abejorro: faster than what ??
| double x = Pow2(a); // is up to 42-times faster than double y = MathPow(M_LN2,2); |
Ok, this will fix my first problem: With that I can receive a whole structure ! - Many thanks for that hint !!
On the other hand, I`m still in the smell of casting. With my code using a uchar I need two functions for writing and reading the member. So it`s only a second away from writing a simple class for handling only data-structure.
There is no smarter way ?
Hi Abejorro.
Everything depends on personal style, but for me it is not very useful to create data accessors within the structure itself, because you cannot hide the structure members from public access. In my code I expect structures to be pure data with no functionality.
For converting arrays and strings use the CharArrayToString, StringToCharArray, StringToShortArray, ShortArrayToString.
As far as you mentioned the structure casting, I think the guide explains coping data between different structure types rather than casting. Though MQL4 supports inheritance and casting of structures, using the casted structures confuses some native functions like FileWriteStruct()@gooly: Yeah ! This is good stuff. There is a function CharArrayToString() and its sisters to convert without me to code a loop. I must have searched like a blind - and they do it better :-) Of course, this will be faster and smarter.
@WHRoeder: Thanks, I understood the example but didn`t see what the alternative in our discussion could be. (s.o.) And 42-times... Amazing !
@Ovo: This functions are really usefull. Now I have a workaround when a string-similar-type is necessary and I can return a structure by function !
Next is the test, if mql4 can reply an object by function like that here...And if there is plural inheritance like in c++ ?
But I`m not sure what you mean, that you can`t hide members. That is one good idea of OOP, or did I get you wrong ? I've coded my issue above to a next level using your suggestions and Polymorphism and 'Private': With that - I think - there is a simple way to prevent damages on data. You can see, there is no way to access the 'mEaKontext'-member. It's only possible using the 'property'-function and therein you can check if the things requested are allowed. On the other hand, I've not calculated what will happen on the RAM when each Data-item comes with a whole function-cocktail :-)
struct sTrade { private: uchar mEaKontext[12]; public: ulong order; uchar symbol[20]; long deal_type; string EaKontext(); // function forming a string for output void EaKontext(string); // function converting a string into this uchar }; string sTrade::EaKontext(void) { return CharArrayToString(mEaKontext, 0);} void sTrade::EaKontext(string tt) { StringToCharArray(tt, mEaKontext);} // ---------------------------------- sTrade retThis() { sTrade test; test.EaKontext("lucky ?"); string ot = test.EaKontext(); return test; }
To me it looks good - thanks a lot !
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hello,
I want to return one whole structure by function. (simple include or class)
I`ve seen that there is a way by casting the thing. https://docs.mql4.com/basis/types/casting#casting_structure
Is there another way useable now in newer versions ? - May be like that (NOT WORKING !):
It would be helpful, if I can deliver a pointer to the original structure...
Thanks for your ideas :-)