Access violation read error and MT4 crash when using custom indicator and C++ DLL

To add comments, please log in or register
Behdad Ahmadi
46
Behdad Ahmadi  
Hello, I'm coding an Indicator which call a function from C++ DLL . I need to pass only Close rates to DLL and retrun a string from DLL.


#import "PythonZones.dll"
void CalculateZones(double &data[], double quantile, int arraySize,char&[]);
#import

//+------------------------------------------------------------------+

//|                                               SuppResistance.mq4 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+




#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
char buffer[4096];
input color M5color = clrTurquoise;

input int WINDOW = 446;
input double PARAM_SHIFT = 0.14;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
 
//---
   return(INIT_SUCCEEDED);
  }
  
  int deinit()
  {
//----
DeleteAllCreatedObjects();
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+

int start()
  {
    if (IsNewBar()){
         double data[];
         ArrayResize(data,WINDOW);
         Rate(data,WINDOW);
         Print(data[0]);
         CalculateZones(data,PARAM_SHIFT ,WINDOW,buffer);
         string zones = CharArrayToString(buffer);
         Print(zones);
         DeleteAllCreatedObjects();
         CreateObjects("MARKET",zones,M5color,1);
 
  }

 
   return(0);
}





void Rate(double &out[],int len){
        for(int i=(len - 1);i>-1;i--){
         double close = iClose(NULL,0,i+1);
         out[i] = close;
      }   
 }
   
bool IsNewBar()
{
   static datetime lastbar;
   datetime curbar = (datetime)SeriesInfoInteger(_Symbol,_Period,SERIES_LASTBAR_DATE);
   Print(lastbar);
   Print(curbar);
   if(lastbar != curbar)
   {
      lastbar = curbar;
      return true;
   }
   return false;
}


 void CreateObjects(string suffixName,string zones,color colorCode, int width){
   string sep=",";
   ushort u_sep;  
   string result[]; 
   u_sep=StringGetCharacter(sep,0);
   int k=StringSplit(zones,u_sep,result);
   
      if(k>0)
        {
         for(int i=0;i<k;i++)
           {
               string name = "ZONE-"+suffixName + result[i];
               ObjectCreate(name,OBJ_HLINE,0,D'2004.02.20 12:30', result[i]);
               
               ObjectSetInteger(0,name,OBJPROP_COLOR,colorCode);
               //ObjectSetInteger(0,name,OBJPROP_WIDTH,1);
               ObjectSetInteger(0,name,OBJPROP_STYLE,1);
               
           }
        }
 }
   
 void DeleteAllCreatedObjects(){
 for(int iObj=ObjectsTotal()-1; iObj >= 0; iObj--){
        string on = ObjectName(iObj);
        if (StringFind(on, "ZONE") == 0)  ObjectDelete(on);
 
      }
 
  }


And C++ DLL Code ( I use VS2013):


//+------------------------------------------------------------------+
//|                                              Sample DLL for MQL4 |
//|                 Copyright © 2004-2006, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#define WIN32_LEAN_AND_MEAN  // Exclude rarely-used stuff from Windows headers
//#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <windows.h>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include "Python.h"
#include "numpy/arrayobject.h"
//----
#define MT4_EXPFUNC __declspec(dllexport)

PyObject *Amanda;
PyObject *AmandaZones;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
#pragma pack(push,1)

//struct RateInfo
 // {
//   unsigned int      ctm;
//   double            open;
//   double            low;
//   double            high;
//   double            close;
//   double            vol;
//  };


#pragma pack(pop)

//----
//struct MqlStr
 // {
 //  int               len;
 //  char             *string;
 // };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
  {
//----
   switch(ul_reason_for_call)
     {
      case DLL_PROCESS_ATTACH:
          Py_Initialize();
          import_array1(-1);
          PyObject *pName;
          pName = PyString_FromString("Amanda");
                  Amanda = PyImport_Import(pName);
          Py_DECREF(pName);
                  if (Amanda != NULL){
                          AmandaZones = PyObject_GetAttrString(Amanda, "CalculateZones");
                          if (AmandaZones == NULL){
                 OutputDebugString("Failed to get desired func.");
             }
          }else{
              OutputDebugString("Failed to load Amanda.");
          }
          OutputDebugString("Attached.");
          break;
      case DLL_THREAD_ATTACH:
          break;
      case DLL_THREAD_DETACH:

          break;
      case DLL_PROCESS_DETACH:
                  Py_DECREF(Amanda);
                  Py_DECREF(AmandaZones);
          Py_Finalize();
          break;
     }
//----
   return(TRUE);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
MT4_EXPFUNC void __stdcall CalculateZones(double *data, double quantile, int arraySize,char *buffer)
  {

        if (arraySize < 0) return;


        npy_intp npy_arraysize;

        npy_arraysize = arraySize;
        PyObject *q = PyFloat_FromDouble(quantile);
        PyObject *np_value = PyArray_SimpleNewFromData(1, &npy_arraysize, NPY_DOUBLE, data);
        Py_INCREF(np_value);;
        Py_INCREF(q);;
        PyObject *pArgs = PyTuple_New(2);
        PyTuple_SetItem(pArgs, 0, np_value);
        PyTuple_SetItem(pArgs, 1, q);
 
 
        PyObject *pResult = PyObject_CallObject(AmandaZones, pArgs);
   Py_DECREF(pArgs);
   Py_DECREF(np_value);
   Py_DECREF(q);

   char* res = PyString_AsString(pResult);

   Py_DECREF(pResult);


   strcpy(buffer,res);
   

   //buffer = res;
 //  if (buffer && data){
   //buffer = res;
           //strcpy(buffer, res);
  // }
   //return 1;
        
//----
  // return(mean);
  }


Indicator works perfectly, but when I remove the indicator from the chart and add it again, It doesn't work anymore and returns an error "Access violation read" .

And also when I use it with strategy tester, Meta Trader crashes without logging any error.

I think the problem is with the array referencing. I attempted to try it with using struct instead of arrays, but I couldn't compile it any way because I don't know  MQL or C++ well, but I work a lot with Python,C# and Swift .

How can I solve the problem? 

Thank you

To add comments, please log in or register