“分析家C语言接口编译dll文件”
- 格式:doc
- 大小:42.50 KB
- 文档页数:7
“分析家C语言接口编译dll文件”[第一讲]准备的东东1.安装VC++ 6.0软件2.下载分析家C语言接口文件。
3.具备C++编程的知识。
如果不会,自己下载教学软件,或找本相关的书籍。
4.会分析家基本公式编写。
如果不会,在本站下载相关分析家公式编写资料。
准备好后,我开始讲一个完整公式的编写过程。
[第二讲]练习编译dll文件。
1.解包分析家c语言接口2.启动Vc++点击菜单[File]选Open Workspace。
选择文件FxjFunc.dsw3.选择菜单[Build],选择Build FxjFunc.dll生成FxjFunc.dll文件。
如果没有错误,显示下面结果。
--------------------Configuration: FxjFunc - Win32 Debug-------------------- FxjFunc.dll - 0 error(s), 0 warning(s)4.生成的FxjFunc.dll文件在D:\SUPERSTK目录中。
如果不在当前使用的分析家目录,可以将FxjFunc.dll文件复制到分析家目录中,也可以复制到飞狐\FoxTrader\FmlDLL目录中。
5.在飞狐或分析家建立公式,看看结果。
公式只有下面一句,10日close均线。
ma1:"fxjfunc@mymaclose"(10); 如果结果正确,你已经成功编写了dll公式了。
在后面的讲课中介绍编写技巧。
第三讲]分析家扩展函数规范及设计分析家扩展函数规范如下:///////////////////////////////////////////////////////////////////////////#ifndef __FXJFUNC_H_INCLUDE#define __FXJFUNC_H_INCLUDE/*///////////////////////////////////////////////////////////////////////////分析家扩展函数规范V3.101.本规范适用于分析家3.10标准版和专业版公式系统.2.扩展函数用于实现系统函数不能实现的特殊算法.3.扩展函数用windows 32位动态连接库实现,建议使用Microsoft Visual C++编程.4.调用时在公式编辑器中写"动态库名称@函数名称"(参数表)即可,例如下面函数可以写为"FXJFUNC@MYCMALOSE"(5)5.动态连接库名称和函数名称可以自己定义.6.使用时可以将动态库拷贝到分析家目录下使用.*/#ifdef __cplusplusextern "C"{#endif //__cplusplus/////////////////////////////////////////////////////////////////////////// //分析周期enum DATA_TYPE{TICK_DATA=2, //分笔成交MIN1_DATA, //1分钟线MIN5_DATA, //5分钟线MIN15_DATA, //15分钟线MIN30_DATA, //30分钟线MIN60_DATA, //60分钟线DAY_DATA, //日线WEEK_DATA, //周线MONTH_DATA, //月线MULTI_DATA //多日线};/////////////////////////////////////////////////////////////////////////// //基本数据typedef struct tagSTKDATA{time_t m_time; //时间,UCTfloat m_fOpen; //开盘float m_fHigh; //最高float m_fLow; //最低float m_fClose; //收盘float m_fVolume; //成交量float m_fAmount; //成交额WORD m_wAdvance; //上涨家数(仅大盘有效)WORD m_wDecline; //下跌家数(仅大盘有效)} STKDATA;//////////////////////////////////////////////////////////////////////////// //扩展数据,用于描述分笔成交数据的买卖盘typedef union tagSTKDATAEx{struct{float m_fBuyPrice[3]; //买1--买3价float m_fBuyVol[3]; //买1--买3量float m_fSellPrice[3]; //卖1--卖3价float m_fSellVol[3]; //卖1--卖3量};float m_fDataEx[12]; //保留} STKDATAEx;///////////////////////////////////////////////////////////////////////////// /*财务数据顺序(m_pfFinData内容)序号内容0 总股本(万股),1 国家股,2 发起人法人股,3 法人股,4 B股,5 H股,6 流通A股,7 职工股,8 A2转配股,9 总资产(千元),10 流动资产,11 固定资产,12 无形资产,13 长期投资,14 流动负债,15 长期负债,16 资本公积金,17 每股公积金,18 股东权益,19 主营收入,20 主营利润,21 其他利润,22 营业利润,23 投资收益,24 补贴收入,25 营业外收支,26 上年损益调整,27 利润总额,28 税后利润,29 净利润,30 未分配利润,31 每股未分配,32 每股收益,33 每股净资产,34 调整每股净资,35 股东权益比,36 净资收益率*////////////////////////////////////////////////////////////////////////////////函数数据结构typedef struct tagCALCINFO{const DWORD m_dwSize; //结构大小const DWORD m_dwVersion; //调用软件版本(V2.10 : 0x210)const DWORD m_dwSerial; //调用软件序列号const char* m_strStkLabel; //股票代码const BOOL m_bIndex; //大盘const int m_nNumData; //数据数量(pData,pDataEx,pResultBuf数据数量)const STKDATA* m_pData; //常规数据,注意:当m_nNumData==0时可能为NULL const STKDATAEx* m_pDataEx; //扩展数据,分笔成交买卖盘,注意:可能为NULLconst int m_nParam1Start; //参数1有效位置const float* m_pfParam1; //调用参数1const float* m_pfParam2; //调用参数2const float* m_pfParam3; //调用参数3const float* m_pfParam4; //调用参数3float* m_pResultBuf; //结果缓冲区const DATA_TYPE m_dataType; //数据类型const float* m_pfFinData; //财务数据} CALCINFO;/*注:1.函数调用参数由m_pfParam1--m_pfParam4带入,若为NULL则表示该参数无效.2.当一个参数无效时,则其后的所有参数均无效.如:m_pfParam2为NULL,则m_pfParam3,m_pfParam4一定为NULL.3.参数1可以是常数参数或序列数参数,其余参数只能为常数参数.4.若m_nParam1Start<0, 则参数1为常数参数,参数等于*m_pfParam1;5.若m_nParam1Start>=0,则参数1为序列数参数,m_pfParam1指向一个浮点型数组, 数组大小为m_nNumData,数据有效范围为m_nParam1Start--m_nNumData.在时间上m_pData[x] 与m_pfParam1[x]是一致的*/////////////////////////////////////////////////////////////////////////////////////* 函数输出__declspec(dllexport) int xxxxxxxx(CALCINFO* pData); ---------- A__declspec(dllexport) int xxxxxxxxVAR(CALCINDO* pData); ---------- B1.函数名称需全部大写.2.函数必须以上述A,B两种形式之一声明,请用实际函数名称替代xxxxxxxx;对于C++程序还需包括在extern "C" { } 括号中.3.上述形式A用于声明不带参数或全部参数为常数的函数;形式B用于声明参数1为序列数的函数;两种函数的区别在于后者以VAR结尾.4.函数计算结果用pData->m_pResultBuf带回.5.函数返回-1表示错误或全部数据无效,否则返回第一个有效值位置,即:m_pResultBuf[返回值] -- m_pResultBuf[m_nNumData-1]间为有效值.6.函数名称长度不能超过15字节,动态连接库文件名不能超过9字节(不包括扩展名),动态库名称不能叫SYSTEM,EXPLORER7.编译时请请选择1字节对齐*///示例函数,使用时用实际名称替换__declspec(dllexport) int WINAPI MYMACLOSE(CALCINFO* pData);__declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData);__declspec(dllexport) int WINAPI MYMACLOSE_CALC_PREV(CALCINFO* pData); __declspec(dllexport) int WINAPI MYMAVAR_CALC_PREV(CALCINFO* pData);#ifdef __cplusplus}#endif //__cplusplus#endif //__FXJFUNC_H_INCLUDE////////////////////////////////////////////////////////////////////////分析家的数据结构见上面。
C语⾔编译成dll
⾸先c语⾔在开始要加上
#ifdef __cplusplus
extern "C" {
#endif
…被导出的⽅法名称
#ifdef __cplusplus
}
#endif
不然系统会将起当做c++,转成的dll中的⽅法名称会被转义。
在实现的⽅法名称前⾯加上__declspec(dllexport)
1. Gcc:gcc –shared -o xxxx.dll xxxx.c 可以直接将.c⽂件转成dll⽂件。
在实际引⽤中,我是将所有的#include都是放在.c⽂件中的,上述的注意代码也是放在.c中的,他的头⽂件是直接抛弃掉了。
2. Vc创建⼀个c++的项⽬,⽂件-新建-新建项⽬-其他语⾔-Visual C++ - Win32 控制台应⽤程序;勾选DLL和导出符号,.c需要修改
成.cpp,右键-属性-预编译头-不使⽤预编译头,右击项⽬“重新⽣成”。
1实地使⽤过确认可以使⽤,2未尝试过但是在使⽤c++转出dll是没有问题的
在导出过程中我们可以使⽤vs⾃带⼀个⼯具来查询⽣成的dll中有那些⽅法,例如:
Vs安装路径下:C:\vs 2012\VC\bin\dumpbin.exe,可能会报⼀个缺少“mspdb110.dll”⽂件的错误,直接将安装路径下:C:\vs
2012\Common7\IDE下⾯的该⽂件复制粘贴到C:\vs 2012\VC\bin\下⾯。
⽤法是,先cd到dumpbin的路径下,dumpbin –exports xxxx.dll。
C#中修改Dll⽂件(反编译后重新编译)Dll⽂件⽣成后,如没有源代码,⼜要修改其中内容
可以⽤微软⾃带的ildasm和ilasm程序
先⽤ildasm将dll⽂件反编译成il⽂件
ildasm Test.dll /out=Test.il
会⽣成Test.res和Test.il两个⽂件
il⽂件可以⽤⽂本编辑器修改,要注意其中的语法
改完后再⽤ilasm将il⽂件重新编译成dll⽂件
ilasm /dll /res:Test.res Test.il /out:Test.dll
本⼈测试时因为ildasm和ilasm程序都是从⽹上下载来的,因为版本不⼀样,总是不成功,⾛了不少弯路
⽤这样⽅式修改唯⼀不⽅便的是il⽂件语法不好理解,⼀版修改少量的可以⽤,⼤量修改也不合适。
⽤Reflector将dll⽂件反编译成cs⽂件,也可以修改,这样好改,可是不好编译回去,有时会报错
所以选则⽤Reflector还是⽤ildasm和ilasm,更据需求各⾃选择。
反编译C#的dll⽂件并修改,再重新⽣成dll
1、把dll⽂件导⼊到ildasm⼯具中,ildasm是由微软提供的.net程序反编译⼯具,位于“C:\Program Files (x86)\Microsoft
SDKs\Windows\v7.0A\Bin”
2、在ildasm中File->dump,把dll⽂件转储为*.il⽂件存到某个指定⽂件夹⾥,得到*.il和*.res两个⽂件,有时也会有*.resource⽂件
3、⽤记事本打开得到的*.il⽂件,找到对应的⽅法,进⾏修改(如果修改的代码太多,那则需要先学习⼀下“C#反编译之IL语法”),具体情况具体分析,修改之后保存。
4、打开DOS命令,进⼊到 c:\Windows\\Framework\v2.0.50727> ⽂件夹,然后输⼊命令:ilasm /dll/resource=a.res a.il(注意a.res和a.il两⽂件夹位置不可变),回车,就在对应⽬录下⽣成新的dll⽂件,如果不放⼼,可以⽤Refletor反编译⼯具重新反编译新的dll⽂件,检查代码。
c语言dll写法
在C语言中,编写DLL(动态链接库)的基本步骤如下:
1. 定义导出函数或变量:使用__declspec(dllexport)关键字将需要导出的函数或变量声明为导出符号。
例如:
```c
__declspec(dllexport) void MyFunction()
{
// 函数实现
}
```
2. 编译源代码:使用C编译器将源代码编译为目标文件。
例如,使用GCC 编译器可以使用以下命令:
```shell
gcc -c -DBUILD_DLL
```
这将生成一个名为的目标文件。
3. 创建DLL项目:使用链接器将目标文件链接为DLL。
例如,使用GCC编译器可以使用以下命令:
```shell
gcc -shared -o
```
这将生成一个名为的DLL文件。
4. 使用DLL:在其他C语言程序中,使用__declspec(dllimport)关键字导
入DLL中的导出符号。
例如:
```c
__declspec(dllimport) void MyFunction();
```
然后在程序中使用该函数或变量即可。
注意,在使用DLL时需要确保DLL
文件与应用程序位于同一目录中,或者在系统路径中添加DLL文件的路径。
以上是编写C语言DLL的基本步骤。
需要注意的是,具体的实现方式可能
会因编译器和操作系统而有所不同。
一、编写Dll文档1.新建一DLL项目dll2.#include"stdafx.h"#include"windows.h"#include"dll.h"#pragma comment(lib,"dll.lib")int _tmain(int argc, _TCHAR* argv[]){HelloWorld();return 0;}3.// dllmain.cpp : 定¡§义°? DLL 应®|用®?程¨¬序¨°的Ì?入¨?口¨²点Ì?。
¡ê#include"stdafx.h"#include"dll.h"#include<windows.h>#include<stdio.h>#include<stdlib.h>void HelloWorld (){MessageBox (0, L"Hello World from DLL!\n", L"Hi", MB_ICONINFORMATION);}BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,DWORD reason /* Reason this function is beingcalled. */ ,LPVOID reserved /* Not used. */ ){switch (reason){case DLL_PROCESS_ATTACH:break;case DLL_PROCESS_DETACH:break;case DLL_THREAD_ATTACH:break;case DLL_THREAD_DETACH:break;}/* Returns TRUE on success, FALSE on failure */return TRUE;}4.生成菜单下的重新生成解决方案,即得到dll和lib文件,如图:至此DLL文件建立完成。
使用gcc编译出dll文件的方法我们通过实例来学习使用gcc编译出dll文件的方法,看下面的例子说明这个过程,共有三个文件:hello.c、dll.h和dll.c。
hello.c 文件内容如下#include <stdio.h>#include "dll.h"int main(){hello();return 0;}其中,hello()函数是动态连接库提供的函数。
dll.h 文件内容如下#ifdef BUILD_DLL#define EXPORT __declspec(dllexport)#else#define EXPORT __declspec(dllimport)#endifEXPORT void hello(void);dll.c 文件内容如下#include "dll.h"EXPORT void hello(void){printf ("Hello\n");}三个文件的内容都很简单,无须解释。
编译连接程序1、编译hello.cgcc -c hello.c2、编译dll.cgcc -c -DBUILD_DLL dll.c注意要使用要使用-DBUILD_DLL来设置宏BUILD_DLL3、创建dllgcc -shared -o message.dll dll.o -Wl,--out-implib,libmessage.a这一步要详细说明一下-shared参数用来创建共享库,在windows中为dll-Wl 等待下一条信息进行连接--out-implib是给连接程序ld使用的,用于创建要连接dll需要的import library 4、创建可执行文件gcc -o hello.exe hello.o -L./ -lmessage-L 指定连接库路径-lmessage (or -l message) 指定dll的import library好了,编译连接完成,运行程序C:\>helloHello!。
c++中.dll与.lib文件的生成与使用的详解--------------------------------------------------------------------------------两种库:·包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library。
·包含函数代码本身,在编译时直接将代码加入程序当中,称为静态链接库static link library。
共有两种链接方式:·动态链接使用动态链接库,允许可执行模块(.dll文件或.exe 文件)仅包含在运行时定位DLL函数的可执行代码所需的信息。
·静态链接使用静态链接库,链接器从静态链接库LIB获取所有被引用函数,并将库同代码一起放到可执行文件中。
--------------------------------------------------------------------------------两种文件的区别--------------------------------------------------------------------------------使用lib需注意两个文件:·.h头文件,包含lib中说明输出的类或符号原型或数据结构。
应用程序调用lib时,需要将该文件包含入应用程序的源文件中。
·.LIB文件。
使用dll需注意三个文件:·.h头文件,包含dll中说明输出的类或符号原型或数据结构的.h文件。
应用程序调用dll时,需要将该文件包含入应用程序的源文件中。
·.LIB文件,是dll在编译、链接成功之后生成的文件,作用是当其他应用程序调用dll时,需要将该文件引入应用程序,否则产生错误(如果不想用lib文件或者没有lib文件,可以用WIN32 API函数LoadLibrary、GetProcAddress装载)。
“分析家C语言接口编译dll文件”[第一讲]准备的东东1.安装VC++ 6.0软件2.下载分析家C语言接口文件。
3.具备C++编程的知识。
如果不会,自己下载教学软件,或找本相关的书籍。
4.会分析家基本公式编写。
如果不会,在本站下载相关分析家公式编写资料。
准备好后,我开始讲一个完整公式的编写过程。
[第二讲]练习编译dll文件。
1.解包分析家c语言接口2.启动Vc++点击菜单[File]选Open Workspace。
选择文件FxjFunc.dsw3.选择菜单[Build],选择Build FxjFunc.dll生成FxjFunc.dll文件。
如果没有错误,显示下面结果。
--------------------Configuration: FxjFunc - Win32 Debug-------------------- FxjFunc.dll - 0 error(s), 0 warning(s)4.生成的FxjFunc.dll文件在D:\SUPERSTK目录中。
如果不在当前使用的分析家目录,可以将FxjFunc.dll文件复制到分析家目录中,也可以复制到飞狐\FoxTrader\FmlDLL目录中。
5.在飞狐或分析家建立公式,看看结果。
公式只有下面一句,10日close均线。
ma1:"fxjfunc@mymaclose"(10); 如果结果正确,你已经成功编写了dll公式了。
在后面的讲课中介绍编写技巧。
第三讲]分析家扩展函数规范及设计分析家扩展函数规范如下:///////////////////////////////////////////////////////////////////////////#ifndef __FXJFUNC_H_INCLUDE#define __FXJFUNC_H_INCLUDE/*///////////////////////////////////////////////////////////////////////////分析家扩展函数规范V3.101.本规范适用于分析家3.10标准版和专业版公式系统.2.扩展函数用于实现系统函数不能实现的特殊算法.3.扩展函数用windows 32位动态连接库实现,建议使用Microsoft Visual C++编程.4.调用时在公式编辑器中写"动态库名称@函数名称"(参数表)即可,例如下面函数可以写为"FXJFUNC@MYCMALOSE"(5)5.动态连接库名称和函数名称可以自己定义.6.使用时可以将动态库拷贝到分析家目录下使用.*/#ifdef __cplusplusextern "C"{#endif //__cplusplus/////////////////////////////////////////////////////////////////////////// //分析周期enum DATA_TYPE{TICK_DATA=2, //分笔成交MIN1_DATA, //1分钟线MIN5_DATA, //5分钟线MIN15_DATA, //15分钟线MIN30_DATA, //30分钟线MIN60_DATA, //60分钟线DAY_DATA, //日线WEEK_DATA, //周线MONTH_DATA, //月线MULTI_DATA //多日线};/////////////////////////////////////////////////////////////////////////// //基本数据typedef struct tagSTKDATA{tim e_t m_time; //时间,UCTfloat m_fOpen; //开盘float m_fHigh; //最高float m_fLow; //最低float m_fClose; //收盘float m_fVolume; //成交量float m_fAmount; //成交额WORD m_wAdvance; //上涨家数(仅大盘有效)WORD m_wDecline; //下跌家数(仅大盘有效)} STKDATA;//////////////////////////////////////////////////////////////////////////// //扩展数据,用于描述分笔成交数据的买卖盘typedef union tagSTKDATAEx{struct{float m_fBuyPrice[3]; //买1--买3价float m_fBuyVol[3]; //买1--买3量float m_fSellPrice[3]; //卖1--卖3价float m_fSellVol[3]; //卖1--卖3量};float m_fDataEx[12]; //保留} STKDATAEx;///////////////////////////////////////////////////////////////////////////// /*财务数据顺序(m_pfFinData内容)序号内容0 总股本(万股),1 国家股,2 发起人法人股,3 法人股,4 B股,5 H股,6 流通A股,7 职工股,8 A2转配股,9 总资产(千元),10 流动资产,11 固定资产,12 无形资产,13 长期投资,14 流动负债,15 长期负债,16 资本公积金,17 每股公积金,18 股东权益,19 主营收入,20 主营利润,21 其他利润,22 营业利润,23 投资收益,24 补贴收入,25 营业外收支,26 上年损益调整,27 利润总额,28 税后利润,29 净利润,30 未分配利润,31 每股未分配,32 每股收益,33 每股净资产,34 调整每股净资,35 股东权益比,36 净资收益率*////////////////////////////////////////////////////////////////////////////////函数数据结构typedef struct tagCALCINFO{const DWORD m_dwSize; //结构大小const DWORD m_dwVersion; //调用软件版本(V2.10 : 0x210)const DWORD m_dwSerial; //调用软件序列号const char* m_strStkLabel; //股票代码const BOOL m_bIndex; //大盘const int m_nNumData; //数据数量(pData,pDataEx,pResultBuf数据数量)const STKDATA* m_pData; //常规数据,注意:当m_nNumData==0时可能为NULL const STKDATAEx* m_pDataEx; //扩展数据,分笔成交买卖盘,注意:可能为NULLconst int m_nParam1Start; //参数1有效位置const float* m_pfParam1; //调用参数1const float* m_pfParam2; //调用参数2const float* m_pfParam3; //调用参数3const float* m_pfParam4; //调用参数3float* m_pResultBuf; //结果缓冲区const DATA_TYPE m_dataType; //数据类型const float* m_pfFinData; //财务数据} CALCINFO;/*注:1.函数调用参数由m_pfParam1--m_pfParam4带入,若为NULL则表示该参数无效.2.当一个参数无效时,则其后的所有参数均无效.如:m_pfParam2为NULL,则m_pfParam3,m_pfParam4一定为NULL.3.参数1可以是常数参数或序列数参数,其余参数只能为常数参数.4.若m_nParam1Start<0, 则参数1为常数参数,参数等于*m_pfParam1;5.若m_nParam1Start>=0,则参数1为序列数参数,m_pfParam1指向一个浮点型数组, 数组大小为m_nNumData,数据有效范围为m_nParam1Start--m_nNumData.在时间上m_pData[x] 与m_pfParam1[x]是一致的*/////////////////////////////////////////////////////////////////////////////////////* 函数输出__declspec(dllexport) int xxxxxxxx(CALCINFO* pData); ---------- A__declspec(dllexport) int xxxxxxxxVAR(CALCINDO* pData); ---------- B1.函数名称需全部大写.2.函数必须以上述A,B两种形式之一声明,请用实际函数名称替代xxxxxxxx;对于C++程序还需包括在extern "C" { } 括号中.3.上述形式A用于声明不带参数或全部参数为常数的函数;形式B用于声明参数1为序列数的函数;两种函数的区别在于后者以VAR结尾.4.函数计算结果用pData->m_pResultBuf带回.5.函数返回-1表示错误或全部数据无效,否则返回第一个有效值位置,即:m_pResultBuf[返回值] -- m_pResult Buf[m_nNumData-1]间为有效值.6.函数名称长度不能超过15字节,动态连接库文件名不能超过9字节(不包括扩展名),动态库名称不能叫SYSTEM,EXPLORER7.编译时请请选择1字节对齐*///示例函数,使用时用实际名称替换__declspec(dllexport) int WINAPI MYMACLOSE(CALCINFO* pData);__declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData);__declspec(dllexport) int WINAPI MYMACLOSE_CALC_PREV(CALCINFO* pData);__declspec(dllexport) int WINAPI MYMAVAR_CALC_PREV(CALCINFO* pData);#ifdef __cplusplus}#endif //__cplusplus#endif //__FXJFUNC_H_INCLUDE////////////////////////////////////////////////////////////////////////分析家的数据结构见上面。