MQL array to C# DLL only passes 1 row

 

Hi,

When I send an array of ints from MQL to C# DLL I only received one of them. In C# im just looping through the int values and attaching them to the return string, also attaching count of array elements to the return string.

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ExpertAdvisor.Chart;
using System.Runtime.InteropServices;

namespace ExpertAdvisor
{
    public class Order
    {
       
        [DllExport("TestArray", CallingConvention = CallingConvention.StdCall)]
        [return: MarshalAs(UnmanagedType.LPWStr)]
        public static string TestArray([MarshalAs(UnmanagedType.LPArray)] int[] bars)
        {
            string value = "";

            foreach (int bar in bars)
            {
                value += " " + bar;
               
            }

            value += " " + bars.Length;

            return value;
        }
    }
}


MQL


#import "ExpertAdvisor.dll"
  string TestArray(int &bars[]);
#import

int OnInit()
  {
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
  }

void OnTick()
  {
    int barsInt[3] = {1, 2, 3};  
  
   Alert(TestArray(barsInt));

}


Hope you can help.

/Hendrik

 
DLL is not aware of the size of array, you should pass it as a parameter to DLL function.
 

Since October 2018, MQL5 supports native integration with Net Framework libraries. Native support means that types, methods and classes placed in the .Net library are now accessible directly from an MQL5 program without prior declaration of the calling functions and their parameters, as well as without the complex typecasting of the two languages. https://www.mql5.com/en/articles/5563

Using the examples from that article https://www.mql5.com/en/articles/249

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace ExpertAdvisor
{
    public static class Order
    {
        public static string TestString()
        {
            return "123444";
        }

        public static string SayGreeting([MarshalAs(UnmanagedType.LPWStr)] string name)
        {
            return "Hello " + name;
        }

        public static int Add(int left, int right)
        {
            return left + right;
        }

        public static int Sub(int left, int right)
        {
            return left - right;
        }

        public static double AddDouble(double left, double right)
        {
            return left + right;
        }

        public static float AddFloat(float left, float right)
        {
            return left + right;
        }

        public static int Get1DInt([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]  int[] tab, int size, int idx)
        {
            return tab[idx];
        }

        public static float Get1DFloat([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]  float[] tab, int size, int idx)
        {
            return tab[idx];
        }

        public static double Get1DDouble([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]  double[] tab, int size, int idx)
        {
            return tab[idx];
        }

        [return: MarshalAs(UnmanagedType.LPWStr)]
        public static string TestArray([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] bars, int size)
        {
            string value = "";

            foreach (int bar in bars)
            {
                value += " " + bar;
            }

            value += " " + bars.Length;

            return value;
        }

    }
}


Compile the DLL from command line 

C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /optimize /platform:x64 /target:library ExpertAdvisor.cs


MQL

#import "ExpertAdvisor.dll"

void OnStart()
  {
   Print(Order::TestString());
   Print(Order::SayGreeting("MQL5"));

//---
   for(int i=0; i<3; i++)
     {
      Print(Order::Add(i,666));
      Print(Order::Sub(666,i));
      Print(Order::AddDouble(666.5,i));
      Print(Order::AddFloat(666.5,-i));
     }
//---
#define SIZE 3
   int tab[SIZE]= {11,22,33};
   float tfloat[SIZE]= {0.5,1.0,1.5};
   double tdouble[SIZE]= {0.5,1.0,1.5};

   for(int i=0; i<SIZE; i++)
     {
      Print(tab[i]);
      Print(Order::Get1DInt(tab,SIZE,i));
      Print(Order::Get1DFloat(tfloat,SIZE,i));
      Print(Order::Get1DDouble(tdouble,SIZE,i));
     }
//---
   Print(Order::TestArray(tab,SIZE));
  }
Exposing C# code to MQL5 using unmanaged exports
Exposing C# code to MQL5 using unmanaged exports
  • www.mql5.com
In this article I presented different methods of interaction between MQL5 code and managed C# code. I also provided several examples on how to marshal MQL5 structures against C# and how to invoke exported DLL functions in MQL5 scripts. I believe that the provided examples may serve as a basis for future research in writing DLLs in managed code. This article also open doors for MetaTrader to use many libraries that are already implemented in C#.
 
Thank you guys. I got the array working :)
 
amrali #:

Since October 2018, MQL5 supports native integration with Net Framework libraries. Native support means that types, methods and classes placed in the .Net library are now accessible directly from an MQL5 program without prior declaration of the calling functions and their parameters, as well as without the complex typecasting of the two languages. https://www.mql5.com/en/articles/5563

Using the examples from that article https://www.mql5.com/en/articles/249

C#


Compile the DLL from command line 


MQL

Thank you, it works when single DLL compiled from CSC but not from Visual Studio 2022. Do you know why? I tried targeting dotnet6, dotnet5, dotnet2.1 - none worked. Is there a VS solution available with this working please? Thanks

 
Faisal Mahmood #:

Thank you, it works when single DLL compiled from CSC but not from Visual Studio 2022. Do you know why? I tried targeting dotnet6, dotnet5, dotnet2.1 - none worked. Is there a VS solution available with this working please? Thanks

Target Net 4.8

 
amrali #:

Target Net 4.8

Are there any big differences when targeting net standard 2.0 on the MQL side?