[matlab] pyramid extension Formula DLL interacts with MATLAB

Source: Internet
Author: User

Task Description:

There are many functions in the PEL of a tower, but there are situations that need to be expanded in some cases, and a tower provides a way to centralize the expansion, one of which is to use the DLL formula (VC DLL programming) to expand, easy to integrate the original formula.

and Matlab inside provides a lot of signals, sequences and other processing methods, can be very convenient to carry out a number of strategies, calculations and so on.

Now you need to extend the functions of the pyramid using the Custom Function (M function) of MATLAB.

Pre-survey:

VC and Matlab Several ways to interact, see the previous article: http://blog.csdn.net/fonjames/article/details/51554385

First Matlab Engine method is said to be inefficient, not recommended, in turn, tried the C + + shared library --and COM components--the way Matlab coder.

A tower of the required DLL mode, referring to a tower provided by the "Chestnut" project Fmldevelope located in ... \weisoft directory \fmldevelop.zip

The DLL you generated is placed in the directory where ... \weisoft \fmldll

Then use "[email protected]" (ARG1,ARG2) in the formula editor of a tower, and note that double quotes must exist.

< Span style= "Color:rgb (85,85,85); font-family: ' Microsoft Yahei '; font-size:12px; line-height:35px ">

/*///////////////////////////////////////////////////////////////////////////xxx Tower "C Language Interface" Extender call Interface Specification V1.01. Extension functions can be used to implement special algorithms that cannot be implemented by system formula functions. 2. Extension functions are implemented with the Windows 32-bit dynamic link library and are recommended for use in Microsoft Visual C + + programming. 3. Write in Equation Editor when calling "  Dynamic Library name @ Function name (parameter table), for example, the following function can be written as "[Email protected]" (5) 4. Dynamic link library names and function names can be defined by themselves. 5. The dynamic library file must be placed in the same directory as the *.STK document when used. Original error, should be Fmldll directory 6. Note The version of the XX tower that is running, and if it is a x64-bit version, compile the DLL into a 64-bit version of the environment to work correctly. From the 2.34 version of the XXX tower, the interface supports candlestick-by-line mode calls, adding RunMode system functions to inform the calling formula System of the operating mode of this interface. The formula of the XXX tower system runs the mode of the sequence mode and the candlestick pattern, the sequence mode mode of the entire Formula system interpretation will only call once this interface, pass and return the sequence parameter data to the interface, and the candlestick pattern will be interpreted by each candlestick call this interface, delivery and return are also single-valued data. The traditional interface is designed to run in sequential mode, although in the candlestick-by-line mode the XXX tower can also invoke a traditional interface, but this is inefficient and unstable, so use this private mode if you need to use the interface in candlestick-by-candle mode. *//*//Call interface information data structure////////////////////////////////////////////////////typedef struct tagcalcinfo{...} Calcinfo; Note 1:1. The function call parameter is brought in by M_PFPARAM1--M_PFPARAM4 and, if NULL, indicates that the parameter is invalid. 2. When one argument is invalid, all subsequent arguments are invalid. For example: M_PFPARAM2 is null, the M_PFPARAM3,M_ PFPARAM4 is also null.3. Parameter 1 can be a constant parameter or a sequence number parameter, and the remaining parameter can only be a constant parameter. 4. If m_nparam1start<0, the parameter 1 is a constant parameter and the parameter equals *m_pfparam1;5. If m_ Nparam1start>=0, the parameter 1 is a sequence number parameter, m_pfparam1 points to a floating-point array with an array size of m_nNumdata, the data valid range is M_nparam1start to m_nnumdata-1. In time m_pdata[x] and m_pfparam1[x] are the same note 2:1. The extension structure makes the invocation parameters technically infinite, And each parameter is a numeric sequence. The 2.CALCPARAM structure is used to bring the parameter information and the actual data, the M_pcalcparam array size is M_nnumparam, the data valid range is 0 to m_nnumparam-1.3. In order of the parameters, M_pcalcparam[0] Data for the first parameter, M_pcalcparam[1] is the second parameter of the data ..., in order to maintain compatibility, the original M_nparam1start, m_pfparam1 and other 5 attributes are still assigned. 4. Take the M_pcalcparam[i].m_pfparam, the array size is m_nnumdata, the data valid range is M_pcalcparam[i].m_nparamstart to M_nnumdata-1. If m_pcalcparam[i].m_nparamstart<0, there is no valid data in this array. 5. Because multiple sequences can be called, calculations for many sequences can be done first in the formula and then as arguments to the call. *//////////////////////////////////////////////////////* function Output __declspec (dllexport) int xxxxxxxx (calcinfo* pData); 1. Function names should all be capitalized. 2. The function must be declared in the above form, replace xxxxxxxx with the actual function name, and the C + + program should be included in the extern "C" {} brackets. 3. Function calculation result with pdata->m_ Presultbuf bring back. 4. function return-1 indicates that the error or all data is invalid, returns the first valid value position for the sequence pattern, that is: m_presultbuf[return value]--m_presultbuf[m_nnumdata-1] is a valid value. A candlestick-pattern return value greater than or equal to 0 means the run mode of the successful *///dll formula, when the system calls the DLL, tells the formula system which mode the DLL formula runs in//return value: 0 This DLL runs the sequence pattern 1 This DLL runs cycle by period mode __declspec (dllexport) int WINAPI runmode ();//example function, replacing __declspec (dllexport) int with actual name when used WINAPI Mymavar (calcinfo* pData) 

Implementation in the example

Calculate the average price, 2 parameters, parameter 1 is the data of the moving average, parameter 2 indicates the calculation period//Call method: "[Email protected]" (close-open,5) __declspec (dllexport) int WINAPI Mymavar ( calcinfo* pData)//For the candlestick pattern, the method of handling the model code {if (pdata->m_pfparam1 && pdata->m_pfparam2) {//For the candlestick pattern, Because the passed data is numeric, an array is required to hold the arguments passed in to be evaluated.//This example simply demonstrates this usage, and if the user invokes the interface multiple times in the formula, then repeated use of the variable results in a calculation error// Therefore, several of these global static variables are used to hold various data depending on the situation. Static std::vector<double> armadata;//First cycle initialization data if (Pdata->m_dwbarpos = = 0) {armadata.clear ();} Double dbdata = *pdata->m_pfparam1;//prevents repeated refresh problems using only the last candlestick of the brush if (armadata.size () >= pdata->m_nnumdata) armadata[ Armadata.size ()-1] = dbdata; Just update the last data elsearmadata.push_back (dbdata);D word dwcyc = (DWORD) *pdata->m_pfparam2;if (Pdata->m_dwbarpos < DWCYC-1) {/* for non-compute cycles, return invalid data */return-1;} First, float fAdd = 0;for (DWORD i = pdata->m_dwbarpos-(dwCyc-1), I <= pdata->m_dwbarpos; i++) {fAdd + = Armadata[i];} *pdata->m_presultbuf = FADD/DWCYC;} Return 1;*/}

Generating a shared dll for MATLAB

