|
// CExample.cpp : Console application that shows how to use the parser through C style DLL calls.
#include "stdafx.h"
#include "bcParserDLL.h" #include "bcParserDLL_unicode.h" #include "objbase.h" //to call CoInitialize #include <TCHAR.h> //to switch betwen _UNICODE, _MBCS etc.
static void printLastError(HANDLE hParser){
_TCHAR temp[255]; //enough storage to hold the eror description.
int size = 0; if(SUCCEEDED(getErrorInfo(hParser, temp, 255, &size))){ _tprintf(_T("Error was: %s\n"), temp); }else{
_tprintf(_T("Error: Could not get the error description!\n")); if(size>0){ //the buffer we have specified was too small.
_tprintf(_T("Required buffer size was: %d\n"), size); } } }
static void displayExpression(HANDLE hParser){
_TCHAR temp[255]; //enough storage to hold the current expression. int size = 0; if(SUCCEEDED(get_Expression(hParser, temp, 255/*2*/, &size))){ _tprintf(_T("Expression was: %s\n"), temp); }else{
_tprintf(_T("Error: Could not get the current expression!\n")); if(size>0){ //the buffer we have specified was too small.
_tprintf(_T("Required buffer size was: %d\n"), size); } } }
int main(int argc, char* argv[]) { if(FAILED(CoInitialize(NULL))){ //still need to initialize COM _tprintf(_T("Could not initialize COM")); return 1; }
_tprintf(_T("Hello World! I am going to *parse* you now! :-)\n"));
//create an instance of expression parser: HANDLE hParser = CreateParser();
if(hParser!=0){//if the handle is non 0, it succeeded.
_tprintf(_T("Parser created!\n")); }else{ _tprintf(_T("Failed to create parser!\n")); return 1; }
//pick an expression to parse. _TCHAR *chr = _T(
"x+3+MYVAR"); //"x+3+MYVAR+THISGIVES_ERROR";
//example of setting any variable:
//(if not created yet, it will create it.) if(FAILED(put_Variable(hParser, _T("MYVAR"), 15))){ //may happen if variable name is not valid. _tprintf(_T("Error: Could not set the new variable MYVAR.")); }
//X is a predefined variable:
put_X(hParser, 5); //not checking return error code for simplicity.
put_Expression(hParser, chr); //set the expression to parse.
double aValue = 0.0;
//evaluate the expression: if(FAILED(
Evaluate(hParser, &aValue))){ _tprintf(_T("Expression '%s' evaluation failed.\n"), chr); printLastError(hParser);
}else{ //display result: _tprintf(_T("Evaluation result for '%s' is %f\n"), chr, aValue);
//report our ground breaking success in detail now: displayExpression(hParser); }
//free the parser instance: FreeParser(hParser)
;
_tprintf(_T("Done!\n"));
CoUninitialize(); //un-init COM
return 0;
}
Output screenshot:

