我正在用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;
}
我的问题是,当从MQL4
调用HistoricMarketData
时,它不起作用。该脚本要么导致整个MetaTrader程序崩溃,要么引发异常并失败。
正如您所看到的,我正在使用Robert Giesecke的Unmanaged Exports库使其工作,并且我正确地将DLL
导入到MQL4
,因为里面的其他函数都在正常工作,没有任何问题。
经过大量的尝试和错误,我发现当我从结构中删除这两个字符串属性(symbol
和time
)时,所有的工作都如预期的那样,并且结构正确地传递给了C#
函数。
所以我的问题是如何正确地将结构中的字符串从MQL4
传递到C#
我已经尝试将结构中MarshalAs
注释处的UnmanagedType
参数更改为其他字符串变体,但没有帮助。将CCD_ 17改为CCD_。
如果有任何建议或帮助,我将不胜感激。
谢谢!
欢迎来到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导入的函数
但魔鬼隐藏在这样的细节中(间接禁止功能):
简单结构
不包含字符串或动态数组对象的结构称为简单结构;这种结构的变量可以自由地相互复制,即使它们是不同的结构。简单结构的变量及其数组可以作为参数传递到从DLL导入的函数。