Unable to return Binance Spot account balances from DLL

0

I tried fetching total Balance from Binance API in C# using glitch100/BinanceDotNet library with some modifications (like converting those data members from private to public static)

The purpose of this is to be called by an MQL5 function for MT5 usage

My C# code for the DLL is somewhat like this:

using System;
using System.Text;
using RGiesecke.DllExport;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO.Pipes;
using System.IO;
using BinanceExchange.API.Client;

namespace BinanceAPIConnectMetaTrader
{
    class Program
    {

        public static string DataServerReturn = null;

        [DllExport("APIFetchTotalFreeBalance", CallingConvention = CallingConvention.StdCall)]
        public static IntPtr APIFetchTotalFreeBalance(int _AccountType, IntPtr _ApiKey, IntPtr _SecretKey)
        {
            if (_AccountType == 0)
            {
                BinanceExchange.API.Endpoints.APIPrefix = "https://api.binance.com/api";
                BinanceExchange.API.Endpoints.WAPIPrefix = "https://api.binance.com/wapi";
                BinanceExchange.API.Websockets.AbstractBinanceWebSocketClient.BaseWebsocketUri = "wss://stream.binance.com:9443/ws";
                BinanceExchange.API.Websockets.AbstractBinanceWebSocketClient.CombinedWebsocketUri = "wss://stream.binance.com:9443/stream?streams";
            }
            else
            {
                BinanceExchange.API.Endpoints.APIPrefix = "https://testnet.binance.vision/api";
                BinanceExchange.API.Endpoints.WAPIPrefix = "https://testnet.binance.vision/wapi";
                BinanceExchange.API.Websockets.AbstractBinanceWebSocketClient.BaseWebsocketUri = "wss://testnet.binance.vision/ws";
                BinanceExchange.API.Websockets.AbstractBinanceWebSocketClient.CombinedWebsocketUri = "wss://testnet.binance.vision/stream?streams";
            }

            decimal total_free_balance = 0.0M;
            
            string apiKey = new MqlString(_ApiKey).Get();
            string secretKey = new MqlString(_SecretKey).Get();

            //Initialise the general client with config
            var client = new BinanceClient(new ClientConfiguration()
            {
                ApiKey = apiKey,
                SecretKey = secretKey,
            });

            
            try
            {
                client.GetAccountInformation(3500).Result.Balances.ForEach(k =>
                {
                   total_free_balance += k.Free;
                });
            
            }
            catch (Exception ex)
            {
                string str = "Exception from dll : " + ex.Message;
                return Marshal.StringToHGlobalAuto(str.ToString());
            }
            
            IntPtr ret = Marshal.StringToHGlobalAuto(total_free_balance.ToString());
            return ret;
        }

    }

    public class StreamString
    {
        private Stream ioStream;
        private UnicodeEncoding streamEncoding;

        public StreamString(Stream ioStream)
        {
            this.ioStream = ioStream;
            streamEncoding = new UnicodeEncoding();
        }

        public string ReadString()
        {
            int len;
            len = ioStream.ReadByte() * 256;
            len += ioStream.ReadByte();
            byte[] inBuffer = new byte[len];
            ioStream.Read(inBuffer, 0, len);

            return streamEncoding.GetString(inBuffer);
        }

        public int WriteString(string outString)
        {
            byte[] outBuffer = streamEncoding.GetBytes(outString);
            int len = outBuffer.Length;
            if (len > UInt16.MaxValue)
            {
                len = (int)UInt16.MaxValue;
            }
            ioStream.WriteByte((byte)(len / 256));
            ioStream.WriteByte((byte)(len & 255));
            ioStream.Write(outBuffer, 0, len);
            ioStream.Flush();

            return outBuffer.Length + 2;
        }
    }

    class MqlString
    {
        private readonly IntPtr _pointer;

        public MqlString(IntPtr pointer)
        {
            _pointer = pointer;
        }

        public string Get()
        {
            int size;

            for (int i = 0; ; i += 2)
            {
                if (Marshal.ReadByte(_pointer, i) == 0)
                {
                    size = i;
                    break;
                }
            }

            byte[] bytes = new byte[size];

            for (int i = 0; i < size; i++)
            {
                bytes[i] = Marshal.ReadByte(_pointer, i);
            }

            return Encoding.Unicode.GetString(bytes);
        }
    }
}

  1. When this function is called, then the exception is caught & the message is displayed as follows:
Total free balance = Exception from dll : One or more errors occurred.
  1. After removing try keyword and its braces and commenting out the inside of catch block, when this function is called, then some funny runtime exception is displayed at MT5 side log messages as follows:
Unhandled exception 0xE0434352
              00007FFE51603AC0 4881ECD8000000    sub        rsp, 0xd8
              00007FFE51603AC7 488B0562732200    mov        rax, [rip+0x227362]
              00007FFE51603ACE 4833C4            xor        rax, rsp
              00007FFE51603AD1 48898424C0000000  mov        [rsp+0xc0], rax
              00007FFE51603AD9 488364242800      and        qword [rsp+0x28], 0x0
              00007FFE51603ADF 488D05DAFFFFFF    lea        rax, [rip-0x26]
              00007FFE51603AE6 83E201            and        edx, 0x1
              00007FFE51603AE9 894C2420          mov        [rsp+0x20], ecx
              00007FFE51603AED 89542424          mov        [rsp+0x24], edx
              00007FFE51603AF1 4889442430        mov        [rsp+0x30], rax
              00007FFE51603AF6 4D85C9            test       r9, r9
              00007FFE51603AF9 744B              jz         0x7ffe51603b46
              
              00007FFE51603AFB B80F000000        mov        eax, 0xf
              00007FFE51603B00 488D4C2440        lea        rcx, [rsp+0x40]
              00007FFE51603B05 443BC0            cmp        r8d, eax
              00007FFE51603B08 498BD1            mov        rdx, r9
              00007FFE51603B0B 440F47C0          cmova      r8d, eax
              00007FFE51603B0F 4489442438        mov        [rsp+0x38], r8d
              00007FFE51603B14 49C1E003          shl        r8, 0x3
              00007FFE51603B18 E84AD30400        call       0x7ffe51650e67  ; PublisherFromPackageFullName (kernelbase.dll)
              00007FFE51603B1D 488D4C2420        lea        rcx, [rsp+0x20]
              00007FFE51603B22 48FF15FF441600    call       qword near [rip+0x1644ff]  ; UnhandledExceptionFilter (kernelbase.dll)
   crash -->  00007FFE51603B29 0F1F440000        nop        [rax+rax+0x0]
              00007FFE51603B2E 488B8C24C0000000  mov        rcx, [rsp+0xc0]
              00007FFE51603B36 4833CC            xor        rcx, rsp
              00007FFE51603B39 E8A25E0400        call       0x7ffe516499e0  ; RemoveDllDirectory (kernelbase.dll)
              00007FFE51603B3E 4881C4D8000000    add        rsp, 0xd8
              00007FFE51603B45 C3                ret        

              00007FFE51603B46 8364243800        and        dword [rsp+0x38], 0x0

00: 0x00007FFE51603B29

I am really clueless about what this is & how to resolve it.

This code is the problematic part (but it is working fine when built as EXE as in the GitHub page of glitch100/BinanceDotNet/BinanceExchange.Console/ExampleProgram.cs)

client.GetAccountInformation(3500).Result.Balances.ForEach(k =>
{
    total_free_balance += k.Free;
});
c#
dll
binance
mql5
metatrader5
asked on Stack Overflow Mar 9, 2021 by test

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0