[英]C++ Access violation write to 0x00000000 in dll in mql4
首先,我是C ++的新手(將近一周),如果這很明顯,請原諒我。 此外,我已經搜索了許多類似問題的帖子。 要么我的理解不夠發達,要么沒有相關信息來幫助我理解這個問題。
在Metatrader 4中,我試圖弄清楚如何將結構變量傳遞給dll,並修改存儲在所述結構中的變量。 到目前為止,即使在處理結構數組時,我也取得了很大的成功。 然后我遇到了一個問題。
我已將問題縮小到使用字符串。 如果你願意的話,請看看下面的代碼,我曾經把它集中在解決這個問題上,並幫助我理解為什么每當我嘗試在mt4中運行腳本時,我都會繼續收到“訪問沖突寫入0x00000000”錯誤。
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
以下內容不能用於導入函數中的參數:
- 指針(*);
- 鏈接到包含動態數組和/或指針的對象。
包含任何類型的字符串和/或動態數組的類,字符串數組或復雜對象不能作為參數傳遞給從DLL導入的函數。
導入的函數采用指針,mql4顯然不支持。
您應該使用固定大小的字符數組來傳遞數據到dll和從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);
我知道這有點奇怪,但我回答了我自己的問題,因為我弄清楚發生了什么......至少大部分都是這樣。
所以這里是交易。 從技術上講,您可以傳遞包含字符串的結構。 你不能做的是編輯字符串。 結構中沒有字符串自動轉換為char []。 因此,當dll嘗試編輯字符串時,它會拋出訪問沖突,因為字符串實際上不是C ++中的字符串,而是偽裝成字符串的char數組。
也就是說,我確實解決了如何傳遞包含字符串的結構,並修改dll中的值。 我就是這樣做的。
---從mql4代碼開始---首先,我用char []而不是字符串聲明了struct。
struct Naming
{
char word[65];
} name;
然后我用null值初始化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];
};
然后功能。 我首先必須在臨時char []中捕獲字符串文字。 我循環了一個for循環,將元素分配給struct中的char []。 問題是,struct中的char []不是const,而char temp []是。 我通過將每個char捕獲到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;
}
這段代碼很漂亮。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.