Yes, your are totally right. It was just some fast copy/paste from me. This is more like I have done it. It could be more ways to do this but this is how I ended up, and it works.
I did some investigation into this, and it seems you need to tread very
carefully when dealing with passed strings. The code sample above is
unsafe and could cause a crash.
The first part of the problem comes in the MqlStr struct reference - it
seems that while MQL4 reserves 4 bytes for the string size, it doesn't
populate the length field (my code showed 0 for the size) so you can't
use that to determine the size of the buffer. As such, you will need to
pre-define a contract on the string size (some max size would be a safe
bet).
The second part is the code above can easily cause a buffer overrun.
While you are properly allocating the buffer size of the source string
(new char[5]), the destination buffer you are copying into
(fieldValue[0].string) is an unknown size. If it is less than 5 bytes, then you
are causing a buffer overrun.
Here's an example: C++ snippet
strcpy(fieldValue[0].string, "1234Buffer Overrun"); //
fieldValue is a struct MqlStr
MQL4 snippet:
string fieldValue[2] = { "Hi",
"Happy Days Are Here" };
ExternalFunction(fieldValue); // This executes the C++ code above
string fixString = fieldValue[1];
MessageBox(fixString);
What happened here is the strcpy overran the buffer of
fieldValue[0] and right on top of fieldValue[1]. In fact, the text in
MessageBox will be "Buffer Overrun".
With that said, there is a way around this, but I
strongly recommend against it for anything besides proof-of-concept code. C++ snippet:
fieldValue[0].string
= "Hack";
Basically, this is replacing the pointer that MQL4 is using
for the string. However, you have now leaked the old fieldValue[0].string, and you don't know which cleanup method MQL4 might attempt to use on your string (which itself could cause a crash). If one of the MQL4 programmers told us some of the inner workings regarding strings, this could be made safe.
I did some investigation into this, and it seems you need to tread very
carefully when dealing with passed strings. The code sample above is
unsafe and could cause a crash.
The first part of the problem comes in the MqlStr struct reference - it
seems that while MQL4 reserves 4 bytes for the string size, it doesn't
populate the length field (my code showed 0 for the size) so you can't
use that to determine the size of the buffer. As such, you will need to
pre-define a contract on the string size (some max size would be a safe
bet).
The second part is the code above can easily cause a buffer overrun.
While you are properly allocating the buffer size of the source string
(new char[5]), the destination buffer you are copying into
(fieldValue[0].string) is an unknown size. If it is less than 5 bytes, then you
are causing a buffer overrun.
Here's an example: C++ snippet
strcpy(fieldValue[0].string, "1234Buffer Overrun"); //
fieldValue is a struct MqlStr
MQL4 snippet:
string fieldValue[2] = { "Hi",
"Happy Days Are Here" };
ExternalFunction(fieldValue); // This executes the C++ code above
string fixString = fieldValue[1];
MessageBox(fixString);
What happened here is the strcpy overran the buffer of
fieldValue[0] and right on top of fieldValue[1]. In fact, the text in
MessageBox will be "Buffer Overrun".
With that said, there is a way around this, but I
strongly recommend against it for anything besides proof-of-concept code. C++ snippet:
fieldValue[0].string
= "Hack";
Basically, this is replacing the pointer that MQL4 is using
for the string. However, you have now leaked the old fieldValue[0].string, and you don't know which cleanup method MQL4 might attempt to use on your string (which itself could cause a crash). If one of the MQL4 programmers told us some of the inner workings regarding strings, this could be made safe.
Brian
Yep, what I have done is to pass a predefined string of 255 characters to the function. That is the maximum MQL can handle. I have not experienced any buffer overruns when doing that, but it is not a very elegant solution. But as long as it works and I have no memory leak I am happy with it until I can find a better solution.
And yes the length field seems to do nothing to me too, but it does not seem to do any harm to set it to the length of the string either. If you replace the pointer to the string you will have a memory leak and the memory usage of terminal.exe will grow into the sky. To me it seems that MQL have no way of handling that at all.
strcpy(fieldValue[0].string, "1234Buffer Overrun"); // fieldValue is a struct MqlStr
MQL4 snippet:
string fieldValue[2] = { "Hi", "Happy Days Are Here" }; ExternalFunction(fieldValue); // This executes the C++ code above string fixString = fieldValue[1]; MessageBox(fixString);
What happened here is the strcpy overran the buffer of fieldValue[0] and right on top of fieldValue[1]. In fact, the text in MessageBox will be "Buffer Overrun".
It would not overrun the buffer. The important thing is, fieldValue[0], fieldValue[1]..., must be init use a value, even use "", after that it will init a string point.
does anybody ever tried this solution in C# dll , I have tried every thing MqlStr , char * c = new char [] , dont allow , waiting for you expert suggestion
hijeenu: does anybody ever tried this solution in C# dll , I have tried every thing MqlStr , char * c = new char [] , dont allow , waiting for you expert suggestion
Please do not double post . . . especially to old threads.
Allow the use of cookies to log in to the MQL5.com website.
Please enable the necessary setting in your browser, otherwise you will not be able to log in.
You are signed in. Two-factor authentication has been disabled. Set it up again and scan a new QR code, or continue with two-factor authentication disabled.
void FunctionWithoutMemoryLeak(MqlStr* fieldValue)
{
char *value = GetValueFromSomeFunction();
}
I did some investigation into this, and it seems you need to tread very carefully when dealing with passed strings. The code sample above is unsafe and could cause a crash.
The first part of the problem comes in the MqlStr struct reference - it seems that while MQL4 reserves 4 bytes for the string size, it doesn't populate the length field (my code showed 0 for the size) so you can't use that to determine the size of the buffer. As such, you will need to pre-define a contract on the string size (some max size would be a safe bet).
The second part is the code above can easily cause a buffer overrun. While you are properly allocating the buffer size of the source string (new char[5]), the destination buffer you are copying into (fieldValue[0].string) is an unknown size. If it is less than 5 bytes, then you are causing a buffer overrun.
Here's an example: C++ snippet
ExternalFunction(fieldValue); // This executes the C++ code above
string fixString = fieldValue[1];
MessageBox(fixString);
With that said, there is a way around this, but I strongly recommend against it for anything besides proof-of-concept code. C++ snippet:
Brian
I did some investigation into this, and it seems you need to tread very carefully when dealing with passed strings. The code sample above is unsafe and could cause a crash.
The first part of the problem comes in the MqlStr struct reference - it seems that while MQL4 reserves 4 bytes for the string size, it doesn't populate the length field (my code showed 0 for the size) so you can't use that to determine the size of the buffer. As such, you will need to pre-define a contract on the string size (some max size would be a safe bet).
The second part is the code above can easily cause a buffer overrun. While you are properly allocating the buffer size of the source string (new char[5]), the destination buffer you are copying into (fieldValue[0].string) is an unknown size. If it is less than 5 bytes, then you are causing a buffer overrun.
Here's an example: C++ snippet
ExternalFunction(fieldValue); // This executes the C++ code above
string fixString = fieldValue[1];
MessageBox(fixString);
With that said, there is a way around this, but I strongly recommend against it for anything besides proof-of-concept code. C++ snippet:
Brian
Yep, what I have done is to pass a predefined string of 255 characters to the function. That is the maximum MQL can handle. I have not experienced any buffer overruns when doing that, but it is not a very elegant solution. But as long as it works and I have no memory leak I am happy with it until I can find a better solution.
And yes the length field seems to do nothing to me too, but it does not seem to do any harm to set it to the length of the string either. If you replace the pointer to the string you will have a memory leak and the memory usage of terminal.exe will grow into the sky. To me it seems that MQL have no way of handling that at all.
#import "mytest.dll"
void getstr(string retstr)
#import
void getstr(char * retstr)
{
char *value = new char[4];
strcpy(value, "Test");
delete [] value;
}
It would work, don't know why. if define : "void getstr(string& retstr)", it will cause crash.
but before call getstr(string) in mq4, input string must be init, e.g.
string var1 = "";
getstr(var1); //shoud ok
string var2;
getstr(var2); //may cause mt4 crash
Here's an example: C++ snippet
ExternalFunction(fieldValue); // This executes the C++ code above
string fixString = fieldValue[1];
MessageBox(fixString);
does anybody ever tried this solution in C# dll , I have tried every thing MqlStr , char * c = new char [] , dont allow , waiting for you expert suggestion
I don't know why you guys make it to be very complicated here. The solution is very simple.
* C++:
* MQL:
I don't know why you guys make it to be very complicated here. The solution is very simple.
* C++:
* MQL:
I am afraid you missed ziggy by more than 6 years with your reply.