November 9th, 2005, 7:31 am
i found easyXLL much simpler to setup. Basically all you need to do to create a UDF is:1) add the following to the top your .cpp file:#include <easyxll/include/types.h>#include <easyxll/include/Registrar.h>#include <easyxll/include/Bridge.h>#include <easyxll/include/Controller.h>using namespace easyxll;2) Create your UDF (here's an example of one I used)LPOPER WINAPI _r_x(LPOPER xlAge, LPOPER xlName){ static OPER xlResult; std::string servicetableName; ServiceTableListEntry* pServiceTable; double x; double r_x; try { servicetableName = BridgeValue<std::string>::get(xlName); x = BridgeValue<double>::get(xlAge); // checks on inputs if(Bridge::isVector(xlAge)) throw "ERROR: Age should be single value"; if(servicetableName.empty() == true) throw "ERROR: No table name specified"; if(x < 0) throw "ERROR: Negative age!"; // lookup table name in global array pServiceTable = g_ServiceTableList.FindTable(&servicetableName); if(pServiceTable == NULL) throw "ERROR: Could not find table"; // now we can return the requested r_x r_x = pServiceTable->pTable->r_x->l(x); BridgeValue<double>::make(&xlResult, r_x); return &xlResult; } catch(char* error) { std::string r(error); BridgeValue<std::string>::make(&xlResult, r); return &xlResult; } catch(...) { Bridge::makeError(&xlResult, Bridge::ErrRef); return &xlResult; }}3) Create a function description for the function wizard to see:Registrar rxreg( "_r_x", // "C" Function name "ActXL", // Function wizard category "Age,TableName", // Arguments help "", // Full path to a .HLP or .CHM help file 0, // Entry point number in the help file "Returns a retirement entry r_x of the service table", // Help line for this function false, // Should this function be hidden from the Function Wizard 2, // Number of arguments "Age required", // Help line for first argument "Service table name");4) Finally you must add the function name to a .def file:LIBRARYEXPORTS_r_xThat's it. It should compile to both managed or unmanaged code using c++.net (/clr flag).