Hi, I am trying to import a dynamic library coded in C++ in my EA.
Only problem is that despite the functions being exported, my EA does not load them properly.
The C++ code is as follows:
CONSOLEAPPLICATION2_API bool UnicodeToAscii(const wchar_t * szUnicode, char * szAscii)
And the Import function call is as follows:
#import "Analytical.dll"
bool UnicodeToAscii(const string szUnicode, char szAscii);
#import
The resulting error is:
2016.11.02 15:00:55.316 Cannot find 'UnicodeToAscii' in 'Analytical.dll'
2016.11.02 15:00:55.316 Dulcimer AUDUSD,M1: 89.18343333262493
2016.11.02 14:47:57.288 Dulcimer AUDUSD,M1: initialized
2016.11.02 14:47:50.241 Expert Dulcimer AUDUSD,M1: loaded successfully
Please help with a fix.
For now you can't send string to dll, only char array.
bool UnicodeToAscii(char &a0[], char szAscii);
#import
...
char a[];
StringToCharArray(szUnicode,a);
UnicodeToAscii(a, ...);
Your import says the second parameter is a single char not an array of char's. |
Thanks. I have recoded the dll and now I'm getting this error...
Any ideas?
Thanks. I have recoded the dll and now I'm getting this error...
Any ideas?
Firstly, MQL4 has native functions for the conversions which you are trying to do. A string datatype in MQL4 is always a Unicode string. An Ascii string has to be represented as a uchar[] array. You can convert between these using StringToCharArray and CharArrayToString. For example:
string strExample = "My input string";
// Convert to an Ascii string, which has to be held as uchar[]
uchar arrAscii[];
StringToCharArray(strExample, arrAscii, 0, StringLen(strExample));
// Convert from Ascii back to native Unicode string
string strRoundTrip = CharArrayToString(arrAscii);
The one point to note is that you can use StringToCharArray(strExample, arrAscii) instead of StringToCharArray(strExample, arrAscii, 0, StringLen(strExample)) but the former will add a terminating null character at the end of the array. In the above example the size of arrAscii would then be 16 characters/bytes, not 15.
The following is therefore pointless in itself, because MQL4 provides all this natively, but it does illustrate how to pass Unicode and Ascii strings in and out of a DLL...
A Unicode string can be passed to a DLL as a const input parameter just by defining the type in the DLL import as "string". But, to pass an in/out buffer, which the DLL writes into, the Unicode buffer must be declared as ushort[]. An Ascii string must be passed in or out of a DLL as uchar[].
For example, take the following 4 DLL functions which do the combinations of Unicode <--> Ascii:
necessarily use N bytes/characters for Ascii and 2N bytes for Unicode as assumed here. */
extern "C" __declspec(dllexport) int CopyUnicodeToUnicode(const wchar_t * InputString, wchar_t * OutputBuffer)
{
wcscpy(OutputBuffer, InputString);
return wcslen(OutputBuffer);
}
extern "C" __declspec(dllexport) int CopyAsciiToAscii(const char * InputString, char * OutputBuffer)
{
strcpy(OutputBuffer, InputString);
return strlen(OutputBuffer);
}
extern "C" __declspec(dllexport) int CopyUnicodeToAscii(const wchar_t * InputString, char * OutputBuffer)
{
int len = wcslen(InputString);
WideCharToMultiByte(CP_UTF8, 0, InputString, len, OutputBuffer, len, NULL, NULL);
return len;
}
extern "C" __declspec(dllexport) int CopyAsciiToUnicode(const char * InputString, wchar_t * OutputBuffer)
{
int len = strlen(InputString);
MultiByteToWideChar(CP_UTF8, 0, InputString, len, OutputBuffer, len);
return len;
}
These functions can be imported in MQL4 as follows:
int CopyUnicodeToUnicode(string, ushort&[]);
int CopyAsciiToAscii(uchar&[], uchar&[]);
int CopyUnicodeToAscii(string, uchar&[]);
int CopyAsciiToUnicode(uchar&[], ushort&[]);
#import
The two functions which take Unicode input parameters can have those parameters declared as string. The two functions which take Unicode output buffers must have those buffers defined as ushort[], not as string.
The functions can then be used in MQL4 as follows:
{
Print(Test_UnicodeToUnicode("Hello"));
Print(Test_AsciiToAscii("Hello"));
Print(Test_UnicodeToAscii("Hello"));
Print(Test_AsciiToUnicode("Hello"));
}
string Test_UnicodeToUnicode(string InputString)
{
// The Unicode output buffer must be declared as ushort[],
// with the array large enough to receive the output
ushort arrDest[];
ArrayResize(arrDest, StringLen(InputString));
int len = CopyUnicodeToUnicode(InputString, arrDest);
// Convert the ushort[] output to a native MQL4 Unicode string
return ShortArrayToString(arrDest, 0, len);
}
string Test_AsciiToAscii(string InputString)
{
// The Ascii input must be created by converting the MQL4 Unicode string
// to a uchar[] array of Ascii bytes/characters
uchar arrInput[];
StringToCharArray(InputString, arrInput, 0, StringLen(InputString));
// The Ascii output must be received by declaring a uchar[] array,
// large enough to receive the output
uchar arrDest[];
ArrayResize(arrDest, StringLen(InputString));
int len = CopyAsciiToAscii(arrInput, arrDest);
// Convert the uchar[] Ascii output back to a native MQL4 Unicode string
return CharArrayToString(arrDest, 0, len);
}
string Test_UnicodeToAscii(string InputString)
{
// The Ascii output must be received by declaring a uchar[] array,
// large enough to receive the output
uchar arrDest[];
ArrayResize(arrDest, StringLen(InputString));
int len = CopyUnicodeToAscii(InputString, arrDest);
// Convert the uchar[] Ascii output back to a native MQL4 Unicode string
return CharArrayToString(arrDest, 0, len);
}
string Test_AsciiToUnicode(string InputString)
{
// The Ascii input must be created by converting the MQL4 Unicode string
// to a uchar[] array of Ascii bytes/characters
uchar arrInput[];
StringToCharArray(InputString, arrInput, 0, StringLen(InputString));
// The Unicode output buffer must be declared as ushort[],
// with the array large enough to receive the output
ushort arrDest[];
ArrayResize(arrDest, StringLen(InputString));
int len = CopyAsciiToUnicode(arrInput, arrDest);
// Convert the ushort[] output to a native MQL4 Unicode string
return ShortArrayToString(arrDest, 0, len);
}
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hi, I am trying to import a dynamic library coded in C++ in my EA.
Only problem is that despite the functions being exported, my EA does not load them properly.
The C++ code is as follows:
CONSOLEAPPLICATION2_API bool UnicodeToAscii(const wchar_t * szUnicode, char * szAscii)
And the Import function call is as follows:
#import "Analytical.dll"
bool UnicodeToAscii(const string szUnicode, char szAscii);
#import
The resulting error is:
2016.11.02 15:00:55.316 Cannot find 'UnicodeToAscii' in 'Analytical.dll'
2016.11.02 15:00:55.316 Dulcimer AUDUSD,M1: 89.18343333262493
2016.11.02 14:47:57.288 Dulcimer AUDUSD,M1: initialized
2016.11.02 14:47:50.241 Expert Dulcimer AUDUSD,M1: loaded successfully
Please help with a fix.