Define and Register a Custom DLL to Export Curves

Through the preference file *RegisterExportDLL(), you can register a DLL for use in exporting curves. The statement is found within the *BeginPlotDefaults() block in the preferences file.

When you use the *RegisterExportDLL() to register a DLL, the name of the DLL is displayed in the list of formats found in the Export Curves dialog. It can then be used as a format to export curves and curve information. Select Export Curves from the File menu to access this dialog.

For example, the statement *RegisterExportDLL("Export DLL", "C:\\software\\export_dll.dll") in a preference file registers the DLL found in C:\software\export_dll.dll as "Export DLL". After reading in the preference file and selecting Export Curves, "Export DLL" will be at the end of the list of formats in the Export Curves dialog box. If "Export DLL" is selected as the format, the file name to which it will be exported is "export" (with no extension). When "Export DLL" is selected and curves are exported to it, the curves are exported by the format dictated in C:\software\export_dll.dll.

Within the DLL, there must be at least three functions exported.
  1. The Open function to open the file. The only parameter it takes is the filename to open, passed as a string, which is specified by you in the Export Curves dialog. This function is called after you click Apply on the Export Curves dialog, but before any data is written, and opens the file "export" for writing. See example above.
  2. The WriteCurve function that writes the curve data to the newly-opened file. This takes one parameter, which is a pointer to a PlotCurveData. The PlotCurveData structure holds the data for the curve. The PlotCurveData structure itself contains members that are of the structures AttributeData, VectorInfo, and NoteInfo. All of these structure are included in the example below. The WriteCurve function is called after the file has been opened and writes the data out to the file opened by OpenFile. WriteCurve is called once for each curve to be exported.
  3. The Close function closes the file after the data has been written. It takes no parameters and is called after the data has been written to the file.
The three DLL functions are:
  • Open(char* filename)
  • WriteCurve(PlotCurveData* curve_data)
  • Close()
Sample DLL Functions and Variables/Structures:
#define DLLFUNC __declspec(dllexport)

// Global Variable
FILE *fp;
*********************************************************************************
struct AttributeData
{
    AttributeData();
    ~AttributeData();

    char                *varname;
    char                *label;
    short                type;
    short                attach_to;
    char                *value;

    void SetAttributeData(Attribute*);

private:
    AttributeData& operator=(const AttributeData&);
};
*********************************************************************************
struct VectorInfo
{
    VectorInfo(VectorSource&);
    ~VectorInfo();

    enum    Type {MATH, FILE, VALS};

    Type    type;

    char    *expression;

    char    *filename;
    char    *data_type;
    char    *request;
    char    *component;

    long     start_idx;
    long     end_idx;
    long     increment;

    long     num_points;
    double  *data;
};
*********************************************************************************
struct NoteInfo
{
    NoteInfo();
    ~NoteInfo();

    void SetNoteInfo(PlotNote*);

    long   attachment_idx;
    char  *text;
};
*********************************************************************************
struct PlotCurveData
{
    PlotCurveData(PlotCurve*);
    ~PlotCurveData();

    char    *label;

    short    num_x_attributes;
    short    num_y_attributes;
    short    num_curve_attributes;

    AttributeData  *x_attributes;
    AttributeData  *y_attributes;
    AttributeData  *curve_attributes;

    VectorInfo  *x_vector;
    VectorInfo  *y_vector;
    VectorInfo  *time_vector;

    short        num_notes;
    NoteInfo    *note_info;

    short        is_on;
};
*********************************************************************************
extern "C" void DLLFUNC Open(char* filename)
{
    fp = fopen(filename, "w");
}
*********************************************************************************
extern "C" void DLLFUNC WriteCurve(PlotCurveData* curve_data)
{
    // Write curve.

    ostrstream  label_ostr;
    ostrstream  num_x_ostr;
    ostrstream  num_y_ostr;
    ostrstream  num_curve_ostr;
    ostrstream  num_notes_ostr;
    ostrstream  is_on_ostr;

    label_ostr << "Label: " << curve_data->label << endl << ends;
    fputs(label_ostr.str(), fp);

    num_x_ostr << "   X: " << curve_data->num_x_attributes << endl << ends;
    fputs(num_x_ostr.str(), fp);

    for (int idx = 0; idx < curve_data->num_x_attributes; idx++)
    {
        ostrstream  x_name_ostr;
        ostrstream  x_label_ostr;
        ostrstream  x_type_ostr;
        ostrstream  x_attach_to_ostr;
        ostrstream  x_value_ostr;

        x_name_ostr << curve_data->x_attributes[idx].varname << endl << ends; 
        fputs(x_name_ostr.str(), fp);

        x_label_ostr << curve_data->x_attributes[idx].label << endl << ends; 
        fputs(x_label_ostr.str(), fp);

        x_type_ostr << curve_data->x_attributes[idx].type << endl << ends; 
        fputs(x_type_ostr.str(), fp);

        x_attach_to_ostr << curve_data->x_attributes[idx].attach_to << endl << ends; 
        fputs(x_attach_to_ostr.str(), fp);

        x_value_ostr << curve_data->x_attributes[idx].value << endl << ends; 
        fputs(x_value_ostr.str(), fp);
    }

    num_y_ostr << "   Y: " << curve_data->num_y_attributes << endl << ends;
    fputs(num_y_ostr.str(), fp);

    for (idx = 0; idx < curve_data->num_y_attributes; idx++)
    {
        ostrstream  y_name_ostr;
        ostrstream  y_label_ostr;
        ostrstream  y_type_ostr;
        ostrstream  y_attach_to_ostr;
        ostrstream  y_value_ostr;

        y_name_ostr << curve_data->y_attributes[idx].varname << endl << ends; 
        fputs(y_name_ostr.str(), fp);

        y_label_ostr << curve_data->y_attributes[idx].label << endl << ends; 
        fputs(y_label_ostr.str(), fp);

        y_type_ostr << curve_data->y_attributes[idx].type << endl << ends; 
        fputs(y_type_ostr.str(), fp);

        y_attach_to_ostr << curve_data->y_attributes[idx].attach_to << endl << ends; 
        fputs(y_attach_to_ostr.str(), fp);

        y_value_ostr << curve_data->y_attributes[idx].value << endl << ends; 
        fputs(y_value_ostr.str(), fp);
    }

    num_curve_ostr << "  Curve: " << curve_data->num_curve_attributes << endl << ends;
    fputs(num_curve_ostr.str(), fp);

    for (idx = 0; idx < curve_data->num_curve_attributes; idx++)
    {
        ostrstream  curve_name_ostr;
        ostrstream  curve_label_ostr;
        ostrstream  curve_type_ostr;
        ostrstream  curve_attach_to_ostr;
        ostrstream  curve_value_ostr;
        
        curve_name_ostr << curve_data->curve_attributes[idx].varname << endl << ends;
        fputs(curve_name_ostr.str(), fp);

        curve_label_ostr << curve_data->curve_attributes[idx].label << endl << ends;
        fputs(curve_label_ostr.str(), fp);

        curve_type_ostr << curve_data->curve_attributes[idx].type << endl << ends;
        fputs(curve_type_ostr.str(), fp);

        curve_attach_to_ostr << curve_data->curve_attributes[idx].attach_to << endl << ends;
        fputs(curve_attach_to_ostr.str(), fp);

        curve_value_ostr << curve_data->curve_attributes[idx].value << endl << ends;
        fputs(curve_value_ostr.str(), fp);
    }

    num_notes_ostr << "  Notes: " << curve_data->num_notes << endl << ends;
    fputs(num_notes_ostr.str(), fp);

    for (idx = 0; idx < curve_data->num_notes; idx++)
    {
        ostrstream  note_info_ostr;
        note_info_ostr << "  " << curve_data->note_info[idx].text << endl << ends;
        fputs(note_info_ostr.str(), fp);
    }

    is_on_ostr << "  Is On? " << curve_data->is_on << endl << ends;
    fputs(is_on_ostr.str(), fp);
}
*********************************************************************************
extern "C" void DLLFUNC Close()
{
    if (fp)
    {
        fclose(fp);
        fp = NULL;
    }
}
*********************************************************************************