欢迎您光临博庭社区!

 找回密码
 立即注册
查看: 29437|回复: 99

金魔方DLL接口   [复制链接]

Rank: 8Rank: 8

发表于 2012-9-21 14:36:53 |显示全部楼层
本帖最后由 ptLibert 于 2012-10-23 11:06 编辑

新的金魔方DLL接口不但兼容老飞狐DLL格式,而且新增了对普通任意DLL的支持。只要在公式中描述清楚函数的定义,就能在金魔方中使用它们。
例如,您在DLL实现了一个函数my_ma,c中定义如下
  1. extern "C" __declspec(dllexport) void WINAPI my_ma(double* resultArray, double* array, int n, int barpos)
  2. {
  3.         int nK = barpos - 1;
  4.         if(barpos >= n)
  5.         {
  6.                 double sum=0;
  7.                 for(int i = 0; i < n; i++)
  8.                         sum += array[nK-i];
  9.                 resultArray[nK] = sum / n;
  10.         }
  11.         else
  12.         {
  13.                 resultArray[nK] = INVALID_NUMERIC;
  14.         }

  15. }
复制代码


解释一下各参数:resultArray是一个浮点数组,array是将要被计算的序列,n是周期,barpos是当期K线序号


那么在公式中,只需要作此声明:
  1. #RunMode Run_By_Bar
  2. extern 'FoxFunc.dll'  void  my_ma(NumericSeries resultArray, NumericSeries array, int n, int barpos);
复制代码


就可以在接下来的语句中使用my_ma这个函数了。
  1. ma1:0;
  2. my_ma(ma1, close, 5, BARPOS);
复制代码

必须说明的是:老的一套DLL调用方式只能工作在逐行模式,而新的一套用法只能工作在逐根模式下所
用到新模式的时候,必须声明#RunMode Run_by_bar
或者
#trade


10月23日新增数组传递支持http://www.hs633.com/forum.php?mod=viewthread&tid=395&pid=3949&page=4&extra=#pid3949


使用道具 举报

Rank: 8Rank: 8

发表于 2012-9-21 14:42:06 |显示全部楼层
本帖最后由 ptLibert 于 2012-9-21 14:59 编辑

除了可以处理序列,DLL还能传入传出单值。
在DLL中写一段这样的代码:
  1. extern "C"  __declspec(dllexport) void WINAPI TestNumbericRef(double* x, double* y, double* z)
  2. {
  3.         *x = 6;
  4.         *y = 7;
  5.         *z = 8;
  6. }
复制代码
然后在公式中声明:
  1. extern 'FoxFunc.dll'  void   TestNumbericRef(NumericRef x, NumericRef y, NumericRef z);
复制代码
然后在接下来的语句中使用:
  1. x:=0;
  2. y:=0;
  3. z:=0;
  4. TestNumbericRef(x, y, z);
  5. COMMENT(x);
  6. COMMENT(y);
  7. COMMENT(z);
复制代码
将会看到屏幕打印的是6,7,和8

使用道具 举报

Rank: 8Rank: 8

发表于 2012-9-21 14:48:49 |显示全部楼层
除了自己写的DLL,只要你知道DLL中包含了什么函数并且知道它的格式,并且是金魔方所支持的数据类型,那也可以在金魔方中调用

举例,GetTickCount()是windowsApi中常用的函数,用来返回windows启动以来所经过的微秒数,那在金魔方公式里是可以直接使用的
  1. extern 'kernel32.dll' int GetTickCount();
  2. tickcount:GetTickCount(),ownerscale;
复制代码
随着公式的每一次调用,将看到tickcount在变化

使用道具 举报

Rank: 8Rank: 8

发表于 2012-9-21 15:08:19 |显示全部楼层
除了通过引用参数或序列返回计算结果,也可以通过函数的return返回结果

例如,写一个这样的DLL函数:
  1. extern "C" __declspec(dllexport) double WINAPI ALL_TYPE_ADD(char d1,  int d2, LONG d3, DWORD d4, float d5, double d6, BOOL d7, ULONG d8)
  2. {
  3.         double sum = d1 +  d2 +   d3 +   d4 +   d5 +   d6 +   d7 +   d8;
  4.         return sum;
  5. }
复制代码
并在公式中使用它
  1. alladd:ALL_TYPE_ADD(1,1,1,1,1,1,1,1);
复制代码


使用道具 举报

Rank: 8Rank: 8

发表于 2012-9-21 15:14:13 |显示全部楼层
本帖最后由 ptLibert 于 2012-9-21 15:23 编辑

传入传出字符串也毫无压力

// 传入字符串
  1. // 传入字符串
  2. static buf[255];
  3. extern "C"  __declspec(dllexport) void WINAPI SetString(LPCWSTR str1, LPCWSTR str2)
  4. {
  5.         strcpy_s( buf, 255, str1 );
  6.        strcat_s( buf ,255, str2);
  7. }

  8. // 传回字符串
  9. extern "C"  __declspec(dllexport) LPCWSTR WINAPI MyString()
  10. {
  11.         return buf;
  12. }
复制代码



公式:
  1. extern 'FoxFunc.dll'  void  SetString(LPCWSTR str1, LPCWSTR str2);
  2. extern 'FoxFunc.dll'   LPCWSTR  MyString();

  3. SetString('msg', 'hello');
  4. COMMENT(MyString());
复制代码


使用道具 举报

Rank: 8Rank: 8

发表于 2012-9-21 15:34:07 |显示全部楼层
本帖最后由 ptLibert 于 2012-10-23 17:12 编辑

其中,foxfunc.rar是DLL的c源码
dllcall.rar中是使用DLL的范例公式代码




附件: 你需要登录才可以下载或查看附件。没有帐号?立即注册

使用道具 举报

Rank: 8Rank: 8

发表于 2012-9-21 17:54:10 |显示全部楼层
.net DLL也能支持
  1. // 公式这样写
  2. extern 'testManaged.dll'  
  3. void  testManaged.TestClass1.my_ma(NumericSeries resultArray, NumericSeries array, int n, int barpos);
  4. my_ma(ma1, close, 5, barpos);


  5. dll 里的一个类这样写

  6. namespace testManaged
  7. {
  8.     public class TestClass1
  9.     {

  10.         public void my_ma(ref double[] resultArray,  double[] array, int n, int barpos)
  11.         {
  12.                 int nK = barpos - 1;
  13.                 if (barpos >= n)
  14.                 {
  15.                     double sum = 0;
  16.                     for (int i = 0; i < n; i++)
  17.                         sum += array[nK - i];
  18.                     resultArray[nK] = sum / n;
  19.                 }
  20.                 else
  21.                 {
  22.                     resultArray[nK] = double.NaN;
  23.                 }


  24.         }

  25.     }
  26. }
复制代码

使用道具 举报

Rank: 4

发表于 2012-9-21 20:51:07 |显示全部楼层
有一个疑问,金语言中,序列下标0代表最近的一根K线所对应的序列数据,那barpos不是一直等于0?

使用道具 举报

Rank: 8Rank: 8

发表于 2012-9-21 21:18:45 |显示全部楼层
udbsss 发表于 2012-9-21 20:51
有一个疑问,金语言中,序列下标0代表最近的一根K线所对应的序列数据,那barpos不是一直等于0? ...

跟在公式里不同,序列传入DLL中之后,下标0是代表最古老的元素。。

在公式里,下标是解释引擎作了转换的,序列的物理存放方式,其实还是古老的元素放在数组的第一个位置,最近的元素存在最后。

所以送进DLL之后,要改变访问方式,0访问早的。

使用道具 举报

Rank: 4

发表于 2012-9-21 21:45:24 |显示全部楼层
ptLibert 发表于 2012-9-21 21:18
跟在公式里不同,序列传入DLL中之后,下标0是代表最古老的元素。。

在公式里,下标是解释引擎作了转换的 ...

意思是序列传入DLL时反序了,然后从DLL传回时又再反序了?

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

bottom

Archiver|http://www.patiosoft.com

GMT+8, 2017-12-16 04:09 , Processed in 0.045462 second(s), 10 queries .

花生网 Copyrigh©2012

和讯信息科技有限公司 ALL Rights Reserved 版权所有 复制必究

回顶部