我正在使用 MQL4
语言为MetaTrader Terminal 4编写一个脚本,该脚本使用 C#DLL库进行进一步的数据处理。
我要做的是传递一组以下MQL4
- 结构:
struct marketUpdate
{
double openPrice;
double closePrice;
double highPrice;
double lowPrice;
int volume;
double pipValuePerLot;
int intervalLength;
string symbol;
string time;
};
到C# DLL
中的此功能:
[DllExport("HistoricMarketData", CallingConvention.StdCall)]
public static int HistoricMarketData(
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] MarketUpdate[] unmanagedArray,
int length)
{
// further processing
}
这是MQL4
方面的功能定义:
int HistoricMarketData(
marketUpdate &marketUpdates[],
int length);
这是C#
方面的结构:
[StructLayout(LayoutKind.Explicit)]
public struct MarketUpdate
{
[MarshalAs(UnmanagedType.R8)]
[FieldOffset(0)]
public double openPrice;
[MarshalAs(UnmanagedType.R8)]
[FieldOffset(8)]
public double closePrice;
[MarshalAs(UnmanagedType.R8)]
[FieldOffset(16)]
public double highPrice;
[MarshalAs(UnmanagedType.R8)]
[FieldOffset(24)]
public double lowPrice;
[MarshalAs(UnmanagedType.I4)]
[FieldOffset(32)]
public int volume;
[MarshalAs(UnmanagedType.R8)]
[FieldOffset(36)]
public double pipValuePerLot;
[MarshalAs(UnmanagedType.I4)]
[FieldOffset(44)]
public int intervalLength;
[MarshalAs(UnmanagedType.LPWStr)]
[FieldOffset(48)]
public string symbol;
[MarshalAs(UnmanagedType.LPWStr)]
[FieldOffset(60)]
public string time;
}
我的问题是,从HistoricMarketData
致电MQL4
时,它无效。该脚本要么崩溃整个MetaTrader程序,要么抛出异常而失败。
正如您所看到的,我正在使用Robert Giesecke的非托管导出库来使其正常工作,并且我正确地将DLL
导入MQL4
,因为内部的其他功能无需任何工作问题。
经过大量的反复试验后,我发现当我从结构中删除这两个字符串属性(symbol
和time
)时,所有工作都按预期工作,并且结构正确传递给{{ 1}}功能。
所以我的问题是如何正确地将结构中的字符串从C#
传递到MQL4
?
我已经尝试将结构C#
注释中的UnmanagedType
参数更改为其他字符串变体,但它没有帮助。将双方的MarshalAs
更改为string
也无济于事。
我会感激任何建议或帮助。
谢谢!
答案 0 :(得分:2)
MQL4
的野外世界,其中string
不是字符串,而是struct
所以,
对此,
而不仅仅是这个,
重新整合MQL4
和DLL
- s
我自己的策略是:
1)避免MQL4
- 字符串,如果不是核心重要性,
2)如果需要,通过DLL
代理实用程序函数传递它们,该函数处理所需的转换:
#import <dll> // DLL-native CallSignatures:
...
int mql4s_send ( int socket, uchar &text[] );
...
#import
// DLL-proxy with StringToCharArray() conversion:
int s_send ( int socket, string text ) { uchar textChar[]; StringToCharArray( text, textChar );
return ( mql4s_send ( socket, textChar ) );
}
无论如何,更确切地说,阅读MQL4
帮助,在每次MetaTrader Build更新后再次更好地重新阅读(是的,我说,新的帮助文件包含(至少)对新MQL4
- 功能的一些评论,没有其他简单的方法可以找到和了解 - 它节省了大量的时间。在维护代码库的情况下,跨越了几百人*年,我非常了解疼痛。)
以下内容不能用于导入功能中的参数:
·指针;
·链接到包含动态数组和/或指针的对象
包含字符串和/或任何类型的动态数组的类,字符串数组或复杂对象不能作为参数传递作为从DLL导入的函数的参数。
但是Devil隐藏在这样的细节中(间接禁止的特征):
...
简单结构
不包含动态数组的字符串或对象的结构称为简单结构;这些结构的变量可以自由地相互复制,即使它们是不同的结构。简单结构的变量以及它们的数组可以作为参数传递给从DLL导入的函数。