Нарушение доступа C ++, запись в 0x00000000 в dll в mql4

Во-первых, я новичок в C ++ (почти неделю), так что простите, если это очевидно. Кроме того, я охотился через много сообщений с похожими проблемами. Либо мое понимание просто недостаточно развито, либо ни у кого не было соответствующей информации, чтобы помочь мне понять эту проблему.

В Metatrader 4 я пытаюсь выяснить, как передать структурную переменную в dll и изменить переменные, хранящиеся в указанной структуре. До сих пор я имел большой успех, даже когда имел дело со структурными массивами. Тогда я столкнулся с проблемой.

Я сузил проблему до использования строк. Если хотите, взгляните на следующий код, который я использовал, чтобы сосредоточиться на решении этой проблемы, и помогите мне понять, почему я продолжаю получать эту ошибку «Access error write to 0x00000000» всякий раз, когда я пытаюсь запустить скрипт в mt4 ,

Код MQL4:

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);
}

Это соответствующий код DLL:

#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

Решение

Из документации mql4: http://docs.mql4.com/basis/preprosessor/import

Следующее нельзя использовать для параметров в импортируемых функциях:

  • указатели (*);
  • ссылки на объекты, которые содержат динамические массивы и / или указатели.

Классы, строковые массивы или сложные объекты, которые содержат строки и / или
динамические массивы любых типов не могут быть переданы в качестве параметра
функции импортированные из DLL.

Импортированная функция берет указатель, и это, очевидно, не поддерживается mql4.

Вам, вероятно, следует использовать массив символов фиксированного размера для передачи данных в и из dll:

лайк:

struct Naming {
char m_name[255];
}

Функция должна была бы принять ссылку на эту структуру (но это, вероятно, также не поддерживается) или принять структуру напрямую и вернуть структуру.

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;
}

Вызов это будет выглядеть так:

name = NameTest(name);
2

Другие решения

Я знаю, что это немного странно, но я отвечаю на свой вопрос, потому что я выяснил, что происходит … по крайней мере, в основном.

Итак, вот сделка. Технически говоря, вы можете передать структуру, содержащую строку. Что вы не можете сделать, это отредактировать строку. В структуре нет автоматического преобразования строки в тип char []. Таким образом, когда dll пытается редактировать строку, она выбрасывает нарушение прав доступа, потому что строка на самом деле не является строкой в ​​C ++, но является массивом символов, замаскированным под строку.

Тем не менее, я решил, как передать структуру, содержащую строку, и изменить значение в DLL. Вот как я это сделал.

—Начиная с кода mql4 —
Сначала я объявил структуру с символом [] вместо строки.

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

Затем я инициализировал char [] нулевым значением, проверил его, передал структуру и проверил, правильно ли установлено значение.

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

—Теперь к коду C ++ —
Я объявил ту же структуру.

struct Naming
{
char n_name[65];
};

Тогда функция. Сначала я должен был захватить строковый литерал во временном символе []. Я зациклил цикл for для распределения элементов в char [] в структуре. Проблема в том, что char [] из структуры не является const, а char temp [] есть. Я справился с этим, захватив каждый символ в переменную char, а затем сохранив значение этой переменной в struct char [].

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;
}

Этот код работает прекрасно.

1

По вопросам рекламы [email protected]