use mcc-w cpplib:yyyxxxxx-t link:lib xxxxxx.m or Deploytool to generate a DLL for the corresponding m function then according to Fmldevelop to write a Win32 DLL, the end result found that a tower after loading this DLL has been hanging dead, the initial suspicion is the load function DllMain to load the M function dll out of the problem.
The process worth documenting is the conversion of Mxarray and Mwarray. Reference http://blog.csdn.net/fonjames/article/details/51622151
   Mwarray dclose = Mwarray (pdata->m_nnumdata,1, Mxdouble_class, mxreal);   Dclose. SetData (&armadata1[0], armadata1.size ());   Mwarray dif1, Dif2;   Mwarray NR = Mwarray ((int) dwrank);   /* M function is automatically generated, declared as: extern lib_matdif_cpp_api void Mw_call_conv matdif (int nargout, mwarray& dif1                                                                                            , mwarray& dif2                                                                                      , const mwarray& close                                                                                        , const mwarray& n);  *   /MATDIF (2, DIF1, Dif2, Dclose, NR);    *pdata->m_presultbuf = Dif1,//mxdouble (DIF1);



A tower after loading the encapsulated DLL, actually does not look for the DLL in the current directory M function, so this process also involves the DLL path lookup, simply put to System32 for its invocation. In this path is not the case, consider the use of COM components, so the third layer (the first layer of a tower, encapsulating the second layer of the DLL) is equal to the whole system to register the location, there is no strong reliance on it?

Build a COM component of MATLABuse Deploytool to generate the COM component of the M function and register it. A method call using http://blog.csdn.net/fonjames/article/details/51543846.
if (disp. CreateObject ("matdif1.libmatdif") = = False) {MessageBox (NULL, "Load COM failed!", "", MB_OK); return 0;}       VARIANT Vclose, v3, VDIF1, Vdif2;    VariantInit (&vclose);   VariantInit (&VDIF1); VariantInit (&VDIF2);    V3.VT = VT_I2;     V3.intval = 3;    VCLOSE.VT = vt_r8| Vt_array;vclose.parray = Safearraycreatevector (Vt_r8,0,armadata1.size ()-1);d ouble * buf = NULL; Safearrayaccessdata (Vclose.parray, (void**) &buf); memcpy (buf,&armadata1[0],sizeof (Double) * ( Armadata1.size ()-1)); Safearrayunaccessdata (vclose.parray);d ISP. InvokeMethod ("Matdif", 2, &vdif1,&vdif2,vclose,v3);pD ata->m_presultbuf = new Float;*pdata->m_ Presultbuf = Vdif1.dblval;
There are new content here, the base type of COM is variant, and the interaction of matrix (vector) data of variant and MATLAB involves SAFEARRAY.Reference articles: http://blog.csdn.net/zhangkunhn/article/details/9220859 and http://blog.csdn.net/csfreebird/article/ details/234547in my example, a relatively simple method is used, in which the array pointer to the vector is the vector-based data is the principle of continuous storage.
  SAFEARRAY Win32 definition: typedef struct TAGSAFEARRAY {//The members of this struct (cdims,clocks, etc.) are set and managed through API functions.          unsigned short cdims;     The number of dimensions of the array unsigned short ffeatures;    A flag used to describe how an array is allocated and how it is released unsigned long cbelements;         The size of the array element unsigned long clocks;                 A counter that is used to track the number of times that the array is locked void * PVDATA; Pointer to data buffer/real data stored in pvdata member Safearraybound rgsabound[1];   Describes the array structure of each dimension of the arrays, the size of which is a mutable//safearraybound structure that defines the details of the array structure.      } SAFEARRAY; /* Rgsabound is an interesting member, its structure is not very intuitive. It is an array of data ranges.      The size of the array differs according to the safe array dimension. The Rgsabound member is an array of safearraybound structures-each element represents a dimension of SAFEARRAY.    */typedef struct TAGSAFEARRAYBOUND {unsigned long celements;   unsigned long llbound;      } safearraybound; /* dimensions are defined in the Cdims member.      For example, the dimension of an array of \ ' c\ ' classes can be a three-dimensional array of [3][4][5]-.     If we use a SAFEARRAY to represent this structure, we define a rgsabound array with three elements-one for one dimension.  Cdims = 3;     Safearraybound Rgsabound[3]; Rgsabound[0] element defines the first dimension. In this example, the Ilbound element is 0, which is the lower bound of the array.      The value of the Celements member is equal to three. The second dimension of the array ([4]) can be defined by the second element of the rgsabound structure. The Nether can alsois 0, the number of elements is 4, and the third dimension is the same. Note that since this is a "C" array, starting with 0, */* for other languages, such as visual Basic, or use a different start.               The details of the array are as follows: element celements Ilbound Rgsabound[0] 3 0 rgsabound[1] 4 0 Rgsabound[2] 5 0 * *



Initializing the COM environment in DllMain, loading the COM file of the M function will cause the program to hang dead and encapsulate the load of COM files into a single method, a singleton call.it is possible to implement the corresponding close data in the pyramid, calculate the result and return it. However, when the switch page (F5) is the time-sharing graph and the K-line graph, it will cause a tower to be hung dead ... (It should be COM's load uninstall problem ...) Need to continue to study)the coder way of Matlabthree layer of call efficiency on the back of a compromise, but also there will be a lot of interaction problems, can directly two layers it? Occasionally found MATLAB provides the coder way. (after 2011a version)Toss the next new version 2014, (compiler also to vs2008 above), the M function generated the source code. you need to select the type of the parameter, and choose to generate C + + code, and select the compiler (VS2008 above) to eventually generate the M function file and rtxxx auxiliary files. After importing all the generated files into the project, each CPP file is pre-compiled with an include "stdAfx.h" file. basically look at the next data structure emxarray_real_t, initialize input data, process output data, generate DLL, put pyramid, call, Success!
<pre name= "code" class= "CPP" >if (Pdata->m_dwbarpos < Dwrank | | PData->m_dwbarpos < PDATA->M_ NNumData-1) {//For non-compute cycles, return invalid data return-1;} Double *dif1 = new Double;double *dif2 = new double;emxarray_real_t * close = emxcreatewrapper_real_t ((double*) &arMaDa Ta[0],1,armadata.size ()); Matdif (close,3, DIF1, dif2);pD ata->m_presultbuf = new Float;*pdata->m_presultbuf = *dif1;emxdestroyarray_real_t (close);



First updated in early 2016.06.16.













[matlab] pyramid extension Formula DLL interacts with MATLAB

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.