📄 fortrandemoobj.cpp
字号:
/*--------------------------------------------------------------------------*
* File Name: FortranDemoObj.cpp *
* Purpose: Demonstrate accessing Fortran Libraries in Origin *
* Creation: April 21, 2000 *
* Copyright Microcal Software Inc. 2000 *
* *
* Modification Log: *
*--------------------------------------------------------------------------*/
#include "FortranDemoObj.h"
//---------------------------------------------------------------------------
// THE_OMOCA_ENTRY_POINT(CDataSetDemo)
//
// This is the main object. A Moca project can have one and only one main
// object declared by the above command which communicates with Origin.
//---------------------------------------------------------------------------
MOCA_ENTRY_POINT(CFortran)
//---------------------------------------------------------------------------
// MOCA projects works with the aid of three types of tables
// 1) Property Tables
// 2) Methods Tables
// 3) Subobject Tables
//
// These tables are used for mapping LabTalk properties and methods to C++
// functions.
//
// 1) Properties(int, double or CString type as simple properties and functions with
// arguments of above types as properties)
// 2) Methods(functions which accepts arguments from LabTalk)
// 3) Subobjects(Member Objects of the main Object and there member Objects....)
// which can have there own properties, methods and subobjects.
// respectively. These Mappings are performed via. the Macros
// OMOCA_BEGIN_PROPERTY_MAP(CLASSNAME, BASECLASSNAME)
// ..........ENTRIES..................................
// OMOCA_END_PROPERTY_MAP(CLASSNAME, BASECLASSNAME)
// for property table, there are similar declaration for Methods and Subobjects
// Tables. The Entries can be of different types (See below) depending on the
// type of the arguments and access levels(Readonly or Writable)
//
// IMPORTANT! IMPORTANT! IMPORTANT! IMPORTANT!
//
// Any class with subobject or methods table MUST have a property
// table, even if it has no entries!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Property Map:
//
// The Property Map is for declaring the properties of your LabTalk object.
//
// A property is mapped to Get and Set function. These functions allow
// you to do error checking or any necessary conversions. A read-only
// property can be declared by using the _GET macro.
//
// MOCA_PROP_INT( <GetFunction>,<SetFunction>,<PropertyNameStr> )
// MOCA_PROP_REAL( <GetFunction>,<SetFunction>,<PropertyNameStr> )
// MOCA_PROP_STR( <GetFunction>,<SetFunction>,<PropertyNameStr> )
// MOCA_PROP_INT_GET( <GetFunction>,<PropertyNameStr> )
// MOCA_PROP_REAL_GET( <GetFunction>,<PropertyNameStr> )
// MOCA_PROP_STR_GET( <GetFunction>,<PropertyNameStr> )
//
// A Simple Property is mapped to a data member. There are no Get/Set
// functions for a Simple Property. MOCA will take care of the assignment.
// A simple read-only property can be declared by using the _GET macro.
//
// MOCA_SIMPLE_PROP_INT( <DataMember>,<PropertyNameStr> )
// MOCA_SIMPLE_PROP_REAL( <DataMember>,<PropertyNameStr> )
// MOCA_SIMPLE_PROP_STR( <DataMember>,<PropertyNameStr> )
// MOCA_SIMPLE_PROP_INT_GET( <DataMember>,<PropertyNameStr> )
// MOCA_SIMPLE_PROP_REAL_GET( <DataMember>,<PropertyNameStr> )
// MOCA_SIMPLE_PROP_STR_GET( <DataMember>,<PropertyNameStr> )
//---------------------------------------------------------------------------
MOCA_BEGIN_PROP_MAP(CFortran, CMOCAObjBase)
MOCA_END_PROP_MAP(CFortran, CMOCAObjBase)
//---------------------------------------------------------------------------
// Method Map:
//
// INPORTANT: To have a Method Map or a SubObject Map, you must
// have a property map.
//
// MOCA_METHOD( <MemberFunction>,<MethodNameStr> )
//
// <MemberFunction> must be declared as "BOOL foo(double &, CStringArray &);"
// The double is used for storing LabTalk's return value.
// The CStringArray contains the arguments passed from LabTalk.
//---------------------------------------------------------------------------
MOCA_BEGIN_METH_MAP(CFortran, CMOCAObjBase)
MOCA_METH_ENTRY(MethodCompute, "COMPUTE")
MOCA_METH_ENTRY(MethodTranspose, "TRANSPOSE")
MOCA_METH_ENTRY(MethodMultiply, "MULTIPLY")
MOCA_METH_ENTRY(MethodPlot, "PLOT")
MOCA_END_METH_MAP(CFortran, CMOCAObjBase)
//---------------------------------------------------------------------------
// SubObject Map:
//
// IMPORTANT: To have a Method Map or a SubObject Map, you must
// have a property map.
//
// MOCA_SUBOBJECT( <m_SubObject>,<SubObjectNameStr> )
//
//---------------------------------------------------------------------------
// This MOCA example has no subobjects.
// The following is an example of how a SubObject table is declared.
//OMOCA_BEGIN_SUBOBJECT_MAP(CLASSNAME, BASECLASSNAME)
// OMOCAENTRY_SUBOBJECT(m_SubObject, "SUBOBJECT")
// OMOCAENTRY_SUBOBJECT(m_SubObject2, "SUBOBJECT2")
//OMOCA_END_SUBOBJECT_MAP(CLASSNAME, BASECLASSNAME)
//---------------------------------------------------------------------------
// CFortran::CFortran()
// CFortran::~CFortran()
//---------------------------------------------------------------------------
CFortran::CFortran()
{
}
CFortran::~CFortran()
{
}
//-------------------------------------------------------------------
//Make Calls to Fortran functions(Use Pointer Variables Only)
// The "C" attribute prevents C++ name mangling and is neede for every
//Fortran routine declared
#ifdef __cplusplus
extern "C"
#endif
float _stdcall MOCAAMACH(int* n);
//unsigned char _stdcall MOCAACHAR(int* i);
#ifdef __cplusplus
extern "C"
#endif
int _stdcall MNDAYS(int* IDAY, int* MONTH, int* IYEAR);
//-------------------------------------------------------------------
BOOL CFortran::MethodCompute(double &dValue, CStringArray &argarray)
{
dValue = NANUM;
int n;
float rinfp;
n = 7;
rinfp = MOCAAMACH(&n);
int i=64;
int day = 21, month = 4, year = 2000;
n = MNDAYS(&day, &month, &year);
dValue = 0;
return TRUE;
}
//-------------------------------------------------------------------
//Make Calls to Fortran functions(Use Pointer Variables Only)
#ifdef __cplusplus
extern "C"
#endif
void _stdcall MOCATRNRR(int* NRA, int* NCA, float A[3][5], int* LDA, float B[5][3]);
//-------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////
// TRANSPOSE(Source_Matrix_Name, Result_Matrix_Name)
//It calls the Fortran function MOCATRNRR, which in tern calls an IMSL function
//to find the transpose of a matrix. I have hard coded the dimensions of the matrices
//and so the source matrix must be 5x3 and the destination 3x5,
//there is a project test.opj in the Fortran folder that I used for testing.
BOOL CFortran::MethodTranspose(double &dValue, CStringArray &argarray)
{
dValue = NANUM;
if(argarray.GetSize() != 2)
return FALSE;
MoMatrix SourceMatrix(argarray[0]);
//check validity
if (! SourceMatrix.IsValid())
{
MessageBox(NULL, "Matrix not valid", "MDLLDemo", MB_OK);
return FALSE;
}
int rows, cols;
rows = (int)SourceMatrix.nRows();
cols = (int)SourceMatrix.nCols();
float z[3][5];
float r[5][3];
int i, j;
for (i=0; i < rows; i++)
{
for (j=0; j < cols; j++)
z[j][i] = SourceMatrix.val(i,j);
}
MOCATRNRR(&rows, &cols, z, &rows,r);
double val;
MoMatrix ResultMatrix(argarray[1]);
//check validity
if (! ResultMatrix.IsValid())
{
MessageBox(NULL, "Matrix not valid", "MDLLDemo", MB_OK);
return FALSE;
}
for ( i=0; i < cols; i++)
{
for (j=0; j < rows; j++)
{
val = r[j][i];
ResultMatrix.SetVal(i , j, val);
}
}
dValue = 0;
return TRUE;
}
//-------------------------------------------------------------------
//Make Calls to Fortran functions(Use Pointer Variables Only)
#ifdef __cplusplus
extern "C"
#endif
void _stdcall MOCAMULTIPLY(int* ROWS, float Z[20], float R[20]);
//-------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////
//MULTIPLY(Data_Set_Name, Result_Data_Set_Name)
//It multiplies the first data set by 5 and puts the result in the second data set.
//It calls a FORTRAN function MOCAMULTIPLY to perform the multiplication.
BOOL CFortran::MethodMultiply(double &dValue, CStringArray &argarray)
{
dValue = NANUM;
if(argarray.GetSize() != 2)
return FALSE;
MoSourceData SourceDataSet(argarray[0]);
//check validity
if (! SourceDataSet.IsValid())
{
MessageBox(NULL, "Dataset not valid", "MDLLDemo", MB_OK);
return FALSE;
}
MoSourceData ResultDataSet(argarray[1]);
//check validity
if (! ResultDataSet.IsValid())
{
MessageBox(NULL, "Dataset not valid", "MDLLDemo", MB_OK);
return FALSE;
}
int rows;
rows = (int)SourceDataSet.iRange2() - (int)SourceDataSet.iRange1();
float z[20];
float r[20];
for (int i=0; i < rows; i++)
{
z[i] = SourceDataSet[i];
}
MOCAMULTIPLY(&rows, z, r);
for (i=0; i < rows; i++)
{
ResultDataSet.SetValue(i, r[i]);
}
dValue = 0;
return TRUE;
}
// avdef.h is the header file for the AView library
#include <avdef.h>
// avviewer.h provides the class declaration for the Array Viewer OLE interface.
#include <avviewer.h>
#include <conio.h>
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//PLOT(matrix name)
//This method opens the Array Visualizer to plot the matrix
BOOL CFortran::MethodPlot(double &dValue, CStringArray &argarray)
{
dValue = NANUM;
if(argarray.GetSize() != 1)
return FALSE;
MoMatrix myMatrix(argarray[0]);
//check validity
if (! myMatrix.IsValid())
{
MessageBox(NULL, "Matrix not valid", "MDLLDemo", MB_OK);
return FALSE;
}
//int dims[] = {5,5};
int dims[2];
dims[0] = myMatrix.nRows();
dims[1] = myMatrix.nCols();
float** z;
// Use aglAlloc to allocate memory for the array.
z = (float **)aglAlloc(2, dims, AGL_FLOAT);
if (z == NULL)
{
printf("aglAlloc failed\n");
return FALSE;
}
for (int i=0; i < myMatrix.nRows(); i++)
{
for (int j=0; j < myMatrix.nCols(); j++)
z[i][j] = myMatrix[i,j];
}
CAViewer *pViewer = new CAViewer;
// Did anything go wrong?
int nError = pViewer->GetErrorNo();
if (nError != 0)
{
printf("Array Viewer reports error: %d\n", nError);
return FALSE;
}
// SetArray tells the viewer to observe our array.
nError = pViewer->SetArray(z);
// Set the title bar on ArrayViewer
pViewer->SetArrayName("test");
// Set the palette to Rainbow_Inverted
pViewer->SetPaletteId(CAViewer::RAINBOW_INVERTED);
pViewer->SetShowPalette(TRUE);
// Array Viewer comes up hidden, use ShowWindow(TRUE) to make it visible
// on the screen.
pViewer->ShowWindow(TRUE);
aglFree(z);
delete pViewer;
dValue = 0;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -