What you're asking for is not passing a string to DLL, but getting a string from DLL!
To pass a string to DLL just declare a function with LPWSTR parameter (not a reference!) in DLL and call it with a string.
To read a string you can allocate a uchar buffer in MQL and pass it as a pointer to the DLL (something like GetString(/*in|out*/uchar *buffer, /*in*/const int bufferLen) in MQL import), which will fill it with chars. Then you can reconstruct the string using CharArrayToString.
Or you can have a static (or preallocated) buffer in the DLL and return wchar_t* (LPWSTR) for it from a function (like string GetString() in MQL import). Probably you can find a solution in this source codes (unfortunately, the description is in Russian only).
In the standard delivery of MT4 (\ MQL4 \ Scripts \ Examples \ DLL) there is an example ( & it works fine in MT5) :
//+------------------------------------------------------------------+
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
//---
#define MT4_EXPFUNC __declspec(dllexport)
//+------------------------------------------------------------------+
#pragma pack(pop)
//---
struct MqlStr
{
int len;
char *string;
};
static int CompareMqlStr(const void *left,const void *right);
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
//---
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
//---
return(TRUE);
}
//+------------------------------------------------------------------+
MT4_EXPFUNC wchar_t* __stdcall GetStringValue(wchar_t *spar)
{
spar=L" it ...";
return(spar);
}
#import "DLLSample.dll"
string GetStringValue(string);
#import
//+------------------------------------------------------------------+
int init()
{
string sret;
int cnt;
//--- simple dll-functions cal
sret=GetStringValue("some string");
Print("Returned value is ",sret);
//---
return(0);
}
- www.metaquotes.net
Mikhail Dovbakh:
In the standard delivery of MT4 (\ MQL4 \ Scripts \ Examples \ DLL) there is an example ( & it works fine in MT5) :
...What you're asking for is not passing a string to DLL, but getting a string from DLL!
To pass a string to DLL just declare a function with LPWSTR parameter (not a reference!) in DLL and call it with a string.
To read a string you can allocate a uchar buffer in MQL and pass it as a pointer to the DLL (something like GetString(/*in|out*/uchar *buffer, /*in*/const int bufferLen) in MQL import), which will fill it with chars. Then you can reconstruct the string using CharArrayToString.
Or you can have a static (or preallocated) buffer in the DLL and return wchar_t* (LPWSTR) for it from a function (like string GetString() in MQL import). Probably you can find a solution in this source codes (unfortunately, the description is in Russian only).
Hi Stanislav , thank you and thank you for the hint. Yes you are right, i want to pass a string reference to a DLL function and within the DLL i want to assign data, like a mysql result. Which means i need to refer a string array. After all that reading i had some problems sorting my mind :D ...I understand what you are saying but somehow it won't work. I guess more, i have some compiler settings missing, because also the examples found here or the mysql_wrapper from russell ( https://www.mql5.com/en/code/8623 ) wont work.
He just provides a 32bit version and i compiled it for 64bit with VS2017. But also very very simple function where you just pass the arument won't work. I dont have problems passing a string, this works. I also can return a wchar_t value but i can't handle a string reference.
In MT4 there use, so far i know, char and in mt5 wchar_t
I tried all this:
#pragma pack(push,1)
struct MqlStr_mt4 {
int len; // 32 bit integer, contains the size of the buffer allocated for the string
char* string; // 32 bit address of the buffer that contains the string
int reserved; // 32 bit integer, reserved, do not use
};
struct MqlStr_mt5 {
int len; // 32 bit integer, contains the size of the buffer allocated for the string
wchar_t* string; // 32 bit address of the buffer that contains the string
int reserved; // 32 bit integer, reserved, do not use
};
#pragma pack(pop,1)
extern MYSQLWRAPPER_API wchar_t* MT5_mysql_wrapper_version (); << works
extern MYSQLWRAPPER_API void MT5_mysql_wrapper_version (int &foobar); << int works
extern MYSQLWRAPPER_API void MT5_mysql_wrapper_version (wchar_t *foobar); << Passing only
extern MYSQLWRAPPER_API void MT5_mysql_wrapper_version (wchar_t *&foobar); << Error in MT
extern MYSQLWRAPPER_API void MT5_mysql_wrapper_version (MqlStr_mt4 &foobar); << Error in MT
extern MYSQLWRAPPER_API void MT5_mysql_wrapper_version (MqlStr_mt4 *&foobar); << Error in MT
extern MYSQLWRAPPER_API void MT5_mysql_wrapper_version (MqlStr_mt5 &foobar); << Error in MT
extern MYSQLWRAPPER_API void MT5_mysql_wrapper_version (MqlStr_mt5 *&foobar); << Error in MT
extern MYSQLWRAPPER_API void MT5_mysql_wrapper_version (LPWSTR &foobar); << Error in MT
extern MYSQLWRAPPER_API void MT5_mysql_wrapper_version (LPWSTR *&foobar); << Error in MT
extern MYSQLWRAPPER_API void MT5_mysql_wrapper_version (wchar_t &foobar); << Error in MT
The function also has been exported with "C" but it wont change.
Also the example from Mikhail don't work. I spend the entiere weekend with MT documentary, google and coffee and i have no clue what i do wrong. Within C++ it works. NO Errors, no NULL Pointer Exception ....all fine.
- votes: 8
- 2008.12.15
- Russell
- www.mql5.com
Hello Christian !
If you do not have the DLL that I packed into the attachment, then you have a 32 bit MT5.
If this is not the case, I can not reason why this assembly of DLL (by the way it was made directly in the META Editor) does not work.
Hi Mikhail ,
no, your DLL get's loaded and it works. I meaned the DLL from the one documentation i mention. But as i said, i need to pass a string reference in order to handle mysql results.
Now, somehow i am a bit futher but still not at the goal. Current this works but the string is displayed incorretly:
Since i export the function as "C", MT stops showing me the unresolve able error message.
C++:
extern "C" MYSQLWRAPPER_API wchar_t* returnString ();
extern "C" MYSQLWRAPPER_API void changeString (wchar_t* &stringTest);
extern "C" MYSQLWRAPPER_API void changeString1 (char* &stringTest);
extern "C" MYSQLWRAPPER_API void fnReplaceString (wchar_t *text, wchar_t *from, wchar_t *to);
wchar_t* __stdcall returnString() {
return(L"this is a wchar_t string");
}
void __stdcall changeString(wchar_t* &stringTest) {
stringTest = L"Hello you ....";
}
void __stdcall changeString1(char* &stringTest) {
stringTest = "Hello you ....";
}
void __stdcall fnReplaceString(wchar_t *text, wchar_t *from, wchar_t *to) {
wchar_t *cp;
//--- parameters check
if (text == NULL || from == NULL || to == NULL) return;
if (wcslen(from) != wcslen(to)) return;
//--- search for substring
if ((cp = wcsstr(text, from)) == NULL) return;
//--- replace it
memcpy(cp, to, wcslen(to) * sizeof(wchar_t));
}
MT5:
#import "Quantum\MySQL\mysql_wrapper.dll"
string returnString ();
void changeString (string &value);
void changeString1 (string &value);
#import
string return_value1 = returnString();
string return_value2 = "";
Print("1. Return value is: " + return_value1 );
// wchar_t
changeString(return_value1);
// char
changeString1(return_value2);
Print("2. Return value is: " + return_value1 );
Print("3. Return value is: " + return_value2 );
//--- modify the string
string text="A quick brown fox jumps over the lazy dog";
fnReplaceString(text,"fox","cat");
Print("Replace: ",text);
Result:
2017.11.19 20:41:06.085 Test (EURUSD,M1) 2. Return value is: ㎘߾
2017.11.19 20:41:07.636 Test (EURUSD,M1) 3. Return value is: ㎸߾
2017.11.19 20:41:11.343 Test (EURUSD,M1) Replace: A quick brown fox jumps over the lazy dog
Also in the example, from a example ( https://www.mql5.com/en/articles/18 ) , the hasn't changed.
But since i overwrite the pointer at the end in the DLL function fnReplaceString:
wchar_t *cp;
//--- parameters check
if (text == NULL || from == NULL || to == NULL) return;
if (wcslen(from) != wcslen(to)) return;
//--- search for substring
if ((cp = wcsstr(text, from)) == NULL) return;
//--- replace it
memcpy(cp, to, wcslen(to) * sizeof(wchar_t));
text = cp;
}
The result looks great:
- 2010.01.27
- MetaQuotes
- www.mql5.com
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hey all,
maybe you could help me solving this problem. I have create a simple DLL, like as described here:
https://www.mql5.com/en/articles/18
The DLL work when i use as parameter a Integer but when i switch to string, MT5 come up with the message, he couldn't find the method:
2017.11.18 11:24:35.507 Test(EURUSD,M1) Cannot find 'testWchar_Ref' in 'Test\variableTest.dll'
This is my import in MT5:
void testInt_Ref (int &intTest_ref);
void testWchar_Ref (string &wchar_tTest_Ref);
#import
Implementation in MT5:
int myInt = 0;
testInt_Ref(myInt);
Print("New INT: ", myInt );
Print("PRE: " + stringTest);
testWchar_Ref(u_stringTest);
Print("POST: " + stringTest);
Export in DLL:
#define QVAR_API __declspec(dllexport)
#else
#define QVAR_API __declspec(dllimport)
#endif
extern QVAR_API void testInt_Ref(int &intTest_ref);
extern QVAR_API void testWchar_Ref(wchar_t &wchar_tTest_Ptr);
DLL Function:
#include "stdafx.h"
using namespace std;
// add new INT value
void testInt_Ref(int &intTest_ref) {
intTest_ref = 222;
}
// add new WCHAR_T value
void testWchar_Ref(wchar_t &wchar_tTest) {
wchar_t *msg = L"This is cool.....";
wchar_t *wchar_tTest_Ref = &wchar_tTest;
//--- replace it
memcpy(wchar_tTest_Ref, msg, wcslen(msg) * sizeof(wchar_t));
}
Result:
2017.11.18 11:24:35.507 Test(EURUSD,M1) PRE: Hello you...
2017.11.18 11:24:35.507 Test(EURUSD,M1) Cannot find 'testWchar_Ref' in 'Test\variableTest.dll'
2017.11.18 11:24:35.507 Test(EURUSD,M1) unresolved import function call
it's compiled correctly. In my c++ Testprogram it works. Even when i leave the DLL Method empty it appears. It must be the parameter.
How can i pass a string to a DLL, modify it and use it back in MT5 ?
Thanks in Advanced