.net C# dll export Marshalas string not working

 

I am trying to invoke this method in MQL:

#import "Trading.dll"
int GetSymbolCount(string symbol);
#import

The C# code is as follows:

[DllExport("GetSymbolCount", CallingConvention = CallingConvention.StdCall)]
public static int GetSymbolCount([MarshalAs(UnmanagedType.LPWStr)]string symbol)

I tried different combinations for UnmanagedType, nothing seems to work. What happens is the first character of the string is passed...

Anyone have any ideas on how this can be solved?

Calling it in OnStart as follows:

Print("HERE ----> ", GetSymbolCount("EURUSD"));

PLEASE HELP!!!

 
Sameer Shariff:

I am trying to invoke this method in MQL [...]

What you are doing should be fine. For example, I get the result 6 if I do GetSymbolCount("EURUSD") with the following code:

    [DllExport("GetSymbolCount", CallingConvention = CallingConvention.StdCall)]
    public static int GetSymbolCount([MarshalAs(UnmanagedType.LPWStr)]string symbol)
    {
        return symbol.Length;
    }

Are you sure that the problem isn't how you are processing/displaying/logging the string inside the DLL, rather than in passing the string value to the DLL?

Another possibility, though this should cause a variety of other problems rather than the one you are describing: is the target platform for the .NET project set to x86?

 

I have been experience the same problem, may my example as follow help you.

MQL4 

#import "test.dll"
string Replace(string source, string oldText, string newText);;
#import
string myString = "A quick fox jump over the dog";
string newText = Replace(myString, "fox", "cat");
Print(newText);

C#

/*
1.      Initialize a IntPtr
2.      Do string operation(s)
3.      Add NULL to return string       //important: should add NULL at the end, otherwise, return string will give you extra characters
4.      Get Unicode Buffer of the return string
5.      Allocates memory from the unmanaged memory of the process
6.      Copies data from a managed array to an unmanaged memory pointer

*/
[DllExport("Replace", CallingConvention.StdCall)]
public static IntPtr Replace([MarshalAs(UnmanagedType.LPWStr) string source, [MarshalAs(UnmanagedType.LPWStr)] string oldText, [MarshalAs(UnmanagedType.LPWStr)] string newText){
        IntPtr result = new IntPtr();                                   //1
        string newText = source.Replace(oldText, newText);              //2
        newText += "\x00";                                              //3
        byte[] buffer = Encoding.Unicode.GetByte(newText);              //4
        result = Marshal.AllocHGlobal(buffer.Length);                   //5
        Marshal.Copy(buffer, 0, result, buffer.Length);                 //6
        return result;
}

Dev Environment:
MT4 Build 1280
VS 2019
Dotnet Framework 4.7.2

I tried


1.      [DllExport("Test", CallingConvention.StdCall)]
        public static void Test([In, Out, MarshalAs(UnmanagedType.LPWStr)] string value)        // NOT WORK (EMPTY value pass in, EMPTY value out)

2.      [DllExport("Test", CallingConvention.StdCall)]
        public static void Test([MarshalAs( UnmanagedType. LPWStr)] ref string value)           // NOT WORK (Access violation read to 0x00000000)

3.      [DllExport("Test", CallingConvention.StdCall)]
        [return: MarshalAs(UnmanagedType.LPWStr)]
        public static string Test([MarshalAs( UnmanagedType. LPWStr)] ref string value)         // Work! BUT cause terminal reconnect every 10 seconds


I took a long time to resolve the problem until I read a blog about C# function return a string to .so library in Linux (Ref: https://dotblogs.com.tw/rjamwxede/2019/08/25/153117)

Hope this small example will help.

mono - C#傳遞string 到so檔的wchar_t | Rme的隨手寫寫 - 點部落
mono - C#傳遞string 到so檔的wchar_t | Rme的隨手寫寫 - 點部落
  • Rme的隨手寫寫
  • dotblogs.com.tw
在windows下C#和C/C++交換wchar_t的資料時沒有什麼問題但linux下卻始終出錯