-- 作者:canbao
-- 发布时间:2020/3/13 21:24:14
-- 请问金字塔软件怎样在DLL中全局类对象以供多个函数调用?
1.编译环境及版本信息- 金字塔版本
金字塔决策交易系统(x86)2020(v5.21) - IDE
Visual Studio Community 2019 版本 16.4.6 - 完整测试代码在附件中
2. 问题描述- 在金字塔软件中,在公式里序列模式下调用DLL扩展函数时,使用了类,在调用该函数时在全局区定义了一个全局变量并置为空,然后在调用的函数处,通过new的方式创建一个对象,并把全局指针变量指向该对象;通过打印文件方式查看到当在金字塔软件里公式调用该DLL函数时,当改变品种或者周期时并没有调用析构函数,但是却新调用了构造函数创建了新的类对象,这里是金字塔通过DLL管理这一块堆上的内存还是用户自己要在DLL里自己进行管理,是否会存在内存泄露的问题?
- 在上诉函数之后,再调用其他函数,该全局指针并未指向上一个函数所产生的对象?要在其他函数里使用其中一个函数中创建的类对象,要进行怎样的定义才行?
3. 想要实现的目的想要实现的目的:比如在 MYMACLOSE_TEST1 中创建了一个类,怎样才能在 MYMACLOSE_TEST2 函数中调用上面 MYMACLOSE_TEST1 中创建的对象,这样就可以调用返回对象的多个属性而不用多次创建,因为用 pData->m_pResultBuf[] 返回值时只能返回一组计算值,当想要返回其他组的计算值是要另外返回 pData->m_pResultBuf[] 才能再公式里获得! 4. 打印的记录信息
5. 测试代码- 金字塔公式
目的就是想用 MYMACLOSE_TEST2 调用 MYMACLOSE_TEST1 中创建的对象,这样就不用重复再计算了,因为如果对象中有多个属性需要返回时,好像只能通过多次函数调用返回! - 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 - 返回调用部分代码:
以下内容为程序代码:
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 }
|