查看自由DLL接口规范的源代码
←
自由DLL接口规范
跳转到:
导航
,
搜索
根据下列原因,你没有权限编辑本页:
您刚才请求的操作只有这个用户组中的用户才能使用:
用户
您可以查看并复制此页面的源代码:
=简介= 相比传统DLL接口(飞狐接口),自由DLL接口的特点是参数更加灵活,由用户指定传入的参数,参数类型是c/c++的标准数据类型。 传统DLL必须引入一个CalcInfo的结构化参数,通过它来传入行情数据,这种设计的好处是用户操心得少一些,因为数据总是有的,不利之处是限制了发挥,难以返回多个序列结果,难以接入没有按接口要求编写的DLL。 自由DLL接口,不再传入CalcInfo参数,取而代之的是,用户必须自己负责传入所有的数据。获得的回报是, 1.支持任意多的参数。 2.支持引用参数,也就是说,可以改变参数的值并返回给公式系统。 3.更灵活的参数传递。例如,可以根据需要传入地址,也可以传入值。 4.支持逐根的计算。每次只计算一根的值并返回单值。自由DLL只能在逐根模式下运行。 与传统接口DLL一样,自由接口DLL也必须放置在FmlDLL目录下。 =自由DLL声明= 为了让公式系统知道DLL的参数格式,调用前需要使用extern语句进行声明 extern 返回值类型 函数名(参数类型1, 参数类型2...); 参数的个数没有限制 =参数类型= 传入DLL的参数有类型限制,目前支持的C类型包括 float, double, int,BOOL, LONG, DWORD, float*, LPCWSTR等 不支持double * =返回值类型= 公式中,有些类型的名字与C不同。 其中,float*,有可能是NumericRef,也可能是NumericSeries,还可以是NumericArray 。 但打算传入单值,并改变值返回,那么用NumericRef,如果打算传入序列那么用NumericSeries,如果传入数组,那么用NumericArray 。 =自由DLL接口的调用= *声明过的函数,可以通过函数名直接调用,无需通过"DLLName@FuncName"格式或RefDLL使用。 *使用时必须将DLL放在软件安装目录下的FmlDll子目录下 *字符串使用单引号,双引号是另一种格式的引用,不能混用 *DLL 需要在 .def 文件中 EXPORTS 项添加要调用的函数,否则有可能找不到函数 *DLL名称和函数名都是大小写敏感的,代码声明和公式调用时需要匹配。 =DLL公式参数传递例子= *无参数时的例子: // 公式里面的声明与调用 extern 'FoxFunc.dll' void test1(); test1(); // c++ .h 函数声明 __declspec(dllexport) void __stdcall test1(); // c++ .cpp 函数实现 extern "C" __declspec(dllexport) void __stdcall test1() { } *传入单值的公式例子: // 公式里面的声明与调用 extern 'FoxFunc.dll' void test2(int, float, bool, char); Variables: NumericSimple var1, NumericSeries var2, NumericArray var3[10]; var1 := 1; var2[0] := 2; var3[0] := 65; test2(1, 2, 1, 65); test2(var1, var2[0], var1, var3[0]); // c++ .h 函数声明 __declspec(dllexport) void __stdcall test2(int i, float f, bool b, char c); // c++ .cpp 函数实现 extern "C" __declspec(dllexport) void __stdcall test2(int i, float f, bool b, char c) { } *传入字符串的公式例子 公式里面的字符串变量是宽字符,编码是GB2312,DLL里面可以使用MultiByteToWideChar/MultiByteToWideChar进行字符转换 // 公式里面的声明与调用 extern 'FoxFunc.dll' void test3(LPCWSTR); Variables: String var1; var1 := 'test string1'; test3(NumToStr(close,3)); test3('aaa'); test3(var1); // c++ .h 函数声明 __declspec(dllexport) void __stdcall test3(const wchar_t* p); // c++ .cpp 函数实现 #include <string> // 窄字符转宽字符 static std::wstring a2w(LPCSTR lpa) { size_t l = MultiByteToWideChar(936, 0, lpa, -1, NULL, 0); std::wstring s; s.resize(l - 1); MultiByteToWideChar(936, 0, lpa, (int)strlen(lpa), (LPWSTR)s.c_str(), (int)s.size()); return s; } // 宽字符转窄字符 static std::string w2a(LPCWSTR lpw) { size_t l = WideCharToMultiByte(936, 0, lpw, -1, NULL, 0, NULL, NULL); std::string s; s.resize(l - 1); WideCharToMultiByte(936, 0, lpw, (int)wcslen(lpw), (LPSTR)s.c_str(), (int)s.size(), NULL, NULL); return s; } extern "C" __declspec(dllexport) void __stdcall test3(const wchar_t *p) { std::wstring sw = p; std::string sa = w2a(sw.c_str()); } *传入序列的公式例子 // 公式声明与调用 extern 'FoxFunc.dll' void test4(NumericSeries, int, NumericArray, int); Variables: NumericSeries var1, NumericArray var2[5]; var1 := close; var2[1] := 1; var2[2] := 2; var2[3] := 3; var2[4] := 4; var2[5] := 5; //var2 数组实际大小是5+1 test4(var1, BarsCount(close), var2, 6); // c++ .h 声明 __declspec(dllexport) void __stdcall test4(float *pf1, int n1, float *pf2, int n2); // c++ .cpp 函数实现 extern "C" __declspec(dllexport) void __stdcall test4(float *pf1, int n1, float *pf2, int n2) { } *传入引用的公式例子 =DLL的返回值= 新格式DLL可返回单值,序列和数组。单值类型大致分为两种:数值类型和字符串类型,可以通过函数返回值直接返回。 *返回单值类型的c语言例子 //返回整数 extern "C" __declspec(dllexport) int WINAPI my_test1() { return 1; } //返回浮点 extern "C" __declspec(dllexport) float WINAPI my_test2() { return 2.0f; } //返回字符串 extern "C" __declspec(dllexport) LPCWSTR WINAPI my_test3() { return L"TEST STRING"; } 相应的公式调用例子 #MAINCHART #Run_By_Bar extern 'MyDll2.dll' int my_test1(); extern 'MyDll2.dll' float my_test2(); extern 'MyDll2.dll' LPCWSTR my_test3(); k1: my_test1; k2: my_test2; comment(my_test3); 若要返回序列或数组,则把需要返回的序列赋值目标当作参数传递给DLL,在DLL内部直接修改已达到赋值。 注意逐根运行模式下,每一根K线都会调用dll,所以通常每次调用只需要赋值比上一根K线新增加的类型, 例如计算收盘价均值时,每次在BarPos位置填入当根K线的均值即可。由此可见,这种应用下通常需要把 BarPos(当前是第几根K线)作为参数传入Dll中。 *返回序列和数组的例子 extern "C" __declspec(dllexport) void WINAPI my_test4(float*pReturn, int nIndex) { pReturn[nIndex-1] = 123; } extern "C" __declspec(dllexport) void WINAPI my_test5(float*pReturn, int nLen) { for(int i=0;i<nLen;i++) pReturn[i] = 0; } 相应的公式调用例子 #MAINCHART #Run_By_Bar variable: NumericSeries mySequence(0); array: myArray[100](1); extern 'MyDll2.dll' void my_test4(NumericSeries mySequence, int nIndex); extern 'MyDll2.dll' void my_test5(NumericArray myArray, int nLen); my_test4(mySequence, BarPos); my_test5(myArray, 100); =DLL的参数类型= {| class="wikitable" |- ! - !! 单值 !! 序列 !! 数组 !! 引用 |- | 数值 || NumericSimple || NumericSeries || NumericArray || NumericRef |- | 字符串 || String || - || StringArray || StringRef |} <br> 其中,公式中NumericSimpe,在DLL中对应float(64位版本对应double)<br> 公式中NumericSeries,NumericArray,NumericRef,在DLL中都对应float* (64位版本对应double*),具体的区别只是数据长度的不同。NumericSeries是随K线增长自动增长的,NumericArray是定长数组,而NumericRef是单值。 =无效数据表示= 公式系统使用std的无效浮点数表示无效值,浮点无效值的一个重要特征是 f != f 为真,可作为判断依据, 其它运算皆输出无效值,其它比较皆输出假。当序列作为指标输出时,开始和结束两段的无效值自动截除,不作为指标输出。 例如要输出5日均线,序列的前4个值可填充无效值(填充0时会使指标线变形) #include <limits> #define INVALID_NUMERIC std::numeric_limits<float>::quiet_NaN() 无效值在公式里可以用 Invalid 关键字指定,例如 k1:Invalid; 则k1指标线不会输出 =编写调用公式= =开发DLL的详细例子= =实例下载= [[Category:公式系统]] =调用Windows系统DLL= 调用win32提供的系统DLL,与调用自己编写的DLL是一样的。 只要知道windows系统函数所属的DLL和函数名,参数等信息就可以直接使用,例如 extern 'kernel32.dll' int GetTickCount(); tickcount:GetTickCount(); =调用.Net DLL= 跟一般DLL不同的是,.net DLL在声明时,除了函数名信息,还要提供命名空间、类名的信息,例如: extern 'RzRq.dll' void RzRq.Grabber.GetFinance( LPCWSTR stockCode); 这里的RzRq就是命名空间,而Grabber则是类的名称,GetFinance是函数名 另外,在.net DLL中,除了可以用参数来传递数据,还可以使用GetVarData, SetVarData这两个函数在.net和公式引擎间交换数据。 .net DLL开发过程如下:<br> 1. visual studio 新建一个类库 工程,用C#或者VB.net,Managed C++都可以,这里以C#为例<br> [[image:dotnet1.png]]<br> <br> 2.添加 金魔方 .net api dll 引用,位置位于金魔方安装目录下 DotNetBridge.dll<br> [[文件:dotnet2.png]]<br> [[文件:dotnet3.png]]<br> <br> 3.新建或者修改 从 Formula 继承 一个类,Formula 是金魔方.net api的类,从此类继承可以访问 GetVarData等接口函数,需要用 fox.api 命名空间<br> [[文件:dotnet4.png]]<br>
返回到
自由DLL接口规范
。
个人工具
内存:18924KB
3.144.15.34
该IP地址的讨论
登录
名字空间
页面
讨论
变换
查看
阅读
查看源代码
查看历史
操作
搜索
导航
首页
社区专页
新闻动态
最近更改
随机页面
金魔方论坛
下载金魔方
帮助
工具箱
链入页面
链出更改
特殊页面