ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  Using ChartDirector from C API using bchartdir.h header - is it possible?
Posted by David Linenberg on Mar-04-2018 09:44
I have a pure C program, and would like to use ChartDirector.  I have found the bchartdir.h header file.

   1) can I use chart director from C?
   2) how do I free resources?
   3) Or do I have to use the C++ interface, and then create a C wrapper function around those C++ funtions?

This simple graph works (in that it will create an SVG chart successfully)  - but how do I free the resources? What resources are created that need to be freed?

XYChartInternal * xyChartInternal = CXYChart_create(500, 250, BackgroundColor, Transparent, 0);
CXYChart_setPlotArea(xyChartInternal, 50, 20, 400, 200, Transparent, -1, -1, 0xc0c0c0, Transparent);
double yData[] = { 1, 4, 9, 16, 25, 36, 49, 64 };
double xData[] = { 1, 2, 3, 4, 5, 6, 7, 8};
int dataLen = 8;
LineLayerInternal * lineLayerInternal = CXYChart_addLineLayer(xyChartInternal, yData, dataLen, -1, "", 0);

LayerInternal * layerInternal = LineLayer2Layer(lineLayerInternal);
CLayer_setXData(layerInternal, xData, dataLen);

AxisInternal * yAxis = CXYChart_yAxis(xyChartInternal);
CAxis_setLogScale(yAxis, 0, 70, LogTick, 0);

BaseChartInternal * baseChartInternal = XYChart2BaseChart(xyChartInternal);
int len = 0;
const char * data;
CBaseChart_makeChart2(baseChartInternal, SVG, &data, &len);

//----
free(data);                      *crashes program*  (? how do I free memory?)
free(xyChartInternal)       *crashes program*  (? how do I free memory?)
etc
//----

  Re: Using ChartDirector from C API using bchartdir.h header - is it possible?
Posted by Peter Kwan on Mar-04-2018 15:32
Hi David,

Since you have examined the header files, you probably know that the ChartDirector DLL "chartdir??.dll" only exposes a C interface. The C++ interface are essentially a thin wrapper to the C interface in the header file (and so it is in source code format).

However, we do not suggest developers to use the C interface directly because the C interface is considered as internal interface of ChartDirector. We may modify the C interface from time to time. We only guarantee that the C++ interface is stable and backwards compatible.

For your case, I think the easiest method is to create your own C wrapper to the C++ interface. In this way, your code does not need to worry about future compatibility and all the complications of the wrapper, like memory management, caching and so on. The C wrapper is not complicated. It is like:

/* C header file cchartdir.h */
// empty structures to define strongly typed pointers
struct CXYChart {};
struct CPlotArea {};

CXYChart *new_XYChart(int a, int b, ....) ;
void delete_XYChart(CXYChart *c);
CPlotArea *XYChart_setPlotArea(CXYChart *c, int a, int b, ...);

....

/* wrapper implementation cchartdir.cpp */
include "cchartdir.h"
include "chartdir.h"

CXYChart *create_XYChart(int a, int b, ....)
{ return (CXYChart*) (new XYChart(a, b , ....)); }

void delete_XYChart(CXYChart *c)
{ delete (XYChart *)c; }

CPlotArea *XYChart_setPlotArea(CXYChart *c, int a, int b, ...)
{ return (CPlotArea *) (((XYChart *)c)->setPlotArea(a, b, ...)); }

....


For your information, in the original ChartDirector C++ chartdir.h, the chart is deleted in  the BaseChart destructor (when the XYChart is deleted, the BaseChart destructor is also called).

~BaseChart() { if (--(*refCount) == 0) { CBaseChart_destroy(ptr); delete refCount; } }

The actual code is CBaseChart_destroy. Again, it is not suggested you call this method directly. The suggested way is to write another wrapper to wrap the ChartDirector C++ interface into C.

Regards
Peter Kwan

  Re: Using ChartDirector from C API using bchartdir.h header - is it possible?
Posted by David Linenberg on Mar-04-2018 21:21
Thanks for your quick response and support. That all sounds good.