BUG: Imported DLL Functions Receive Only First Character of Strings Passed By Value (MQL Build 237)

 

Hey 

It appears there is a serious error in invoking external DLL's from MetaEditor (MQL5: Version 237). The bug appears when external DLL's are referenced and are passed MQL string types.

I have already reviewed https://www.mql5.com/en/forum/122 and allowed importing DLL's.

I was not sure about the error at first as I was using a DLL that I had created myself and therefore thought the fault lay not with MQL but with my own DLL.To eliminate that possibility I called the standard Windows user32.dll and noticed that only the first character of the string was being passed to the DLL's messagebox function. My DLL (and user32.dll)  does a MessageBox.Show a preview of which I am attaching ,that displays only the first character when invoked, in addition the user32:MessageBoxA which is a widely used and important Windows DLL also displays the first character only.

There can be no other possibility except that MQL5 is not passing its native string type in entirety but passing only the first char, since I have verified that the DLL is receiving a string of length 1.

My entire code/script is pasted below:-

#import "ExpertSample.dll"

   string ExecuteScalar(string strSQL);   

#import  


#import "user32.dll"

  int MessageBoxA(int hWnd,string lpText,string lpCaption,int uType); 

#import


int OnStart()

{

   //In both cases only the first Character is passed to respective DLL Functions

   int result = MessageBoxA(NULL,"Helo world!","MQL4 Messagebox",0);      

   string temp = ExecuteScalar("INSERT INTO [Clean].[dbo].[System_Roles] VALUES ('hey', 'hey')");

   return(0);

}


The trimmed down version of my DLL only does this :-

MT4_EXPFUNC char * __stdcall ExecuteScalar(char *strSQL)

  {  

MessageBox(NULL,(LPCSTR)strSQL,(LPCSTR)L"no error",MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2 );

MessageBox(NULL,strSQL,(LPCSTR)L"no error",MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2 );

  }

I tried many combinations of the LPCSTR, and finally just did a strlen (strSQL) and noticed that the length being transmitted was 1.

char test[10];

itoa(strlen(strSQL), test, 10);

Test returns 1.

 

Attached pictures will show the messageboxes as they appears on my computer.

Attached also is my VS_2008 SP1 Project that builds the custom made DLL should you require to make modifications, although the user32.dll will do just fine also to serve as a litmus test for the above.


Thank you

Kanhar Munshi

PS I can be reached immediately at---> kanhar AT gmail.com 

<a href="www.kanharmunshi.com">Kanhar Munshi</a> 

Files:
snapshot.jpg  9 kb
expertsample.rar  2444 kb
 

https://www.mql5.com/en/docs/basis/types/stringconst

"A text string is a sequence of characters in the Unicode format with the final zero at the end of it."

You should use MessageBoxW function instead of MessageBoxA and wchar_t* type instead of char* 

Documentation on MQL5: Language Basics / Data Types / String Type
  • www.mql5.com
Language Basics / Data Types / String Type - Documentation on MQL5
 
stringo:

https://www.mql5.com/en/docs/basis/types/stringconst

"A text string is a sequence of characters in the Unicode format with the final zero at the end of it."

You should use MessageBoxW function instead of MessageBoxA and wchar_t* type instead of char* 

Stringo--

Thank you for your help.

 You were, it turns out, right in both cases. MessageBoxW works instead of MessageBoxA.

More importantly however, in my custom made DLL, wchar_t* type works instead of char*.

I was quite frustrated towards the end, because I had tried everything I could think including a data structure that I thought resembled the MQL String type which I was told looks something like this :-

struct MqlStr

  {

   int               len;

   char             *string;

  }; 

In the end however the code in my DLL looks like this. I had some trouble initially converting the wchar_t type to char*, and the null terminator needs to be explicitly placed twice for it to work correctly, but everything else fell into place like a charm.

Here is the DLL Code to accept a string sent via MQL 5 

MT4_EXPFUNC char * __stdcall ExecuteScalar(wchar_t *wstr)

  {  

char* sql = new char[wcslen(wstr) + 1];

wcstombs( sql, wstr, wcslen(wstr) );

sql[wcslen(wstr)] = '\0'; 

}

Thank you once again for your help

 

sincerely

Kanhar Munshi 

 

Hello guys,

I have the same problem with one single character.

I'm using one dll to read/write clipboard which has these exports: 

BOOL CopyTextToClipboard(LPCTSTR strText)

Puts text onto the Windows clipboard. Returns TRUE if successful or FALSE if it fails (I don't see why it would ever fail).

 

LPCTSTR GetTextFromClipboard()

Gets the contents of the Windows clipboard if there is text available, returns an empty string ("") if not there. 

 

I tried all combinations I could think of, I read the forum and searched the net, but now I'm stuck. And I don't have the source of dll. Just the result and description of functions.

What type combination should I use to get and set a whole text?

This is what is written right now in my code (I'm aware of the fact LPCTSTR is a pointer, but I don't know either how to give it a pointer, or why still it works and writes the first character into the clipboard.

#import "IRClipboardFunctions.dll"
//Returns TRUE or FALSE depending on whether or not there is text available on the Windows clipboard.
bool IsTextOnClipboard();

//Puts text onto the Windows clipboard. Returns TRUE if successful or FALSE if it fails (I don't see why it would ever fail).
bool CopyTextToClipboard(string strText);

//Gets the contents of the Windows clipboard if there is text available, returns an empty string ("") if not there.
string GetTextFromClipboard();

#import

 Can someone help me with this?

Thank you in advance. 

 
I'm struck in the same problem, did you find a solution ?
Reason: