欢迎使用金字塔普通技术服务论坛,您可以在相关区域发表技术支持贴。
我司技术服务人员将优先处理 VIP客服论坛 服务贴,普通区问题处理速度慢,请耐心等待。谢谢您对我们的支持与理解。


金字塔客服中心 - 专业程序化交易软件提供商金字塔软件高级功能研发区 → 请问金字塔软件怎样在DLL中全局类对象以供多个函数调用?

   

欢迎使用金字塔普通技术服务论坛,您可以在相关区域发表技术支持贴。
我司技术服务人员将优先处理 VIP客服论坛 服务贴,普通区问题处理速度慢,请耐心等待。谢谢您对我们的支持与理解。    


  共有3718人关注过本帖树形打印复制链接

主题:请问金字塔软件怎样在DLL中全局类对象以供多个函数调用?

帅哥哟,离线,有人找我吗?
canbao
  1楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:新手上路 帖子:16 积分:0 威望:0 精华:0 注册:2015/7/4 2:12:53
请问金字塔软件怎样在DLL中全局类对象以供多个函数调用?  发帖心情 Post By:2020/3/13 21:24:14 [只看该作者]

 
 下载信息  [文件大小:   下载次数: ]
图片点击可在新窗口打开查看点击浏览该文件:ctestdemo.zip


1.编译环境及版本信息

  1. 金字塔版本
    金字塔决策交易系统(x86)2020(v5.21)
  2. IDE
    Visual Studio Community 2019 版本 16.4.6
  3. 完整测试代码在附件中

2. 问题描述

  1. 在金字塔软件中,在公式里序列模式下调用DLL扩展函数时,使用了类,在调用该函数时在全局区定义了一个全局变量并置为空,然后在调用的函数处,通过new的方式创建一个对象,并把全局指针变量指向该对象;通过打印文件方式查看到当在金字塔软件里公式调用该DLL函数时,当改变品种或者周期时并没有调用析构函数,但是却新调用了构造函数创建了新的类对象,这里是金字塔通过DLL管理这一块堆上的内存还是用户自己要在DLL里自己进行管理,是否会存在内存泄露的问题?
  2. 在上诉函数之后,再调用其他函数,该全局指针并未指向上一个函数所产生的对象?要在其他函数里使用其中一个函数中创建的类对象,要进行怎样的定义才行?

3. 想要实现的目的

想要实现的目的:比如在 MYMACLOSE_TEST1 中创建了一个类,怎样才能在 MYMACLOSE_TEST2 函数中调用上面 MYMACLOSE_TEST1 中创建的对象,这样就可以调用返回对象的多个属性而不用多次创建,因为用 pData->m_pResultBuf[] 返回值时只能返回一组计算值,当想要返回其他组的计算值是要另外返回 pData->m_pResultBuf[] 才能再公式里获得!

4. 打印的记录信息

图片点击可在新窗口打开查看 图片点击可在新窗口打开查看


图片点击可在新窗口打开查看

图片点击可在新窗口打开查看

5. 测试代码

  1. 金字塔公式

    目的就是想用 MYMACLOSE_TEST2 调用 MYMACLOSE_TEST1 中创建的对象,这样就不用重复再计算了,因为如果对象中有多个属性需要返回时,好像只能通过多次函数调用返回!

  2. DLL中的代码:
    --  测试类的代码:
    以下内容为程序代码:

    1 #pragma once
    2 #include<vector>
    3 #include <iostream>
    4 #include<fstream>
    5 #include<time.h>
    6 #include "StockFunc.h"
    7
    8 #define MyClassTestDeBug
    9
    10 using namespace std;
    11
    12 //测试在DLL中运用类对象
    13 class MyClassTest
    14 {
    15 public:
    16     MyClassTest(CALCINFO* pData);
    17     ~MyClassTest();
    18     void MyCalMa(int _nPeriod);    //计算均线
    19     vector<float> c_MaData;        //结果值
    20
    21 private:
    22     CALCINFO* c_pData_test;
    23     
    24 };
    25
    26 MyClassTest::MyClassTest(CALCINFO* pData)
    27 {
    28     c_pData_test = pData;
    29 #ifdef MyClassTestDeBug
    30     ofstream outfile;
    31     //outfile.imbue(locale(locale(), "", LC_CTYPE)); // ①
    32     outfile.open("./Document/ctestdomedebug.txt", ios::app);    //"D:/Program Files (x86)/Weisoft Stock(x86)/Document/clcdebug.txt"
    33     if (outfile.is_open())
    34     {
    35         outfile.imbue(locale("", locale::all ^ locale::numeric));
    36         time_t time_seconds = time(NULL);    struct tm now_time;    localtime_s(&now_time, &time_seconds);
    37         char str[26]; strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", &now_time);
    38         outfile << __FUNCTION__ << " ; c_pData_test->m_nNumData: " << c_pData_test->m_nNumData << " ; c_MaData.size: " << c_MaData.size() << " ";
    39         outfile << " name: " << c_pData_test->m_strStkName << "; label:" << (string)c_pData_test->m_strStkLabel << " ; run_time: " << str << endl;
    40         outfile << "--------------------------------------------------------------" << endl;
    41     }
    42     outfile.close();
    43 #endif // MyClassTestDeBug        输出类属性StockFunc.h中的结构、均线计算的结果值
    44
    45 }
    46
    47 MyClassTest::~MyClassTest()
    48 {
    49 #ifdef MyClassTestDeBug
    50     ofstream outfile;
    51     outfile.open("./Document/ctestdomedebug.txt", ios::app);    //"D:/Program Files (x86)/Weisoft Stock(x86)/Document/clcdebug.txt"
    52     if (outfile.is_open())
    53     {
    54         time_t time_seconds = time(NULL);    struct tm now_time;    localtime_s(&now_time, &time_seconds);
    55         char str[26]; strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", &now_time);
    56         outfile << __FUNCTION__ << " ; c_MaData.size: " << c_MaData.size() << " " << str << endl;
    57         outfile << "--------------------------------------------------------------" << endl;
    58     }
    59     outfile.close();
    60 #endif // MyClassTestDeBug
    61 }
    62
    63 inline void MyClassTest::MyCalMa(int _nPeriod)
    64 {
    65     if (_nPeriod > 0)
    66     {
    67         float fTotal;
    68         float fCal;
    69         int i(0), j(0);
    70         for (i = 0; i < c_pData_test->m_nNumData; i++)//计算_nPeriod周期的均线,数据从_nPeriod-1开始有效
    71         {
    72             fTotal = 0.0f;
    73             fCal = 0.0f;
    74             if (i >= _nPeriod - 1)
    75             {
    76                 for (j = 0; j < _nPeriod; j++)                //累加
    77                 {
    78                     fTotal += c_pData_test->m_pData[i - j].m_fClose;
    79                 }
    80             }
    81             fCal = fTotal / _nPeriod;    //平均
    82             c_MaData.push_back(fCal);
    83         }
    84         
    85     }
    86 #ifdef MyClassTestDeBug
    87     ofstream outfile;
    88     outfile.open("./Document/ctestdomedebug.txt", ios::app);    //"D:/Program Files (x86)/Weisoft Stock(x86)/Document/clcdebug.txt"
    89     if (outfile.is_open())
    90     {
    91         time_t time_seconds = time(NULL);    struct tm now_time;    localtime_s(&now_time, &time_seconds);
    92         char str[26]; strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", &now_time);
    93         outfile << __FUNCTION__ << " ; c_pData_test->m_nNumData: " << c_pData_test->m_nNumData << " ; c_MaData.size: " << c_MaData.size() << " " << str << endl;
    94         outfile << "--------------------------------------------------------------" << endl;
    95     }
    96     outfile.close();
    97 #endif // MyClassTestDeBug
    98 }
    99
  3. 返回调用部分代码:
    以下内容为程序代码:

    1 // StockFunc.cpp : Defines the entry point for the DLL application.
    2 //
    3
    4 #include "pch.h"    //#include "stdafx.h"
    5 #include "StockFunc.h"
    6 #include "CTestDemo.h"
    7 #include "stdio.h"
    8 #include "vector"
    9
    10 #define Test_Interface_DeBug
    11
    12 BOOL APIENTRY DllMain( HANDLE hModule,
    13 DWORD ul_reason_for_call,
    14 LPVOID lpReserved
    15                      )
    16 {
    17 switch (ul_reason_for_call)
    18     {
    19         case DLL_PROCESS_ATTACH:
    20         case DLL_THREAD_ATTACH:
    21         case DLL_THREAD_DETACH:
    22         case DLL_PROCESS_DETACH:
    23             break;
    24 }
    25 return TRUE;
    26 }
    27
    28 //DLL公式的运行模式,系统系统调用该DLL时,告知公式系统该DLL公式运行在何种模式下
    29 //返回值:     0本DLL运行序列模式 1本DLL运行逐周期模式
    30 __declspec(dllexport) int WINAPI RUNMODE()
    31 {
    32     //本DLL运行序列模式,如果运行逐K线模式将此函数返回1,此时每执行一个K线都是调用本接口一次。
    33 //    return 1;
    34     return 0;
    35 }
    36
    37
    38 //测试对象函数部分
    39 MyClassTest* instance = nullptr; //定义一个类指针的全局变量,目的是为了下面的MYMACLOSE_TEST2也能够通过这个指针获得类属性
    40 __declspec(dllexport) int WINAPI MYMACLOSE_TEST1(CALCINFO* pData)
    41 {
    42     if (pData->m_pfParam1 &&                //参数1有效
    43         pData->m_nParam1Start < 0 &&            //参数1为常数
    44         pData->m_pfParam2 == NULL)            //仅有一个参数
    45     {
    46         float fParam = *pData->m_pfParam1;
    47         int nPeriod = (int)fParam;            //参数1
    48         instance = new MyClassTest(pData);    //类的实例化
    49         instance->MyCalMa(nPeriod);            //计算均线值
    50         const std::vector<float>& maData = instance->c_MaData; //获得类属性(均线值)
    51         for (int i = nPeriod - 1; i < (int)maData.size(); i++)//计算nPeriod周期的均线,数据从nPeriod-1开始有效
    52         {
    53             pData->m_pResultBuf[i] = maData[i];    //平均
    54         }
    55 #ifdef Test_Interface_DeBug
    56         ofstream outfile;
    57         outfile.open("./Document/ctestdomedebug.txt", ios::app);    //"D:/Program Files (x86)/Weisoft Stock(x86)/Document/clcdebug.txt"
    58         if (outfile.is_open())
    59         {
    60             time_t time_seconds = time(NULL);    struct tm now_time;    localtime_s(&now_time, &time_seconds);
    61             char str[26]; strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", &now_time);
    62             outfile << __FUNCTION__ << " ; maData.size: " << maData.size() << " " << str << endl;
    63             outfile << "instance指向的地址:" << instance <<" ; 获得的类属性(返回的均线值)的地址:"<< &maData<< endl;
    64             outfile << "--------------------------------------------------------------" << endl;
    65         }
    66         outfile.close();
    67 #endif // Test_Interface_DeBug
    68         return nPeriod - 1;
    69     }
    70     return -1;
    71 }
    72
    73 //该函数测试上面全局变量instance是否可用?
    74 __declspec(dllexport) int WINAPI MYMACLOSE_TEST2(CALCINFO* pData)
    75 {
    76     if (pData->m_pfParam1 &&                //参数1有效
    77         pData->m_nParam1Start < 0 &&            //参数1为常数
    78         pData->m_pfParam2 == NULL)            //仅有一个参数
    79     {
    80 #ifdef Test_Interface_DeBug
    81         ofstream outfile;
    82         outfile.open("./Document/ctestdomedebug.txt", ios::app);    //"D:/Program Files (x86)/Weisoft Stock(x86)/Document/clcdebug.txt"
    83         if (outfile.is_open())
    84         {
    85             time_t time_seconds = time(NULL);    struct tm now_time;    localtime_s(&now_time, &time_seconds);
    86             char str[26]; strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", &now_time);
    87             outfile << __FUNCTION__ << " ; pData->m_nNumData: " << pData->m_nNumData << " " << str << endl;
    88             outfile << "instance指向的地址:" << instance << endl;
    89             outfile << "--------------------------------------------------------------" << endl;
    90         }
    91         outfile.close();
    92 #endif // Test_Interface_DeBug
    93         float fParam = *pData->m_pfParam1;
    94         int nPeriod = (int)fParam;            //参数1
    95         //instance = new MyClassTest(pData);    //类的实例化
    96         //instance->MyCalMa(nPeriod);            //计算均线值
    97
    98         if (instance == nullptr)
    99         {
    100 #ifdef Test_Interface_DeBug
    101             ofstream outfile1;
    102             outfile1.open("./Document/ctestdomedebug.txt", ios::app);    //"D:/Program Files (x86)/Weisoft Stock(x86)/Document/clcdebug.txt"
    103             if (outfile1.is_open())
    104             {
    105                 time_t time_seconds = time(NULL);    struct tm now_time;    localtime_s(&now_time, &time_seconds);
    106                 char str[26]; strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", &now_time);
    107                 outfile1 << __FUNCTION__ << " 类对象指针指向的均线属性是否为空:" << instance->c_MaData.empty() << " " << str << endl;
    108                 outfile1 << "--------------------------------------------------------------" << endl;
    109             }
    110             outfile1.close();
    111 #endif // Test_Interface_DeBug
    112             return -1;
    113         }
    114
    115         const std::vector<float>& maData = instance->c_MaData; //获得类属性(均线值)
    116
    117         for (int i = nPeriod - 1; i < (int)maData.size(); i++)//计算nPeriod周期的均线,数据从nPeriod-1开始有效
    118         {
    119             pData->m_pResultBuf[i] = maData[i] * 1.01f;    //平均
    120         }
    121 #ifdef Test_Interface_DeBug
    122         ofstream outfile2;
    123         outfile2.open("./Document/ctestdomedebug.txt", ios::app);    //"D:/Program Files (x86)/Weisoft Stock(x86)/Document/clcdebug.txt"
    124         if (outfile2.is_open())
    125         {
    126             time_t time_seconds = time(NULL);    struct tm now_time;    localtime_s(&now_time, &time_seconds);
    127             char str[26]; strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", &now_time);
    128             outfile2 << __FUNCTION__ << " ; maData.size: " << maData.size() << " " << str << endl;
    129             outfile2 << "--------------------------------------------------------------" << endl;
    130         }
    131         outfile2.close();
    132 #endif // Test_Interface_DeBug
    133         return nPeriod - 1;
    134     }
    135     return -1;
    136 }

 回到顶部
帅哥哟,离线,有人找我吗?
永杰
  2楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:新手上路 帖子:77 积分:0 威望:0 精华:0 注册:2015/7/30 6:43:57
  发帖心情 Post By:2020/3/14 9:00:39 [只看该作者]

加我QQ406720655我询问一件事情,或者你在这里回答我的问题,我告诉你实现方法:我用VS2019测试了你这个代码,没有发现任何错误,并且我可以正常编译;而去年51VS2019升级以后,几个月时间,我VS2019无法正常编辑金字塔接口程序,是可以正常打开,但是光标无法下拉到下面编辑的行,咨询了很多人都无法解决,而你这个接口解决了,不知道是金字塔接口文件更新了还是你经过了特殊处理?先谢谢你啊

 回到顶部
帅哥哟,离线,有人找我吗?
永杰
  3楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:新手上路 帖子:77 积分:0 威望:0 精华:0 注册:2015/7/30 6:43:57
  发帖心情 Post By:2020/3/14 9:07:59 [只看该作者]

图片点击可在新窗口打开查看我发图给你看看,你有一个空指针,当然没有多大问题,我编译正常,编辑正常
图片点击可在新窗口打开查看此主题相关图片如下:捕获.png
图片点击可在新窗口打开查看

 回到顶部
帅哥哟,离线,有人找我吗?
无为剑
  4楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:2437 积分:0 威望:0 精华:0 注册:2016/3/5 22:53:41
  发帖心情 Post By:2020/3/14 9:16:09 [只看该作者]

给你2个解决方案你尝试一下:
1 工具-》选项-》其他,勾选DLL公式内存加载驻留模式
2 使用文件保存的方式来实现2个不同的项目之间的数据共享

 回到顶部
帅哥哟,离线,有人找我吗?
canbao
  5楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:新手上路 帖子:16 积分:0 威望:0 精华:0 注册:2015/7/4 2:12:53
  发帖心情 Post By:2020/3/14 10:52:03 [只看该作者]

 首先编译问题肯定是编译器的问题,其次金字塔里的FmlDevelope.zip里的文件来看数据交互头文件确实更新了,但是时间是2018/4/5号,如果你上述问题,可以查看你软件里的这个文件,这是官方给我接口文件!有空多多交流,这一块交流的人确实不多!

 回到顶部
帅哥哟,离线,有人找我吗?
canbao
  6楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:新手上路 帖子:16 积分:0 威望:0 精华:0 注册:2015/7/4 2:12:53
  发帖心情 Post By:2020/3/14 10:56:46 [只看该作者]

 谢谢你的回复,我的问题不是编译的问题,请看文字描述部分,简单说就是,我想创建一个类,计算什么的在该类里实现,然后再金字塔软件里实现多次调用该类的属性,这里是软件与DLL数据交互机制的问题!

 回到顶部
帅哥哟,离线,有人找我吗?
canbao
  7楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:新手上路 帖子:16 积分:0 威望:0 精华:0 注册:2015/7/4 2:12:53
  发帖心情 Post By:2020/3/14 11:06:15 [只看该作者]

 谢谢管理大大的回复,我看了下逐K模式的官方Demo里面用的静态局部变量的vector来存储数据,是不是意味着在逐K模式下,就可以创建一个类对象,然后在多个返回函数里调用该对象?内存驻留模式字面理解确实是这个理,管理大大,软件在与DLL交互时,是不是只管内存申请?当在k线图表界面换品种或周期时又另外再次调用了DLL,而之前的调用确不是软件来管理这样的内存的?即便是DLL里使用的单例模式?

 回到顶部
帅哥哟,离线,有人找我吗?
无为剑
  8楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:2437 积分:0 威望:0 精华:0 注册:2016/3/5 22:53:41
  发帖心情 Post By:2020/3/14 11:54:07 [只看该作者]

如果你选择了DLL驻留模式,就等于说这个DLL就会一直加载的内存中,理论是可以实现你的多个函数的数据共享的,但是如果我们要做类似项目的时候,可能这不是优选的解决方案,因为这种模式不利于排查错误,逻辑复杂也非常容易出错,所以我们会优选文件记录的方式来解决你的项目需求

 回到顶部
帅哥哟,离线,有人找我吗?
canbao
  9楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:新手上路 帖子:16 积分:0 威望:0 精华:0 注册:2015/7/4 2:12:53
  发帖心情 Post By:2020/3/14 13:55:21 [只看该作者]

 是这个理,如果多个地方调用的话,对于整个工程项目确实不好定位错误位置,而且管理也比较容易混乱,我用你说内存DLL驻留的方法,测试成功,管理,还有个问题想请教下,当我在开盘时间里,调用了DLL的公式,如果中途断了连接一段时间,然后又恢复好了,恢复后,公式在K线图表上加载他又是重起始位置重新全部遍历吗?

 回到顶部
帅哥哟,离线,有人找我吗?
无为剑
  10楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:2437 积分:0 威望:0 精华:0 注册:2016/3/5 22:53:41
  发帖心情 Post By:2020/3/14 14:25:46 [只看该作者]

要看你的运行模式是什么,对于逐K线而言,即便你勾选了仅刷最后K线,那么再出现新的K线时也会从头刷一遍的。你也可以多尝试进行日志记录,依此来多了解金字塔PEL的工作机理

 回到顶部
总数 12 1 2 下一页