C++ 访问冲突写入 mql4 中的 dll 中的 0x00000000
C++ Access violation write to 0x00000000 in dll in mql4
首先,我是 C++ 的新手(学习了将近一个星期),如果这很明显,请原谅我。另外,我已经搜索了许多具有类似问题的帖子。要么我的理解不够深入,要么 none 有相关信息可以帮助我理解这个问题。
在 Metatrader 4 中,我试图找出如何将结构变量传递给 dll,并修改存储在所述结构中的变量。到目前为止,即使在处理结构数组时,我也取得了巨大的成功。然后我遇到了一个问题。
我已将问题缩小到字符串的使用。如果你愿意,请看一下下面的代码,我用它来专注于解决这个问题,并帮助我理解为什么我在尝试 运行 脚本时总是收到这个 'Access violation 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;
}
来自 mql4 的文档:http://docs.mql4.com/basis/preprosessor/import
The following can't be used for parameters in imported functions:
- pointers (*);
- links to objects that contain dynamic arrays and/or pointers.
Classes, string arrays or complex objects that contain strings and/or
dynamic arrays of any types cannot be passed as a parameter to
functions imported from DLL.
导入的函数采用指针,显然 mql4 不支持该指针。
您可能应该使用固定大小的字符数组来将数据传入和传出 dll:
喜欢:
struct Naming {
char m_name[255];
}
该函数需要接受对此结构的引用(但这可能也不被支持)或直接接受结构和 return 结构。
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);
我知道这有点奇怪,但我正在回答我自己的问题,因为我知道发生了什么......至少大部分时间。
所以,这是交易。从技术上讲,您可以传递包含字符串的结构。您不能做的是编辑字符串。结构中不会自动将字符串转换为 char[]。因此,当 dll 尝试编辑字符串时,它会抛出访问冲突,因为字符串在 C++ 中并不是真正的字符串,而是伪装成字符串的字符数组。
也就是说,我确实解决了如何传递包含字符串的结构,并修改了 dll 中的值。这是我的做法。
---从mql4代码开始---
首先,我用 char[] 而不是字符串声明了结构。
struct Naming
{
char word[65];
} name;
然后我用空值初始化char[],检查它,传递结构,并检查值是否设置正确。
ArrayInitialize(name.word, '[=11=]');
Print("original name: ", CharArrayToString(name.word));
if( NameTest( name ) )
{
Print("new name: ", CharArrayToString(name.word));
}
---现在是C++代码---
我声明了相同的结构。
struct Naming
{
char n_name[65];
};
然后是函数。我首先必须在临时 char[] 中捕获字符串文字。我循环了一个 for 循环以将元素分配给结构中的 char[]。问题是,结构中的 char[] 不是常量,而 char temp[] 是。我通过将每个 char 捕获到一个 char 变量,然后将该变量值存储在 struct char[].
中来解决这个问题
bool __stdcall NameTest(Naming *name)
{
char temp[] = "Captain Success";
for (int i = 0; temp[i] != '[=13=]'; i++)
{
char t = temp[i];
name->n_name[i] = t;
}
return true;
}
这段代码工作得很好。
首先,我是 C++ 的新手(学习了将近一个星期),如果这很明显,请原谅我。另外,我已经搜索了许多具有类似问题的帖子。要么我的理解不够深入,要么 none 有相关信息可以帮助我理解这个问题。
在 Metatrader 4 中,我试图找出如何将结构变量传递给 dll,并修改存储在所述结构中的变量。到目前为止,即使在处理结构数组时,我也取得了巨大的成功。然后我遇到了一个问题。
我已将问题缩小到字符串的使用。如果你愿意,请看一下下面的代码,我用它来专注于解决这个问题,并帮助我理解为什么我在尝试 运行 脚本时总是收到这个 'Access violation 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;
}
来自 mql4 的文档:http://docs.mql4.com/basis/preprosessor/import
The following can't be used for parameters in imported functions:
- pointers (*);
- links to objects that contain dynamic arrays and/or pointers.
Classes, string arrays or complex objects that contain strings and/or dynamic arrays of any types cannot be passed as a parameter to functions imported from DLL.
导入的函数采用指针,显然 mql4 不支持该指针。
您可能应该使用固定大小的字符数组来将数据传入和传出 dll:
喜欢:
struct Naming {
char m_name[255];
}
该函数需要接受对此结构的引用(但这可能也不被支持)或直接接受结构和 return 结构。
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);
我知道这有点奇怪,但我正在回答我自己的问题,因为我知道发生了什么......至少大部分时间。
所以,这是交易。从技术上讲,您可以传递包含字符串的结构。您不能做的是编辑字符串。结构中不会自动将字符串转换为 char[]。因此,当 dll 尝试编辑字符串时,它会抛出访问冲突,因为字符串在 C++ 中并不是真正的字符串,而是伪装成字符串的字符数组。
也就是说,我确实解决了如何传递包含字符串的结构,并修改了 dll 中的值。这是我的做法。
---从mql4代码开始--- 首先,我用 char[] 而不是字符串声明了结构。
struct Naming
{
char word[65];
} name;
然后我用空值初始化char[],检查它,传递结构,并检查值是否设置正确。
ArrayInitialize(name.word, '[=11=]');
Print("original name: ", CharArrayToString(name.word));
if( NameTest( name ) )
{
Print("new name: ", CharArrayToString(name.word));
}
---现在是C++代码--- 我声明了相同的结构。
struct Naming
{
char n_name[65];
};
然后是函数。我首先必须在临时 char[] 中捕获字符串文字。我循环了一个 for 循环以将元素分配给结构中的 char[]。问题是,结构中的 char[] 不是常量,而 char temp[] 是。我通过将每个 char 捕获到一个 char 变量,然后将该变量值存储在 struct char[].
中来解决这个问题bool __stdcall NameTest(Naming *name)
{
char temp[] = "Captain Success";
for (int i = 0; temp[i] != '[=13=]'; i++)
{
char t = temp[i];
name->n_name[i] = t;
}
return true;
}
这段代码工作得很好。