C ++ Access violation writing at 0x00000000 in dll in mql4

Firstly, I am new to C ++ (almost a week later), so forgive me if this is obvious. Also, I have hunted many posts with similar problems. Either my understanding is simply underdeveloped, or none of them have relevant information to help me understand this problem.

In Metatrader 4, I am trying to figure out how to pass a structured variable to a dll and change the variables stored in the said structure. So far, I have had great success even with structures. Then I ran into a problem.

I've narrowed it down to using strings. If so, please take a look at the following code I used to focus on solving this problem and help me understand why I keep getting the "Write access error at 0x00000000" error whenever I try to run the script in mt4 ...

Mql4 code:

struct Naming
{
  string word;
} name;

#import  "SampleDLLtest.dll"
bool     NameTest(Naming &name);
#import

int init() { return(0); }

int start()
{
   Print("original name: ", name.word);
   if( NameTest( name ) )
   {
     Print("new name: ", name.word);
   }

   //---
   return(0);
}

      

This is the relevant dll code:

#define WIN32_LEAN_AND_MEAN
#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>

BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
   //---
   switch (ul_reason_for_call)
   {
      case DLL_PROCESS_ATTACH:
      case DLL_THREAD_ATTACH:
      case DLL_THREAD_DETACH:
      case DLL_PROCESS_DETACH:
      break;
   }

   //---
   return(TRUE);
}

struct Naming
{
   std::string n_name;
};

bool __stdcall NameTest(Naming *name)
{
   name->n_name = "Captain Success";

   return true;
}

      

+3


source to share


2 answers


From mql4 documentation: http://docs.mql4.com/basis/preprosessor/import

You cannot use the following parameters for imported functions:

  • pointers (*);
  • references to objects containing dynamic arrays and / or pointers.

Classes, string arrays or complex objects containing strings and / or dynamic arrays of any type cannot be passed as a parameter to a function imported from a DLL.

The imported function takes a pointer and apparently is not supported by mql4.

You should probably use a fixed size character array to pass data to and from dlls:

as:



struct Naming {
  char m_name[255];
}

      

The function should accept a reference to this structure (but this is probably not supported) or accept the structure directly and return the structure.

Naming NameTest(Naming name) {

  strncpy(name.m_name, "New Content", sizeof(name.m_name) -1);
  if (sizeof(name.m_name) > 0) {
      name.m_name[sizeof(name)-1] = 0;
  }
  return name;
}

      

The call will look like this:

name = NameTest(name);

      

+2


source


I know this is a little weird, but I am answering my own question because I figured out what was going on ... at least at least.

So here's the deal. Technically speaking, you can pass a structure that contains a string. What you cannot do is edit the line. The structure does not automatically convert a string to char []. So when the dll tries to edit the string, it causes an access violation because the string is not actually a string in C ++, but a char array disguised as a string.

However, I figured out how to pass the structure containing the string and change the value in the dll. This is how I did it.

--- Starting from the mql4 code --- First, I declared a structure with char [] instead of a string.

struct Naming
{
  char word[65];
} name;

      

Then I initialized char [] with a null value, checked it, passed the structure and checked if the value was set correctly.



ArrayInitialize(name.word, '\0');
Print("original name: ", CharArrayToString(name.word));
if( NameTest( name ) )
{
   Print("new name: ", CharArrayToString(name.word));
}

      

--- now the C ++ code --- I have declared the same structure.

struct Naming
{
    char n_name[65];
};

      

Then the function. I first had to write the string literal in a temporary char []. I looped through the for loop to allocate the elements to char [] in the structure. The problem is that char [] from struct is not a constant, but char temp []. I got around this by taking each char into a char variable and then storing that variable value in a char [] structure.

bool __stdcall NameTest(Naming *name)
{
    char temp[] = "Captain Success";

    for (int i = 0; temp[i] != '\0'; i++)
    {
        char t = temp[i];
        name->n_name[i] = t;
    }

    return true;
}

      

This code works nicely.

+1


source







All Articles