0

I'm trying to call a c# function in a dll from an unmanaged 3rd party app - metatrader

I have followed advice from Calling C# dll from unmanaged code however, the example about marshalling strings does not work.

Note: I have successfully called the integer addition example from the reference (function "Add"), and it works end to end with no problems, so I know the issue is to do with strings. Ie, the "ReplaceString" function does not work. I have also looked atRobertGisiecke website, but there is not a string example there, or I am too dumb to figure it out.

The error message I get in metatrader is:

15:27:40 2009.11.10 00:01 MT4LibTest EURUSD,H1: function 'ReplaceString' call from dll 'Testme.dll' critical error c0000005 at 040B031B.

Platform is Windows Server 2012 (64bit) and I have compiled to x86 because Metatrader is an x86 program

One more thing: I am not very experienced in VS world, so Im hoping someone can be kind enough to help

Thank you

C# code:

[DllExport("ReplaceString", CallingConvention = CallingConvention.StdCall)]
    public static int ReplaceString(
        [In, Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder str,
        [MarshalAs(UnmanagedType.LPWStr)]string a, 
        [MarshalAs(UnmanagedType.LPWStr)]string b)
    {
        str.Replace(a, b);

        if (str.ToString().Contains(a)) return 1;
        else 
            return 0;
    }

Calling function (Metatrader):

#import "MT4Lib.dll"
    int ReplaceString(string & str,string a,string b);
    int Add(int x, int y);
#import
    string str="A quick brown fox jumps over the lazy dog";
    string stra = "fox";
    string strb = "cat";        

    Print(str);
    Print(ReplaceString(str,stra,strb));
    Print(str);

EDIT: I should make clear that the metatrader API that allows one to write 'scripts' does not allow full C++ types. So there is no char, no wchar and certainly no pointers to these types. Only "string".

  • Welcome to StackOverflow. You can't pass a C++ string to a C# application. You'll probably need to make it a `wchar *`. Also see the related questions (on the right). For example: http://stackoverflow.com/questions/643202/send-c-string-to-c-sharp-string-interop – Jim Mischel Dec 29 '12 at 16:47
  • You cannot pinvoke functions that take C++ objects as arguments. – Hans Passant Dec 29 '12 at 17:09
  • To do this 'C++ calling C#' thing, I suggest you use COM instead. Create a COM object in C# and use it in C++. – Simon Mourier Dec 29 '12 at 17:50

1 Answers1

0

Solution found!

First off, thank yous to everyone who responded. Getting to grips with new technology (for me) has been a little challenging). @Jim: See the EDIT I added. MQL (the metatrader language) may be based on C++ but has been seriously shackled by the designers of the application. So no wchar types. @Simon: Adding a reference to NuGet package "UnmanagedExports" will place wrappers and handle CIL fixups for you, so you can concentrate on your code. The link I included in the question details this.

There were two issues with the code as is:

  1. In the sample code given, string arguments in c# function were declared as LPWStr (Wide strings). Looking at them in debugger showed they had Chinese-looking characters in them. LPStr works fine.

    public static int ReplaceString(
        [In, Out, MarshalAs(UnmanagedType.LPStr)] StringBuilder str,
        [MarshalAs(UnmanagedType.LPStr)]string a, 
        [MarshalAs(UnmanagedType.LPStr)]string b)
    
  2. Sample code also had a pointer to string declared as an argument in the caller (native) code. Removing this, and using StringBuilder class to change the string in the managed c# code, worked.

    #import "MT4Lib.dll"
        int ReplaceString(string str,string a,string b);
        int Add(int x, int y);
    #import
    
  • If someone is trying to marshall strings to MQL terminals, this link will be very helpful: https://www.mql5.com/en/articles/249 – opewix May 20 '16 at 07:16