【问题标题】:How to create a DLL, which accepts strings from MT4 and returns back string type?如何创建一个 DLL,它接受来自 MT4 的字符串并返回字符串类型?
【发布时间】:2016-12-13 12:52:33
【问题描述】:

我尝试了两个星期来创建一个 DLL,我可以向其传递字符串并获取字符串。但还是没有成功。

我在 Dev-C++(TDM-GCC 4.9.2) 和 Visual Studio 社区 2015 上进行了尝试。我对此进行了很多搜索,并尝试了几乎所有找到的示例代码,但没有成功。

我必须将此 DLL 与 MetaTrader 终端 4 一起使用。
这是我使用的一个示例代码。这段代码编译成功,但是当我发送一个 string 给它时,来自 MT4,我得到一个访问冲突错误。

#ifndef MYLIB_HPP
#define MYLIB_HPP

#include <string>

#ifdef MYLIB_EXPORTS
#define MYLIB_API __declspec(dllimport) 
#else
#define MYLIB_API __declspec(dllexport) 
#endif
bool MYLIB_API test(const std::string& str);
#endif

bool MYLIB_API MyTest(const std::string& str)
{
    return (str == "Hi There");
}

【问题讨论】:

标签: c++ dll mql4 metatrader4 mt4


【解决方案1】:

如果您确实在 DLL 和另一个可执行文件之间共享 C++ string,则两者都需要使用相同的工具链进行编译。这是因为std::string 仅在标头中定义。因此,如果 DLL 和可执行文件使用不同的 string 标头,它们很可能是二进制不兼容的。

如果您想确保不同的工具链都能正常工作,请坚持使用以 NULL 结尾的 C 字符串。

【讨论】:

  • 您可能已经意识到问题出在 MQL4 不是 C 语言并且 MetaTrader 终端 4 MetaLanguage 编译器 + 代码执行环境不将 string 表示为 string,但更像是struct。我们在这里碰撞。所有其余的只是从这个事实向前推进。 享受这一天,多伦。
【解决方案2】:

您刚刚体验了 MQL4 技巧之一,
MQL4 string 不是 string 而是 struct 因此 在 MQL4 方面#import 将使 MT4 注入它,不符合您的 DLL C 端期望并且访问冲突错误很简单,因为您的 C 端代码试图访问 MQL4 区域...


设计 API/DLL 的第一条规则:仔细阅读文档。

是的,有人可能会反对,说 MQL4 文档有点难以理解,但因此比规则#1 还要多一倍,请非常、非常、非常仔细地阅读文档,因为一些重要的设计事实几乎隐藏在一些不太清楚的地方可预测的章节或 ENUM 表的解释、编译器指令、pragma-s side-notes et al.


第二条规则:设计API/DLL接口,以便顺利集成

MQL4 在某个地方更改了关于 Build 670+ 的规则。好消息是,MetaQuotes 已宣布,他们不会对 MT4 的进一步开发进行进一步投资,因此 DLL/API 集成的 MT4 方面有望停止进一步蔓延。

鉴于您的声明,即您设计 DLL/API,请尝试设计面向未来的规范——使用 uchar[]-s 块而不是“解释”-敏感 @ 987654327@通过引用传递输入和输出,只返回某种形式的int aReturnCODE = myDLL_FUNC( byRefParA, byRefParB, byRefRESULT );,你的努力将产生干净的代码,更好的可移植性第三方语言包装器,还将最大限度地减少您的进一步维护成本。

【讨论】:

    【解决方案3】:

    很可能,您的代码和您要链接的代码已使用 std::string 的不同 ABI 编译,即库使用的字符串与您使用的字符串具有不同的内存布局(和 sizeof) '正在编译。

    我曾经在链接 hdf5 库并使用 gcc 时遇到过这个问题。在这种情况下,可以通过恢复到以前的 ABI 来解决问题,如 here 所述。

    但是,当没有这样的解决方案时,clang 也出现了问题。因此,为了使这一切正常工作,我必须避免在对使用不同 ABI 编译的库(在我的情况下为 hdf5)的任何调用中使用std::string,而是使用const char* 来处理 hdf5 接口。

    【讨论】:

    • 它不起作用 以何种方式?如果它没有编译,那么你只是没有遵守 API。
    • @Walter 关于 DLL 端双 ABI 的想法不错,但是,MQL4 不是 C 语言,而且 MetaTrader 终端 4 MetaLanguage 编译器 + 代码执行环境不代表 stringstring,但更像是struct。这是问题的根本原因。所有其余的只是从这个事实向前推进。 享受这一天,沃尔特。
    • @user3666197 这不正是我所说的吗?该库使用不同的 ABI(不是std::string,而是一些struct 的内存布局与调用者的std::string 中使用的内存布局不同)。
    • 明白你的看法,沃尔特,不过,我敢同意这个想法。最好的 neutral 模式是将纯容器(非结构化 buf-blocks)按引用传递为(uchar[])+一个 int 标量,用于缓冲区块内有效数据的有效长度(两者都在方式“那里”和“回来”)。永远不知道,下一次那个内部秘密什么时候会悄悄改变。
    • @user3666197 不,我还没有听到过血腥的部分。听起来像一个严重的公鸡。
    猜你喜欢
    • 2021-11-29
    • 2022-11-15
    • 1970-01-01
    • 2021-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多