Strange String behaviour
Has anyone come across the following
I have a script with the following declarations
string symbol = "XXXXXX";
string open = "open"; string stop = "stop"; string takeP = "take";
I then call a DLL declared as follows
void GetParmQuery(string symbol, string open, string stop, string takeP,
double& Levels, int& Data);
The values returned from the DLL are as expected ie the default values for symbol, open, stop and takeP have been changed However if I then do the following test
if (open != "open")
the test fails and I get "EQ" printed
Any ideas what is happening and can it be fixed without a messy work around
What are you trying to do that can't be done the conventional way?
What i can tell from my own experience is that strings passed to the DLL will simply be pointers to nullterminated strings. In Pascal you would use a PChar type for this. I have had only one instance where i ever felt the need to return a string from the dll to the script and that was when i wrote my python binding. The function returning the value of a python string object to the calling mql4 script looks like this:
function PyGetString(item : PPyObject) : [color="Red"]PChar[/color]; stdcall; var gs : TGILState; begin gs := PyGILState_Ensure(); PyGetString := PyString_AsString(item); PyGILState_Release(gs); end;
(You can find the full source code (Lazarus/FPC) attached as a .rar file at the end of this site: http://sites.google.com/site/prof7bi...on-integration)
The above will return a pointer to the string (created by the python DLL), simply using the fuction return value. MT4 will immediately copy the string from the returned pointer into it's own memory.
When i recommended the conventional way i was referring to the conventional way for solving the problem, not the conventional way of returning strings. The conventional way of solving the problem (whatever it may be) would most likely not include any usage of strings returned to the script. Therefore here the question again: what are you trying to do?
As 7Bit states you are manipulating memory that you (DLL) havent allocated and you dont know how MQL deals with allocating memory to that string or how it stores its dynamic size (length)
tstr = DLLreturnNullString();
This works because MQL is given a pointer to a nullTerm string (that your DLL allocated memory for) MQL then deals with allocating its own memory and internal allocation lists / string size list and copies the data into this new MQL memory. Everythings good because you let MQL build its own copy of the string.
This is dangerous for several reasons :
A) you dont know how much memory (if any) MQL has allocated to the pointer your DLL recieves.
B) If you change the string then MQL wont know it about it and if you change the length of it then MQL wont have updated its own 'knowlegde' of the length of the string
C) if you try to change or read the string and over step the memory that MQL allocated for it then you have a protection fault
D) In my experience whilst MQL will allow strings to be upto 64KB in size Im sure the memory is not always alocated as one contiguous block of memory.
If you do persist down this route (and id advise not to ) the best way is
String tstr=" " ;
// pad upto 255 characters at definition time so that memory is allocated
This way your DLL passes back the new length of the string so you at least have some knowledge of its new length.
I've seen a C header that details the MQL string structure (but have never used it) which alludes to the fact that the string length is stored in an INT (4 Bytes) before The start of the string.
So in your DLL you might try decrementing the String pointer supplied by MQL (by 4 bytes) and writing an integer to this memory location to define the new length
Ive never tried it / dont know if im correct on this & and I wouldnt advise doing this because you are messing with MQL's knowledge of what its done with this String if you change its length from 255 to 10 then MQL may well leak the memory that your DLL has made it ignorant of.
OK Guys thanks for the help it seems the MQL docs are somewhat unclear. I will now focus on returning new strings from the DLL (as a Function call in Delphi) rather than changing existing ones And I will look at limiting the use of strings in future as 7Bit suggests
© Forex Factory