簡體   English   中英

C ++訪問沖突在mql4中寫入dll中的0x00000000

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM