简体   繁体   中英

Calling/Marshalling strings from c# dll to unmanaged code

I'm trying to call ac# 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".

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 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM