MT4 build 600+ C# and DLL Strings

 

Hello,

Prior to build 600, I wrote a C# DLL that worked perfectly but it seems that build 600 broked my EA calls.

The C# DLL define some functions like this (using RGiesecke library):

[DllExport("loadAllDatabase", CallingConvention = CallingConvention.StdCall)]
public static bool testFunction(string testString)
{
writeToDebugFile(testString);
return true;
}

On the EA side, something like this is written:

#import "myLibrary.dll"
bool testFunction(string connectionString);

testFunction("Test string");


I understand that build 600+ now uses Unicode string instead of ANSI ones, but I have to admit that don't have a clue how to handle this. :)
Does anybody know?

Thank you!

 

OK, solved!

I had to add MarshalAs directives to make it work again. Just like this:

[DllExport("loadAllDatabase", CallingConvention = CallingConvention.StdCall)]
public static bool testFunction([MarshalAs(UnmanagedType.LPWStr)] string testString)
{
writeToDebugFile(testString);
return true;

}

Quite simple in fact :)

 

I solved a similar problem, but with string return value.

For others:

[DllExport("getLastStatus", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.LPWStr)]
public static string getLastStatus(int ECIndex) {
// ...
return "Your string";
}

 
lukucz:

I solved a similar problem, but with string return value.

For others:

[DllExport("getLastStatus", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.LPWStr)]
public static string getLastStatus(int ECIndex) {
// ...
return "Your string";
}


I tried this approach to returning a String using DllExport and it did not free the memory. If you're doing this every tick in Strategy Tester, you'll notice. Maybe a bug in DllExport?

 

Anyway, the workaround is to do the following (as per https://www.mql5.com/en/articles/249)

         [DllExport("GetCommandName", CallingConvention = CallingConvention.StdCall)]

        public static void GetCommandName(Int64 ix, int id, [In, Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder commandName)

 

And the MQL:

      string name = "";

      GetCommandName(ix, requestId, name);

 
dotpanic #:
[MarshalAs(UnmanagedType.LPWStr)]
Thanks so much!!! Worked like a charm!!!