Here is the bcParser.DLL’s exported functions
(Generated by Borland impdef tool)
LIBRARY BCPARSER.DLL
EXPORTS
CreateDefaultFuncs @5 ; CreateDefaultFuncs
CreateDefaultVars @6 ; CreateDefaultVars
CreateParser @7 ; CreateParser
DeleteAllFuncs @8 ; DeleteAllFuncs
DeleteAllVars @9 ; DeleteAllVars
DllCanUnloadNow @1 ; DllCanUnloadNow
DllGetClassObject @2 ; DllGetClassObject
DllRegisterServer @3 ; DllRegisterServer
DllUnregisterServer @4 ; DllUnregisterServer
Evaluate @10 ; Evaluate
FreeParseTree @11 ; FreeParseTree
FreeParser @12 ; FreeParser GetInvalidPortionOfExpression @13 ; GetInvalidPortionOfExpression
GetInvalidPortionOfExpressionW @14 ; GetInvalidPortionOfExpressionW
Parse @15 ; Parse
Randomize @16 ; Randomize
_Create3ParamFuncwAddress @17 ; _Create3ParamFuncwAddress _Create3ParamFuncwAddressW @18 ; _Create3ParamFuncwAddressW
_CreateOneParamFuncwAddress @19 ; _CreateOneParamFuncwAddress _CreateOneParamFuncwAddressW @20 ; _CreateOneParamFuncwAddressW
_CreateTwoParamFuncwAddress @21 ; _CreateTwoParamFuncwAddress _CreateTwoParamFuncwAddressW @22 ; _CreateTwoParamFuncwAddressW
_CreateVar @23 ; _CreateVar
_CreateVarW @24 ; _CreateVarW
_DeleteFunc @25 ; _DeleteFunc
_DeleteFuncW @26 ; _DeleteFuncW
_DeleteVar @27 ; _DeleteVar
_DeleteVarW @28 ; _DeleteVarW
_Is3ParamFunction @29 ; _Is3ParamFunction
_Is3ParamFunctionW @30 ; _Is3ParamFunctionW
_IsFuncUsed @31 ; _IsFuncUsed
_IsFuncUsedW @32 ; _IsFuncUsedW
_IsOneParamFunction @33 ; _IsOneParamFunction _IsOneParamFunctionW @34 ; _IsOneParamFunctionW
_IsTwoParamFunction @35 ; _IsTwoParamFunction
_IsTwoParamFunctionW @36 ; _IsTwoParamFunctionW
_IsVariable @37 ; _IsVariable
_IsVariableUsed @38 ; _IsVariableUsed
_IsVariableUsedW @39 ; _IsVariableUsedW
_IsVariableW @40 ; _IsVariableW
_getErrorInfo @41 ; _getErrorInfo
_getErrorInfoW @42 ; _getErrorInfoW
_get_Expression @43 ; _get_Expression
_get_ExpressionW @44 ; _get_ExpressionW
_get_Variable @45 ; _get_Variable
_get_VariableW @46 ; _get_VariableW
_put_Expression @47 ; _put_Expression
_put_ExpressionW @48 ; _put_ExpressionW
_put_Variable @49 ; _put_Variable
_put_VariableW @50 ; _put_VariableW
get_OptimizationOn @51 ; get_OptimizationOn
get_Value @52 ; get_Value
get_X @53 ; get_X
get_Y @54 ; get_Y
put_OptimizationOn @55 ; put_OptimizationOn
put_X @56 ; put_X
put_Y @57 ; put_Y
bcParserDLL_unicode.h
#ifndef __BCPARSER_UNICODE__ #define __BCPARSER_UNICODE__ //This header is used to map UNICODE and ANSI versions of the DLL functions to a common name to be able to write portable code that can be compiled with _UNICODE ON or OFF.
#ifdef _UNICODE
#define IsTwoParamFunction _IsTwoParamFunctionW
#define IsOneParamFunction _IsOneParamFunctionW #define IsVariable _IsVariableW #define IsVariableUsed _IsVariableUsedW #define IsFuncUsed _IsFuncUsedW #define DeleteFunc _DeleteFuncW
#define DeleteVar _DeleteVarW #define CreateTwoParamFuncwAddress _CreateTwoParamFuncwAddressW #define CreateOneParamFuncwAddress _CreateOneParamFuncwAddressW #define CreateVar _CreateVarW #define get_Variable _get_VariableW #define put_Variable _put_VariableW #define get_Expression _get_ExpressionW
#define put_Expression _put_ExpressionW #define Is3ParamFunction _Is3ParamFunctionW #define Create3ParamFuncwAddress _Create3ParamFuncwAddressW #define getErrorInfo _getErrorInfoW
#else //if not _UNICODE
#define IsTwoParamFunction _IsTwoParamFunction
#define IsOneParamFunction _IsOneParamFunction #define IsVariable _IsVariable #define IsVariableUsed _IsVariableUsed #define IsFuncUsed _IsFuncUsed #define DeleteFunc _DeleteFunc
#define DeleteVar _DeleteVar #define CreateTwoParamFuncwAddress _CreateTwoParamFuncwAddress #define CreateOneParamFuncwAddress _CreateOneParamFuncwAddress #define CreateVar _CreateVar #define get_Variable _get_Variable #define put_Variable _put_Variable #define get_Expression _get_Expression
#define put_Expression _put_Expression #define Is3ParamFunction _Is3ParamFunction #define Create3ParamFuncwAddress _Create3ParamFuncwAddress #define getErrorInfo _getErrorInfo #endif
#endif //__BCPARSER_UNICODE__
Here is the listing for the bcParserDLL.h
(C function signatures in bcParser.dll)
// The following ifdef block is the standard way of creating macros which make exporting from a DLL simpler. All files within this DLL are compiled with the BCPARSERDLL_EXPORTS symbol defined on the command line. this symbol should not be defined on any project that uses this DLL. This way any other project whose source files include this file see BCPARSERDLL_API functions as being imported from a DLL, wheras this DLL sees symbols defined with this macro as being exported.
#ifdef BCPARSERDLL_EXPORTS
#define BCPARSERDLL_API extern "C" __declspec(dllexport)
#else #define BCPARSERDLL_API extern "C" __declspec(dllimport) #endif
#define BC_STDMETHOD(x) BCPARSERDLL_API HRESULT x
typedef long double NUMBER; //the number format used in the calculations
/*TTwoParamFunc type specifies the prototype of the functions that users can add to the list of available functions with two parameters to be used in an expression. */
typedef NUMBER __stdcall fTwoParamFunc(const NUMBER x, const NUMBER y);
/*TOneParamFunc type specifies the prototype of the functions that users can add to the list of available functions with one parameter to be used in an expression. */
typedef NUMBER __stdcall fOneParamFunc(const NUMBER x);
/*T3ParamFunc type specifies the prototype of the functions that users can add to the list of available functions with 3 parameters to be used in an expression. */
typedef NUMBER __stdcall f3ParamFunc(const NUMBER x, const NUMBER y, const NUMBER z);
BCPARSERDLL_API HANDLE CreateParser();
BCPARSERDLL_API void FreeParser(HANDLE hParser);
/*All methods return an HRESULT value that indicate whether the function has succeeded or not. If the return value hRESULT == S_OK, then the function has succeeded. It can be checked using the macros SUCCEEDED(hResult) or FAILED(hResult) as well. These are the standard COM HRESULTs and relevant documentation will have if you have any questions. If any functions returns an error, then the error description string can be obtained by calling getErrorInfo function. Once this function is called, it clears the error info. */
BC_STDMETHOD(_IsTwoParamFunction)(HANDLE hParser,/*[in]*/ char *funcName, /*[out, retval]*/ BOOL *exists);
BC_STDMETHOD(_IsTwoParamFunctionW)(HANDLE hParser,/*[in]*/ WCHAR *funcName, /*[out, retval]*/ BOOL *exists);
BC_STDMETHOD(_IsOneParamFunction)(HANDLE hParser,/*[in]*/ char *funcName, /*[out, retval]*/ BOOL *exists);
BC_STDMETHOD(_IsOneParamFunctionW)(HANDLE hParser,/*[in]*/ WCHAR *funcName, /*[out, retval]*/ BOOL *exists);
BC_STDMETHOD(_IsVariable)(HANDLE hParser,/*[in]*/ char * varName, /*[out, retval]*/ BOOL *exists);
BC_STDMETHOD(_IsVariableW)(HANDLE hParser,/*[in]*/ WCHAR * varName, /*[out, retval]*/ BOOL *exists);
BC_STDMETHOD(_IsVariableUsed)(HANDLE hParser,/*[in]*/ char * funcName, /*[out, retval]*/ BOOL *isUsed);
BC_STDMETHOD(_IsVariableUsedW)(HANDLE hParser,/*[in]*/ WCHAR * funcName, /*[out, retval]*/ BOOL *isUsed);
BC_STDMETHOD(_IsFuncUsed)(HANDLE hParser,/*[in]*/ char * funcName, /*[out, retval]*/ BOOL *isUsed);
BC_STDMETHOD(_IsFuncUsedW)(HANDLE hParser,/*[in]*/ WCHAR * funcName, /*[out, retval]*/ BOOL *isUsed);
BC_STDMETHOD(FreeParseTree)(HANDLE hParser);
BC_STDMETHOD(Randomize)(HANDLE hParser);
BC_STDMETHOD(DeleteAllFuncs)(HANDLE hParser);
BC_STDMETHOD(DeleteAllVars)(HANDLE hParser);
BC_STDMETHOD(_DeleteFunc)(HANDLE hParser,/*[in]*/ char * funcName);
BC_STDMETHOD(_DeleteFuncW)(HANDLE hParser,/*[in]*/ WCHAR * funcName);
BC_STDMETHOD(_DeleteVar)(HANDLE hParser,/*[in]*/ char * varName);
BC_STDMETHOD(_DeleteVarW)(HANDLE hParser,/*[in]*/ WCHAR * varName);
BC_STDMETHOD(CreateDefaultVars)(HANDLE hParser);
BC_STDMETHOD(CreateDefaultFuncs)(HANDLE hParser);
BC_STDMETHOD(_CreateOneParamFuncwAddress)(HANDLE hParser,/*[in]*/ char * newFuncName, /*[in]*/ fOneParamFunc funcAddr);
BC_STDMETHOD(_CreateOneParamFuncwAddressW)(HANDLE hParser,/*[in]*/ WCHAR * newFuncName, /*[in]*/ fOneParamFunc funcAddr);
BC_STDMETHOD(_CreateTwoParamFuncwAddress)(HANDLE hParser,/*[in]*/ char * newFuncName, /*[in]*/ fTwoParamFunc funcAddr);
BC_STDMETHOD(_CreateTwoParamFuncwAddressW)(HANDLE hParser,/*[in]*/ WCHAR * newFuncName, /*[in]*/ fTwoParamFunc funcAddr);
BC_STDMETHOD(_Create3ParamFuncwAddress)(HANDLE hParser,/*[in]*/ char * newFuncName, /*[in]*/ f3ParamFunc funcAddr);
BC_STDMETHOD(_Create3ParamFuncwAddressW)(HANDLE hParser,/*[in]*/ WCHAR * newFuncName, /*[in]*/ f3ParamFunc funcAddr);
BC_STDMETHOD(_CreateVar)(HANDLE hParser,/*[in]*/ char * varName, /*[in]*/ double varValue);
BC_STDMETHOD(_CreateVarW)(HANDLE hParser,/*[in]*/ WCHAR * varName, /*[in]*/ double varValue);
BC_STDMETHOD(Parse)(HANDLE hParser);
BC_STDMETHOD(Evaluate)(HANDLE hParser,/*[out, retval]*/ double *pVal);
BC_STDMETHOD(get_OptimizationOn)(HANDLE hParser,/*[out, retval]*/ BOOL *pVal);
BC_STDMETHOD(put_OptimizationOn)(HANDLE hParser,/*[in]*/ BOOL newVal);
BC_STDMETHOD(get_Y)(HANDLE hParser,/*[out, retval]*/ double *pVal);
BC_STDMETHOD(put_Y)(HANDLE hParser,/*[in]*/ double newVal);
BC_STDMETHOD(get_X)(HANDLE hParser,/*[out, retval]*/ double *pVal);
BC_STDMETHOD(put_X)(HANDLE hParser,/*[in]*/ double newVal);
BC_STDMETHOD(_get_Variable)(HANDLE hParser,/*[in]*/ char * varName, /*[out, retval]*/ double *pVal);
BC_STDMETHOD(_get_VariableW)(HANDLE hParser,/*[in]*/ WCHAR * varName, /*[out, retval]*/ double *pVal);
BC_STDMETHOD(_put_Variable)(HANDLE hParser,/*[in]*/ char * varName, /*[in]*/ double newVal);
BC_STDMETHOD(_put_VariableW)(HANDLE hParser,/*[in]*/ WCHAR * varName, /*[in]*/ double newVal);
BC_STDMETHOD(get_Value)(HANDLE hParser,/*[out, retval]*/ double *pVal);
/*The expression char array is copied into the buffer that is passed in by the caller with pVal parameter. The argument int len specifies the size of this pVal buffer. If this pVal buffer size len is not enough, then this function will return an error and the int * requiredLen argument will carry out the buffer length that is required to copy the expression.*/
BC_STDMETHOD(_get_Expression)(HANDLE hParser,/*[in, out, retval]*/ char *pVal, /*[in]*/ int len, /*[in, out, retval]*/int * requiredLen);
BC_STDMETHOD(_get_ExpressionW)(HANDLE hParser,/*[in, out, retval]*/ WCHAR *pVal, /*[in]*/ int len, /*[in, out, retval]*/int * requiredLen);
BC_STDMETHOD(_put_Expression)(HANDLE hParser,/*[in]*/ char * newVal);
BC_STDMETHOD(_put_ExpressionW)(HANDLE hParser,/*[in]*/ WCHAR * newVal);
BC_STDMETHOD(_Is3ParamFunction)(HANDLE hParser,/*[in]*/ char * newFuncName, /*[out, retval]*/ BOOL *exists);
BC_STDMETHOD(_Is3ParamFunctionW)(HANDLE hParser,/*[in]*/ WCHAR * newFuncName, /*[out, retval]*/ BOOL *exists);
/*The error message char array is copied into the buffer that is passed in by the caller with pVal parameter. The argument int len specifies the size of this pVal buffer. If this pVal buffer size len is not enough, then this function will return an error and the int * requiredLen argument will carry out the buffer length that is required to copy the expression.*/
BC_STDMETHOD(_getErrorInfo)(HANDLE hParser, char * pVal, int len, int * required_length);
BC_STDMETHOD(_getErrorInfoW)(HANDLE hParser, WCHAR * pVal, int len, int * required_length);
|