Hi,
among M. Joshi's (and others) xlw examples, a Visual C++ 2010 solution named "ObjectCacheDemo.sln" is present. README.txt by Narinder Claire says: It has been asked several times on a number of forums and mailing lists how to implement the feature of persistent objects in XLW. The standard response from the XLW developers, and rightly so, is to use ObjectHandler. However sometimes what is required is a very small and an extremely light-weight solution and some other times just a demonstration of how it could possibly be done. For these requests I have coded a VERY simple implementation of the feature just to illustrate the concept. Source code shows that permanent Excel objects use multiple inheritance to inherit features either from singleton< class T > and from std::map< std::string, class T >, hence no multiple instances of the same object can be created and std::map indexing method can be used to retrieve objects by using a descriptive std::string. I know that ObjectHandler is used by QuantLibXL to generate all the "obj_01270#0002"-like stuff in Excel cells, but I've not been able to find any documentation explaining how to include and use ObjectHandler classes and methods from scratch: assuming I take advantage of xlw's [cppinterface.h / source.cpp / xlwRapper.cpp / RunInterfaceGenerator] mechanism... I would like to know what to #include in my class and how to use ObjectHandler classes and methods to achieve the same result that QuantLibXL does. Thanks |
Hi Lisa,
The ObjectHandler project includes an example project which demonstrates how you would take a C++ static library and export it to Excel and C++ using ObjectHandler. This example is independent of QuantLib. It is documented here: http://quantlib.org/objecthandler/installation.html That document might be very slightly out of date as far as which #include statements you need, please refer instead to the example source code which is included with ObjectHandler. That example has nothing to do with XLW so if you wanted to link XLW to ObjectHandler then you would need to write the code for that yourself. Kind Regards, Eric On Wed, 12 Aug 2015 07:21:16 -0700 (MST) Lisa Ann <[hidden email]> wrote: > Hi, > > among M. Joshi's (and others) xlw > <http://xlw.sourceforge.net/index.shtml> examples, a Visual C++ 2010 > solution named "ObjectCacheDemo.sln" is present. README.txt by > Narinder Claire says: > > /It has been asked several times on a number of forums and mailing > lists how to implement the feature of persistent objects in XLW. The > standard response from the XLW developers, and rightly so, is to use > ObjectHandler. However sometimes what is required is a very small and > an extremely light-weight solution and some other times just a > demonstration of how it could possibly be done. For these requests I > have coded a VERY simple implementation of the feature just to > illustrate the concept./ > > Source code shows that permanent Excel objects use multiple > inheritance to inherit features either from singleton< class T > and > from std::map< std::string, class T >, hence no multiple instances of > the same object can be created and std::map indexing method can be > used to retrieve objects by using a descriptive std::string. > > I know that ObjectHandler is used by QuantLibXL to generate all the > "obj_01270#0002"-like stuff in Excel cells, but I've not been able to > find any documentation explaining how to include and use > ObjectHandler classes and methods from scratch: assuming I take > advantage of xlw's [cppinterface.h / source.cpp / xlwRapper.cpp / > RunInterfaceGenerator] mechanism... I would like to know what to > #include in my class and how to use ObjectHandler classes and methods > to achieve the same result that QuantLibXL does. > > Thanks > > > > -- > View this message in context: > http://quantlib.10058.n7.nabble.com/Tutorial-to-use-ObjectHandler-outside-of-QuantLibXL-tp16776.html > Sent from the quantlib-users mailing list archive at Nabble.com. > > ------------------------------------------------------------------------------ > _______________________________________________ > QuantLib-users mailing list > [hidden email] > https://lists.sourceforge.net/lists/listinfo/quantlib-users ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Thank you for the hint, Eric.
I've already given a look at: account.hpp addindynamic1.cpp addindynamic2.cpp addinstatic.cpp example.cpp I'm currently trying to understand which are the "basic" blocks that I need to build my first experiments with ObjectHandler. Wandering through classes, for example, I see several classes that might be good candidates to inherit generic objects from (e.g. should a financial instrument to be cached inherit either from Object and from Observable?), but I am not still able to grasp the basic structure. If you had to write a very simple main to cache an object and retrieve its ID via ObjectHandler, how much would your code be different than this? __________________________________________________________________ #include <oh/objecthandler.hpp> class MyObject : public ObjectHandler::Object { public: MyObject(); virtual ~MyObject(); private: // ... } main() { boost::shared_ptr< ObjectHandler::Object> myObject(new MyObject()); ObjectHandler::Repository::instance().storeObject("Lisa", myObject, false); boost::shared_ptr< ObjectHandler::Object> anotherObj(new MyObject()); ObjectHandler::Repository::instance().retrieveObject(anotherObj, "Lisa"); return 0; } __________________________________________________________________ Examples are so full of many methods and classes that I'm afraid of being missing some pieces along the path... Thanks |
Hi Lisa,
> objects from (e.g. should a financial instrument to be cached inherit > either from Object and from Observable?), but I am not still able to Object only. The Observable class is for use internally by ObjectHandler. > If you had to write a very simple main to cache an object and > retrieve its ID via ObjectHandler, how much would your code be > different than this? At first glance the code you provided looks all right to me. If you have further questions don't hesitate to ask. Kind Regards, Eric On Fri, 14 Aug 2015 04:05:38 -0700 (MST) Lisa Ann <[hidden email]> wrote: > Thank you for the hint, Eric. > > I've already given a look at: > > account.hpp > <http://quantlib.org/objecthandler/account_8hpp-example.html> > addindynamic1.cpp > <http://quantlib.org/objecthandler/addindynamic1_8cpp-example.html> > addindynamic2.cpp > <http://quantlib.org/objecthandler/addindynamic2_8cpp-example.html> > addinstatic.cpp > <http://quantlib.org/objecthandler/addinstatic_8cpp-example.html> > example.cpp > <http://quantlib.org/objecthandler/example_8cpp-example.html> > > I'm currently trying to understand which are the "basic" blocks that > I need to build my first experiments with ObjectHandler. Wandering > through classes > <http://quantlib.org/objecthandler/annotated.html> , for example, I > see several classes that might be good candidates to inherit generic > objects from (e.g. should a financial instrument to be cached inherit > either from Object and from Observable?), but I am not still able to > grasp the basic structure. > > If you had to write a very simple main to cache an object and > retrieve its ID via ObjectHandler, how much would your code be > different than this? > __________________________________________________________________ > > #include <oh/objecthandler.hpp> > > class MyObject : public ObjectHandler::Object > { > public: > MyObject(); > virtual ~MyObject(); > private: > // ... > } > > main() > { > boost::shared_ptr< ObjectHandler::Object> myObject(new MyObject()); > ObjectHandler::Repository::instance().storeObject("Lisa", myObject, > false); > boost::shared_ptr< ObjectHandler::Object> anotherObj(new > MyObject()); > ObjectHandler::Repository::instance().retrieveObject(anotherObj, > "Lisa"); > > return 0; > } > __________________________________________________________________ > > Examples are so full of many methods and classes that I'm afraid of > being missing some pieces along the path... > > Thanks > > > > -- > View this message in context: > http://quantlib.10058.n7.nabble.com/Tutorial-to-use-ObjectHandler-outside-of-QuantLibXL-tp16776p16780.html > Sent from the quantlib-users mailing list archive at Nabble.com. > > ------------------------------------------------------------------------------ > _______________________________________________ > QuantLib-users mailing list > [hidden email] > https://lists.sourceforge.net/lists/listinfo/quantlib-users ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
When building release of 'ObjectHandler_vc10' with Visual C++ 2010 Express I get some Windows pop ups that say opening .py files is not possibile (e.g. "preprocess_doxyfile.py").
Am I supposed to have Python installed before building that solution? Should I tell Windows to open those .py files with Python? |
Hello,
> When building release of 'ObjectHandler_vc10' with Visual C++ 2010 > Express I get some Windows pop ups that say opening .py files is not > possibile (e.g. "preprocess_doxyfile.py"). > > Am I supposed to have Python installed before building that solution? > Should I tell Windows to open those .py files with Python? Python is a prerequisite for ObjectHandler. And depending on how Python is installed, you might have to make a little fix to invoke it. This is all explained in the documentation: http://quantlib.org/objecthandler/installation.html Kind Regards, Eric ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Sorry, my bad... I skipped straight Python chapter assuming it was an optional step.
By the way, I now have Python 2.7 installed and I am ready for rebuilding the whole... (just to be sure: uncommented "PYTHON=C:\Python27\python.exe" in ObjectHandler\gensrc\Makefile.vc). 1 rebuild out of 14 fails, and I think that comes from here: +------------------------------------------------------------------ | NMAKE : fatal error U1077: 'doxygen.exe' : return code '0x1' | Stop. | C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Microsoft.MakeFile.Targets(43,5): | error MSB3073: The command "NMAKE /f Makefile.vc /a" exited with code 2. +------------------------------------------------------------------ Nevertheless, I wanted to give it a try with this: /* +------------------------------------------------------------------ * | MyValueObject class derived from ValueObject just * | to be able to use it in a concrete way * +------------------------------------------------------------------ */ #pragma once #include <oh/objecthandler.hpp> class MyValueObject : public ObjectHandler::ValueObject { public: MyValueObject( const std::string& objectId, const std::string& className, bool permanent); ~MyValueObject(); virtual std::vector< std::string > getPropertyNamesVector() const; virtual const std::set< std::string >& getSystemPropertyNames() const; virtual ObjectHandler::property_t getSystemProperty(const std::string& name) const; virtual void setSystemProperty(const std::string& name, const ObjectHandler::property_t& value); }; // I can paste here implementations if needed... __________________________________________________________________ /* +------------------------------------------------------------------ * | Main * +------------------------------------------------------------------ */ #include <iostream> #include "MyValueObject.h" void makeObject( const std::string& objectID, const std::string& name) { boost::shared_ptr< ObjectHandler::ValueObject > valueObject(new MyValueObject(objectID, name, false)); boost::shared_ptr< ObjectHandler::Object > object(new ObjectHandler::Object(valueObject, false)); ObjectHandler::Repository::instance().storeObject(objectID, object, true); }; int main() { try { makeObject("Object1", "Foo"); char tmp; std::cin >> tmp; return 0; } catch(...) { throw "Exception thrown!"; return 1; } } __________________________________________________________________ This fails due to: +------------------------------------------------------------------ | main.obj : error LNK2001: unresolved external symbol | "public: static class ObjectHandler::Repository & __cdecl ObjectHandler::Repository::instance(void)" | (?instance@Repository@ObjectHandler@@SAAAV12@XZ) | C:\...\MyObjectHandler.exe : fatal error LNK1120: 1 unresolved externals +------------------------------------------------------------------ I don't think this is linked to the previous build failure, this seems related to singleton declaration of something static... any help? Do you get the same error? |
Hello,
> 1 rebuild out of 14 fails, and I think that comes from here: > > +------------------------------------------------------------------ > | NMAKE : fatal error U1077: 'doxygen.exe' : return code '0x1' You can ignore that, it's to build the documentation (the same as the web site), or you can install doxygen. > This fails due to: > > +------------------------------------------------------------------ > | main.obj : error LNK2001: unresolved external symbol > | "public: static class ObjectHandler::Repository & __cdecl > ObjectHandler::Repository::instance(void)" > | (?instance@Repository@ObjectHandler@@SAAAV12@XZ) > | C:\...\MyObjectHandler.exe : fatal error LNK1120: 1 unresolved > externals > +------------------------------------------------------------------ > > I don't think this is linked to the previous build failure, this seems > related to singleton declaration of something static... That's right, you need to instantiate the Repository singleton before you can call any of its functions. It doesn't have to be static, it just has to persist for as long as your program uses it. You could put this at the top of your main function: ObjectHandler::Repository repository; Please have a look at the ExampleCpp project. https://github.com/eehlers/quantlib/blob/master/ObjectHandler/Examples/C%2B%2B/example.cpp Kind Regards, Eric ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
I had done what you said, that is, instantiating the Repository singleton before calling its functions, during my first attempts... and this was the result:
int main() { try { ObjectHandler::Repository repository; makeObject("Object1", "Foo"); char tmp; std::cin >> tmp; return 0; } catch(...) { throw "Exception thrown!"; return 1; } } +------------------------------------------------------------------ | C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\Microsoft.Cpp.Win32.Targets(268,5): | error MSB6006: "link.exe" exited with code 1120. | main.obj : error LNK2001: unresolved external symbol "public: static class ObjectHandler::Repository & __cdecl ObjectHandler::Repository::instance(void)" (?instance@Repository@ObjectHandler@@SAAAV12@XZ) | main.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall ObjectHandler::Repository::~Repository(void)" (??1Repository@ObjectHandler@@UAE@XZ) | main.obj : error LNK2001: unresolved external symbol "public: __thiscall ObjectHandler::Repository::Repository(void)" (??0Repository@ObjectHandler@@QAE@XZ) | C:\...\Release\MyObjectHandler.exe : fatal error LNK1120: 3 unresolved externals +------------------------------------------------------------------ That's the reason why I tried to not instantiate it before calling its method. |
> I had done what you said, that is, instantiating the Repository
> singleton before calling its functions, during my first attempts... > and this was the result: > > int main() > { > try > { > *ObjectHandler::Repository repository;* > makeObject("Object1", "Foo"); > > char tmp; > std::cin >> tmp; > return 0; > } > catch(...) > { > throw "Exception thrown!"; > return 1; > } > } You definitely need to instantiate the repository, so whatever error you got must be something else, let's see the message. What happens if you run this code? #include <iostream> #include <exception> int main() { try { ObjectHandler::Repository repository; makeObject("Object1", "Foo"); return 0; } catch(const std::exception &e) { std::cout "Exception " << e.what() << std::endl; return 1; } catch(...) { std::cout "Exception" << std::endl; return 1; } } ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
If I run your code, build fails due to:
+------------------------------------------------------------------ | C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\Microsoft.Cpp.Win32.Targets(268,5): error MSB6006: "link.exe" exited with code 1120. | main.obj : error LNK2001: unresolved external symbol "public: static class ObjectHandler::Repository & __cdecl ObjectHandler::Repository::instance(void)" (?instance@Repository@ObjectHandler@@SAAAV12@XZ) | main.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall ObjectHandler::Repository::~Repository(void)" (??1Repository@ObjectHandler@@UAE@XZ) | main.obj : error LNK2001: unresolved external symbol "public: __thiscall ObjectHandler::Repository::Repository(void)" (??0Repository@ObjectHandler@@QAE@XZ) | C:\...\Release\MyObjectHandler.exe : fatal error LNK1120: 3 unresolved externals +------------------------------------------------------------------ If you are able to build it, I guess that something must be wrong in my project VC++ Directories; here is my setup: - Include Directories: C:\DevTools\ObjectHandler\;c:\DevTools\boost_1_54_0\;c:\DevTools\QuantLib-1.3\;$(IncludePath) - Library Directories: C:\DevTools\ObjectHandler\lib\;C:\DevTools\log4cxx\msvc\lib\;c:\DevTools\boost_1_54_0\lib32-msvc-10.0\;c:\DevTools\QuantLib-1.3\lib\;$(LibraryPath) |
I think you need to link to ObjectHandler. It appears that you have
specified the library directory correctly, but you also need to link to the library. There are 3 ways you can do this (pick one): 1) If your project is in the same solution as ObjectHandler, you can make your project dependent on ObjectHandler. This is how the ExampleCpp project does it. 2) In the project properties under linker input you can specify the name of the ObjectHandler lib file. 3) You can add this to your source code file: #include <oh/auto_link.hpp> Kind Regards, Eric On Sun, 23 Aug 2015 06:54:22 -0700 (MST) Lisa Ann <[hidden email]> wrote: > If I run your code, build fails due to: > > +------------------------------------------------------------------ > | C:\Program > Files\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\Microsoft.Cpp.Win32.Targets(268,5): > error MSB6006: "link.exe" exited with code 1120. > | main.obj : error LNK2001: unresolved external symbol "public: > static class ObjectHandler::Repository & __cdecl > ObjectHandler::Repository::instance(void)" > (?instance@Repository@ObjectHandler@@SAAAV12@XZ) > | main.obj : error LNK2001: unresolved external symbol "public: > virtual __thiscall ObjectHandler::Repository::~Repository(void)" > (??1Repository@ObjectHandler@@UAE@XZ) > | main.obj : error LNK2001: unresolved external symbol "public: > __thiscall ObjectHandler::Repository::Repository(void)" > (??0Repository@ObjectHandler@@QAE@XZ) > | C:\...\Release\MyObjectHandler.exe : fatal error LNK1120: 3 > unresolved externals > +------------------------------------------------------------------ > > If you are able to build it, I guess that something must be wrong in > my project VC++ Directories; here is my setup: > > - Include Directories: > *C:\DevTools\ObjectHandler\;c:\DevTools\boost_1_54_0\;c:\DevTools\QuantLib-1.3\;$(IncludePath)* > - Library Directories: > *C:\DevTools\ObjectHandler\lib\;C:\DevTools\log4cxx\msvc\lib\;c:\DevTools\boost_1_54_0\lib32-msvc-10.0\;c:\DevTools\QuantLib-1.3\lib\;$(LibraryPath)* > > > > -- > View this message in context: > http://quantlib.10058.n7.nabble.com/Tutorial-to-use-ObjectHandler-outside-of-QuantLibXL-tp16776p16832.html > Sent from the quantlib-users mailing list archive at Nabble.com. > > ------------------------------------------------------------------------------ > _______________________________________________ > QuantLib-users mailing list > [hidden email] > https://lists.sourceforge.net/lists/listinfo/quantlib-users ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
I picked the third one: #include <oh/auto_link.hpp> in MyValueObject.h.
Finally, some good news (thanks to your holy patience and hints, Eric). This seems to be the the first working step: #include <iostream> #include <exception> #include "MyValueObject.h" void makeObject( const std::string& objectID) { boost::shared_ptr< ObjectHandler::ValueObject > valueObject(new MyValueObject(objectID, "", false)); boost::shared_ptr< ObjectHandler::Object > object(new ObjectHandler::Object(valueObject, false)); ObjectHandler::Repository::instance().storeObject(objectID, object, true); }; std::string getObject( const std::string& objectID) const { boost::shared_ptr< ObjectHandler::Object > object; ObjectHandler::Repository::instance().retrieveObject(object, objectID); boost::shared_ptr< ObjectHandler::ValueObject > valueObject = object->properties(); return valueObject->objectId(); }; int main() { try { ObjectHandler::Repository repository; makeObject("Object1"); std::cout << getObject("Object1"); } catch(const std::exception &e) { std::cout << "Exception " << e.what() << std::endl; return 1; } catch(...) { std::cout << "Exception" << std::endl; return 1; } } Runtime gives "Object1", which is the proper ID :) Now it's time to see how it works in Excel... thank you! |
There's still an element which puzzles me: please, consider as example my code above and let MyValueObject class has a double private variable, "_value", whose value has been initialized with constructor and set equal to 10.
Of course, a proper getter has been defined inside MyValueObject class: const double GetValue() const {return _value}; We've seen that using as instance this function... void makeObject( const std::string& objectID, double value) { boost::shared_ptr< ObjectHandler::ValueObject > valueObject(new MyValueObject(objectID, "", false, value)); boost::shared_ptr< ObjectHandler::Object > object(new ObjectHandler::Object(valueObject, false)); ObjectHandler::Repository::instance().storeObject(objectID, object, true); }; ...we are able to store an object in repository by calling... ObjectHandler::Repository repository; makeObject("Object1", 10); Nevertheless, wandering through ObjectHandler::ValueObject documentation I've given a try to some methods to retrieve that private variable by using MyValueObject::GetValue(), but I've not figured out how it can be done: once properties of an object have been assigned to a ValueObject by... boost::shared_ptr< ObjectHandler::Object > object; ObjectHandler::Repository::instance().retrieveObject(object, objectID); boost::shared_ptr< ObjectHandler::ValueObject > valueObject = object->properties(); ...I would like to find a way to call MyValueObject::GetValue(). In ObjectHandler examples objects derived from ObjectHandler::ValueObject seem able to call their getter methods, whilst my pointer doesn't. |
Hello,
> Nevertheless, wandering through ObjectHandler::ValueObject > <http://quantlib.org/objecthandler/class_object_handler_1_1_value_object.html> > documentation I've given a try to some methods to retrieve that > private variable by using MyValueObject::GetValue(), but I've not > figured out how it can be done: once properties of an object have > been assigned to a ValueObject by... > > boost::shared_ptr< ObjectHandler::Object > object; > ObjectHandler::Repository::instance().retrieveObject(object, > objectID); boost::shared_ptr< ObjectHandler::ValueObject > > valueObject = object->properties(); > > ...I would like to find a way to call MyValueObject::GetValue(). I think you could do double d = object->properties()->GetValue(); I would not bother with the member variable and the getter, if the value is in the properties of the value object then you should just be able to do double d = object->properties()->getProperty("value"); I have not tested either of those statements and it might be necessary to monkey around with the syntax a litte. Kind Regards, Eric ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Free forum by Nabble | Edit this page |