From 3e2b56b55c0f8fc614e3de6dca5d5ee6354b3bc8 Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Mon, 7 Dec 2020 17:41:05 +0100 Subject: [PATCH 001/143] Add RTTI example basis --- Examples/RTTI/RTTI.xml | 100 ++ .../Bindings/CppDynamic/rtti_abi.hpp | 174 ++++ .../Bindings/CppDynamic/rtti_dynamic.h | 175 ++++ .../Bindings/CppDynamic/rtti_dynamic.hpp | 885 ++++++++++++++++++ .../Bindings/CppDynamic/rtti_types.hpp | 125 +++ .../RTTI_component/Bindings/Python/RTTI.py | 392 ++++++++ .../Python/__pycache__/RTTI.cpython-38.pyc | Bin 0 -> 11311 bytes .../Examples/CppDynamic/CMakeLists.txt | 26 + .../Examples/CppDynamic/RTTI_example.cpp | 38 + .../Examples/Python/RTTI_Example.py | 36 + .../Implementations/Cpp/CMakeLists.txt | 46 + .../Cpp/Interfaces/rtti_abi.hpp | 174 ++++ .../Interfaces/rtti_interfaceexception.cpp | 45 + .../Interfaces/rtti_interfaceexception.hpp | 60 ++ .../Cpp/Interfaces/rtti_interfaces.hpp | 367 ++++++++ .../Cpp/Interfaces/rtti_interfacewrapper.cpp | 407 ++++++++ .../Cpp/Interfaces/rtti_types.hpp | 125 +++ .../Implementations/Cpp/Stub/rtti.cpp | 54 ++ .../Implementations/Cpp/Stub/rtti_animal.cpp | 22 + .../Implementations/Cpp/Stub/rtti_animal.hpp | 67 ++ .../Cpp/Stub/rtti_animaliterator.cpp | 27 + .../Cpp/Stub/rtti_animaliterator.hpp | 69 ++ .../Implementations/Cpp/Stub/rtti_base.cpp | 61 ++ .../Implementations/Cpp/Stub/rtti_base.hpp | 74 ++ .../Implementations/Cpp/Stub/rtti_giraffe.cpp | 22 + .../Implementations/Cpp/Stub/rtti_giraffe.hpp | 67 ++ .../Implementations/Cpp/Stub/rtti_mammal.cpp | 22 + .../Implementations/Cpp/Stub/rtti_mammal.hpp | 67 ++ .../Implementations/Cpp/Stub/rtti_reptile.cpp | 22 + .../Implementations/Cpp/Stub/rtti_reptile.hpp | 67 ++ .../Implementations/Cpp/Stub/rtti_snake.cpp | 22 + .../Implementations/Cpp/Stub/rtti_snake.hpp | 67 ++ .../Implementations/Cpp/Stub/rtti_tiger.cpp | 27 + .../Implementations/Cpp/Stub/rtti_tiger.hpp | 69 ++ .../Implementations/Cpp/Stub/rtti_turtle.cpp | 22 + .../Implementations/Cpp/Stub/rtti_turtle.hpp | 67 ++ .../Implementations/Cpp/Stub/rtti_zoo.cpp | 27 + .../Implementations/Cpp/Stub/rtti_zoo.hpp | 69 ++ Examples/RTTI/RTTI_component/license.txt | 5 + 39 files changed, 4191 insertions(+) create mode 100644 Examples/RTTI/RTTI.xml create mode 100644 Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp create mode 100644 Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h create mode 100644 Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp create mode 100644 Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_types.hpp create mode 100644 Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py create mode 100644 Examples/RTTI/RTTI_component/Bindings/Python/__pycache__/RTTI.cpython-38.pyc create mode 100644 Examples/RTTI/RTTI_component/Examples/CppDynamic/CMakeLists.txt create mode 100644 Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp create mode 100644 Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/CMakeLists.txt create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaceexception.cpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaceexception.hpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_types.hpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti.cpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animal.cpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animal.hpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.cpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.hpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_base.cpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_base.hpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_giraffe.cpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_giraffe.hpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_mammal.cpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_mammal.hpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_reptile.cpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_reptile.hpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_snake.cpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_snake.hpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.cpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.hpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_turtle.cpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_turtle.hpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.cpp create mode 100644 Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.hpp create mode 100644 Examples/RTTI/RTTI_component/license.txt diff --git a/Examples/RTTI/RTTI.xml b/Examples/RTTI/RTTI.xml new file mode 100644 index 00000000..42008c32 --- /dev/null +++ b/Examples/RTTI/RTTI.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp new file mode 100644 index 00000000..9e3e457e --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp @@ -0,0 +1,174 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated C++-Header file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +#ifndef __RTTI_HEADER_CPP +#define __RTTI_HEADER_CPP + +#ifdef __RTTI_EXPORTS +#ifdef _WIN32 +#define RTTI_DECLSPEC __declspec (dllexport) +#else // _WIN32 +#define RTTI_DECLSPEC __attribute__((visibility("default"))) +#endif // _WIN32 +#else // __RTTI_EXPORTS +#define RTTI_DECLSPEC +#endif // __RTTI_EXPORTS + +#include "rtti_types.hpp" + + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************************************* + Class definition for Base +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Animal +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Mammal +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Reptile +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Giraffe +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Tiger +**************************************************************************************************************************/ + +/** +* Roar like a tiger +* +* @param[in] pTiger - Tiger instance. +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_tiger_roar(RTTI_Tiger pTiger); + +/************************************************************************************************************************* + Class definition for Snake +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Turtle +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for AnimalIterator +**************************************************************************************************************************/ + +/** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_animaliterator_getnextanimal(RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal); + +/************************************************************************************************************************* + Class definition for Zoo +**************************************************************************************************************************/ + +/** +* Return an iterator over all zoo animals +* +* @param[in] pZoo - Zoo instance. +* @param[out] pIterator - +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_zoo_iterator(RTTI_Zoo pZoo, RTTI_AnimalIterator * pIterator); + +/************************************************************************************************************************* + Global functions +**************************************************************************************************************************/ + +/** +* retrieves the binary version of this library. +* +* @param[out] pMajor - returns the major version of this library +* @param[out] pMinor - returns the minor version of this library +* @param[out] pMicro - returns the micro version of this library +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_getversion(RTTI_uint32 * pMajor, RTTI_uint32 * pMinor, RTTI_uint32 * pMicro); + +/** +* Returns the last error recorded on this object +* +* @param[in] pInstance - Instance Handle +* @param[in] nErrorMessageBufferSize - size of the buffer (including trailing 0) +* @param[out] pErrorMessageNeededChars - will be filled with the count of the written bytes, or needed buffer size. +* @param[out] pErrorMessageBuffer - buffer of Message of the last error, may be NULL +* @param[out] pHasError - Is there a last error to query +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_getlasterror(RTTI_Base pInstance, const RTTI_uint32 nErrorMessageBufferSize, RTTI_uint32* pErrorMessageNeededChars, char * pErrorMessageBuffer, bool * pHasError); + +/** +* Releases shared ownership of an Instance +* +* @param[in] pInstance - Instance Handle +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_releaseinstance(RTTI_Base pInstance); + +/** +* Acquires shared ownership of an Instance +* +* @param[in] pInstance - Instance Handle +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_acquireinstance(RTTI_Base pInstance); + +/** +* Injects an imported component for usage within this component +* +* @param[in] pNameSpace - NameSpace of the injected component +* @param[in] pSymbolAddressMethod - Address of the SymbolAddressMethod of the injected component +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_injectcomponent(const char * pNameSpace, RTTI_pvoid pSymbolAddressMethod); + +/** +* Returns the address of the SymbolLookupMethod +* +* @param[out] pSymbolLookupMethod - Address of the SymbolAddressMethod +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_getsymbollookupmethod(RTTI_pvoid * pSymbolLookupMethod); + +/** +* Create a new zoo with animals +* +* @param[out] pInstance - +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_createzoo(RTTI_Zoo * pInstance); + +#ifdef __cplusplus +} +#endif + +#endif // __RTTI_HEADER_CPP + diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h new file mode 100644 index 00000000..55c81793 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h @@ -0,0 +1,175 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated C++-Header file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +#ifndef __RTTI_DYNAMICHEADER_CPPTYPES +#define __RTTI_DYNAMICHEADER_CPPTYPES + +#include "rtti_types.hpp" + + + +/************************************************************************************************************************* + Class definition for Base +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Animal +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Mammal +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Reptile +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Giraffe +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Tiger +**************************************************************************************************************************/ + +/** +* Roar like a tiger +* +* @param[in] pTiger - Tiger instance. +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTITiger_RoarPtr) (RTTI_Tiger pTiger); + +/************************************************************************************************************************* + Class definition for Snake +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Turtle +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for AnimalIterator +**************************************************************************************************************************/ + +/** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIAnimalIterator_GetNextAnimalPtr) (RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal); + +/************************************************************************************************************************* + Class definition for Zoo +**************************************************************************************************************************/ + +/** +* Return an iterator over all zoo animals +* +* @param[in] pZoo - Zoo instance. +* @param[out] pIterator - +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIZoo_IteratorPtr) (RTTI_Zoo pZoo, RTTI_AnimalIterator * pIterator); + +/************************************************************************************************************************* + Global functions +**************************************************************************************************************************/ + +/** +* retrieves the binary version of this library. +* +* @param[out] pMajor - returns the major version of this library +* @param[out] pMinor - returns the minor version of this library +* @param[out] pMicro - returns the micro version of this library +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIGetVersionPtr) (RTTI_uint32 * pMajor, RTTI_uint32 * pMinor, RTTI_uint32 * pMicro); + +/** +* Returns the last error recorded on this object +* +* @param[in] pInstance - Instance Handle +* @param[in] nErrorMessageBufferSize - size of the buffer (including trailing 0) +* @param[out] pErrorMessageNeededChars - will be filled with the count of the written bytes, or needed buffer size. +* @param[out] pErrorMessageBuffer - buffer of Message of the last error, may be NULL +* @param[out] pHasError - Is there a last error to query +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIGetLastErrorPtr) (RTTI_Base pInstance, const RTTI_uint32 nErrorMessageBufferSize, RTTI_uint32* pErrorMessageNeededChars, char * pErrorMessageBuffer, bool * pHasError); + +/** +* Releases shared ownership of an Instance +* +* @param[in] pInstance - Instance Handle +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIReleaseInstancePtr) (RTTI_Base pInstance); + +/** +* Acquires shared ownership of an Instance +* +* @param[in] pInstance - Instance Handle +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIAcquireInstancePtr) (RTTI_Base pInstance); + +/** +* Injects an imported component for usage within this component +* +* @param[in] pNameSpace - NameSpace of the injected component +* @param[in] pSymbolAddressMethod - Address of the SymbolAddressMethod of the injected component +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIInjectComponentPtr) (const char * pNameSpace, RTTI_pvoid pSymbolAddressMethod); + +/** +* Returns the address of the SymbolLookupMethod +* +* @param[out] pSymbolLookupMethod - Address of the SymbolAddressMethod +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIGetSymbolLookupMethodPtr) (RTTI_pvoid * pSymbolLookupMethod); + +/** +* Create a new zoo with animals +* +* @param[out] pInstance - +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTICreateZooPtr) (RTTI_Zoo * pInstance); + +/************************************************************************************************************************* + Function Table Structure +**************************************************************************************************************************/ + +typedef struct { + void * m_LibraryHandle; + PRTTITiger_RoarPtr m_Tiger_Roar; + PRTTIAnimalIterator_GetNextAnimalPtr m_AnimalIterator_GetNextAnimal; + PRTTIZoo_IteratorPtr m_Zoo_Iterator; + PRTTIGetVersionPtr m_GetVersion; + PRTTIGetLastErrorPtr m_GetLastError; + PRTTIReleaseInstancePtr m_ReleaseInstance; + PRTTIAcquireInstancePtr m_AcquireInstance; + PRTTIInjectComponentPtr m_InjectComponent; + PRTTIGetSymbolLookupMethodPtr m_GetSymbolLookupMethod; + PRTTICreateZooPtr m_CreateZoo; +} sRTTIDynamicWrapperTable; + +#endif // __RTTI_DYNAMICHEADER_CPPTYPES + diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp new file mode 100644 index 00000000..64965c21 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp @@ -0,0 +1,885 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated C++-Header file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +#ifndef __RTTI_CPPHEADER_DYNAMIC_CPP +#define __RTTI_CPPHEADER_DYNAMIC_CPP + +#include "rtti_types.hpp" +#include "rtti_dynamic.h" + + +#ifdef _WIN32 +#include +#else // _WIN32 +#include +#endif // _WIN32 +#include +#include +#include +#include + +namespace RTTI { + +/************************************************************************************************************************* + Forward Declaration of all classes +**************************************************************************************************************************/ +class CWrapper; +class CBase; +class CAnimal; +class CMammal; +class CReptile; +class CGiraffe; +class CTiger; +class CSnake; +class CTurtle; +class CAnimalIterator; +class CZoo; + +/************************************************************************************************************************* + Declaration of deprecated class types +**************************************************************************************************************************/ +typedef CWrapper CRTTIWrapper; +typedef CBase CRTTIBase; +typedef CAnimal CRTTIAnimal; +typedef CMammal CRTTIMammal; +typedef CReptile CRTTIReptile; +typedef CGiraffe CRTTIGiraffe; +typedef CTiger CRTTITiger; +typedef CSnake CRTTISnake; +typedef CTurtle CRTTITurtle; +typedef CAnimalIterator CRTTIAnimalIterator; +typedef CZoo CRTTIZoo; + +/************************************************************************************************************************* + Declaration of shared pointer types +**************************************************************************************************************************/ +typedef std::shared_ptr PWrapper; +typedef std::shared_ptr PBase; +typedef std::shared_ptr PAnimal; +typedef std::shared_ptr PMammal; +typedef std::shared_ptr PReptile; +typedef std::shared_ptr PGiraffe; +typedef std::shared_ptr PTiger; +typedef std::shared_ptr PSnake; +typedef std::shared_ptr PTurtle; +typedef std::shared_ptr PAnimalIterator; +typedef std::shared_ptr PZoo; + +/************************************************************************************************************************* + Declaration of deprecated shared pointer types +**************************************************************************************************************************/ +typedef PWrapper PRTTIWrapper; +typedef PBase PRTTIBase; +typedef PAnimal PRTTIAnimal; +typedef PMammal PRTTIMammal; +typedef PReptile PRTTIReptile; +typedef PGiraffe PRTTIGiraffe; +typedef PTiger PRTTITiger; +typedef PSnake PRTTISnake; +typedef PTurtle PRTTITurtle; +typedef PAnimalIterator PRTTIAnimalIterator; +typedef PZoo PRTTIZoo; + + +/************************************************************************************************************************* + classParam Definition +**************************************************************************************************************************/ + +template class classParam { +private: + const T* m_ptr; + +public: + classParam(const T* ptr) + : m_ptr (ptr) + { + } + + classParam(std::shared_ptr sharedPtr) + : m_ptr (sharedPtr.get()) + { + } + + RTTIHandle GetHandle() + { + if (m_ptr != nullptr) + return m_ptr->handle(); + return nullptr; + } +}; + +/************************************************************************************************************************* + Class ERTTIException +**************************************************************************************************************************/ +class ERTTIException : public std::exception { +protected: + /** + * Error code for the Exception. + */ + RTTIResult m_errorCode; + /** + * Error message for the Exception. + */ + std::string m_errorMessage; + +public: + /** + * Exception Constructor. + */ + ERTTIException(RTTIResult errorCode, const std::string & sErrorMessage) + : m_errorMessage("RTTI Error " + std::to_string(errorCode) + " (" + sErrorMessage + ")") + { + m_errorCode = errorCode; + } + + /** + * Returns error code + */ + RTTIResult getErrorCode() const noexcept + { + return m_errorCode; + } + + /** + * Returns error message + */ + const char* what() const noexcept + { + return m_errorMessage.c_str(); + } + +}; + +/************************************************************************************************************************* + Class CInputVector +**************************************************************************************************************************/ +template +class CInputVector { +private: + + const T* m_data; + size_t m_size; + +public: + + CInputVector( const std::vector& vec) + : m_data( vec.data() ), m_size( vec.size() ) + { + } + + CInputVector( const T* in_data, size_t in_size) + : m_data( in_data ), m_size(in_size ) + { + } + + const T* data() const + { + return m_data; + } + + size_t size() const + { + return m_size; + } + +}; + +// declare deprecated class name +template +using CRTTIInputVector = CInputVector; + +/************************************************************************************************************************* + Class CWrapper +**************************************************************************************************************************/ +class CWrapper { +public: + + CWrapper(void* pSymbolLookupMethod) + { + CheckError(nullptr, initWrapperTable(&m_WrapperTable)); + CheckError(nullptr, loadWrapperTableFromSymbolLookupMethod(&m_WrapperTable, pSymbolLookupMethod)); + + CheckError(nullptr, checkBinaryVersion()); + } + + CWrapper(const std::string &sFileName) + { + CheckError(nullptr, initWrapperTable(&m_WrapperTable)); + CheckError(nullptr, loadWrapperTable(&m_WrapperTable, sFileName.c_str())); + + CheckError(nullptr, checkBinaryVersion()); + } + + static PWrapper loadLibrary(const std::string &sFileName) + { + return std::make_shared(sFileName); + } + + static PWrapper loadLibraryFromSymbolLookupMethod(void* pSymbolLookupMethod) + { + return std::make_shared(pSymbolLookupMethod); + } + + ~CWrapper() + { + releaseWrapperTable(&m_WrapperTable); + } + + inline void CheckError(CBase * pBaseClass, RTTIResult nResult); + + inline void GetVersion(RTTI_uint32 & nMajor, RTTI_uint32 & nMinor, RTTI_uint32 & nMicro); + inline bool GetLastError(classParam pInstance, std::string & sErrorMessage); + inline void ReleaseInstance(classParam pInstance); + inline void AcquireInstance(classParam pInstance); + inline void InjectComponent(const std::string & sNameSpace, const RTTI_pvoid pSymbolAddressMethod); + inline RTTI_pvoid GetSymbolLookupMethod(); + inline PZoo CreateZoo(); + +private: + sRTTIDynamicWrapperTable m_WrapperTable; + + RTTIResult checkBinaryVersion() + { + RTTI_uint32 nMajor, nMinor, nMicro; + GetVersion(nMajor, nMinor, nMicro); + if ( (nMajor != RTTI_VERSION_MAJOR) || (nMinor < RTTI_VERSION_MINOR) ) { + return RTTI_ERROR_INCOMPATIBLEBINARYVERSION; + } + return RTTI_SUCCESS; + } + RTTIResult initWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable); + RTTIResult releaseWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable); + RTTIResult loadWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable, const char * pLibraryFileName); + RTTIResult loadWrapperTableFromSymbolLookupMethod(sRTTIDynamicWrapperTable * pWrapperTable, void* pSymbolLookupMethod); + + friend class CBase; + friend class CAnimal; + friend class CMammal; + friend class CReptile; + friend class CGiraffe; + friend class CTiger; + friend class CSnake; + friend class CTurtle; + friend class CAnimalIterator; + friend class CZoo; + +}; + + +/************************************************************************************************************************* + Class CBase +**************************************************************************************************************************/ +class CBase { +public: + +protected: + /* Wrapper Object that created the class. */ + CWrapper * m_pWrapper; + /* Handle to Instance in library*/ + RTTIHandle m_pHandle; + + /* Checks for an Error code and raises Exceptions */ + void CheckError(RTTIResult nResult) + { + if (m_pWrapper != nullptr) + m_pWrapper->CheckError(this, nResult); + } +public: + /** + * CBase::CBase - Constructor for Base class. + */ + CBase(CWrapper * pWrapper, RTTIHandle pHandle) + : m_pWrapper(pWrapper), m_pHandle(pHandle) + { + } + + /** + * CBase::~CBase - Destructor for Base class. + */ + virtual ~CBase() + { + if (m_pWrapper != nullptr) + m_pWrapper->ReleaseInstance(this); + m_pWrapper = nullptr; + } + + /** + * CBase::handle - Returns handle to instance. + */ + RTTIHandle handle() const + { + return m_pHandle; + } + + /** + * CBase::wrapper - Returns wrapper instance. + */ + CWrapper * wrapper() const + { + return m_pWrapper; + } + + friend class CWrapper; +}; + +/************************************************************************************************************************* + Class CAnimal +**************************************************************************************************************************/ +class CAnimal : public CBase { +public: + + /** + * CAnimal::CAnimal - Constructor for Animal class. + */ + CAnimal(CWrapper* pWrapper, RTTIHandle pHandle) + : CBase(pWrapper, pHandle) + { + } + +}; + +/************************************************************************************************************************* + Class CMammal +**************************************************************************************************************************/ +class CMammal : public CAnimal { +public: + + /** + * CMammal::CMammal - Constructor for Mammal class. + */ + CMammal(CWrapper* pWrapper, RTTIHandle pHandle) + : CAnimal(pWrapper, pHandle) + { + } + +}; + +/************************************************************************************************************************* + Class CReptile +**************************************************************************************************************************/ +class CReptile : public CAnimal { +public: + + /** + * CReptile::CReptile - Constructor for Reptile class. + */ + CReptile(CWrapper* pWrapper, RTTIHandle pHandle) + : CAnimal(pWrapper, pHandle) + { + } + +}; + +/************************************************************************************************************************* + Class CGiraffe +**************************************************************************************************************************/ +class CGiraffe : public CMammal { +public: + + /** + * CGiraffe::CGiraffe - Constructor for Giraffe class. + */ + CGiraffe(CWrapper* pWrapper, RTTIHandle pHandle) + : CMammal(pWrapper, pHandle) + { + } + +}; + +/************************************************************************************************************************* + Class CTiger +**************************************************************************************************************************/ +class CTiger : public CMammal { +public: + + /** + * CTiger::CTiger - Constructor for Tiger class. + */ + CTiger(CWrapper* pWrapper, RTTIHandle pHandle) + : CMammal(pWrapper, pHandle) + { + } + + inline void Roar(); +}; + +/************************************************************************************************************************* + Class CSnake +**************************************************************************************************************************/ +class CSnake : public CReptile { +public: + + /** + * CSnake::CSnake - Constructor for Snake class. + */ + CSnake(CWrapper* pWrapper, RTTIHandle pHandle) + : CReptile(pWrapper, pHandle) + { + } + +}; + +/************************************************************************************************************************* + Class CTurtle +**************************************************************************************************************************/ +class CTurtle : public CReptile { +public: + + /** + * CTurtle::CTurtle - Constructor for Turtle class. + */ + CTurtle(CWrapper* pWrapper, RTTIHandle pHandle) + : CReptile(pWrapper, pHandle) + { + } + +}; + +/************************************************************************************************************************* + Class CAnimalIterator +**************************************************************************************************************************/ +class CAnimalIterator : public CBase { +public: + + /** + * CAnimalIterator::CAnimalIterator - Constructor for AnimalIterator class. + */ + CAnimalIterator(CWrapper* pWrapper, RTTIHandle pHandle) + : CBase(pWrapper, pHandle) + { + } + + inline PAnimal GetNextAnimal(); +}; + +/************************************************************************************************************************* + Class CZoo +**************************************************************************************************************************/ +class CZoo : public CBase { +public: + + /** + * CZoo::CZoo - Constructor for Zoo class. + */ + CZoo(CWrapper* pWrapper, RTTIHandle pHandle) + : CBase(pWrapper, pHandle) + { + } + + inline PAnimalIterator Iterator(); +}; + + /** + * CWrapper::GetVersion - retrieves the binary version of this library. + * @param[out] nMajor - returns the major version of this library + * @param[out] nMinor - returns the minor version of this library + * @param[out] nMicro - returns the micro version of this library + */ + inline void CWrapper::GetVersion(RTTI_uint32 & nMajor, RTTI_uint32 & nMinor, RTTI_uint32 & nMicro) + { + CheckError(nullptr,m_WrapperTable.m_GetVersion(&nMajor, &nMinor, &nMicro)); + } + + /** + * CWrapper::GetLastError - Returns the last error recorded on this object + * @param[in] pInstance - Instance Handle + * @param[out] sErrorMessage - Message of the last error + * @return Is there a last error to query + */ + inline bool CWrapper::GetLastError(classParam pInstance, std::string & sErrorMessage) + { + RTTIHandle hInstance = pInstance.GetHandle(); + RTTI_uint32 bytesNeededErrorMessage = 0; + RTTI_uint32 bytesWrittenErrorMessage = 0; + bool resultHasError = 0; + CheckError(nullptr,m_WrapperTable.m_GetLastError(hInstance, 0, &bytesNeededErrorMessage, nullptr, &resultHasError)); + std::vector bufferErrorMessage(bytesNeededErrorMessage); + CheckError(nullptr,m_WrapperTable.m_GetLastError(hInstance, bytesNeededErrorMessage, &bytesWrittenErrorMessage, &bufferErrorMessage[0], &resultHasError)); + sErrorMessage = std::string(&bufferErrorMessage[0]); + + return resultHasError; + } + + /** + * CWrapper::ReleaseInstance - Releases shared ownership of an Instance + * @param[in] pInstance - Instance Handle + */ + inline void CWrapper::ReleaseInstance(classParam pInstance) + { + RTTIHandle hInstance = pInstance.GetHandle(); + CheckError(nullptr,m_WrapperTable.m_ReleaseInstance(hInstance)); + } + + /** + * CWrapper::AcquireInstance - Acquires shared ownership of an Instance + * @param[in] pInstance - Instance Handle + */ + inline void CWrapper::AcquireInstance(classParam pInstance) + { + RTTIHandle hInstance = pInstance.GetHandle(); + CheckError(nullptr,m_WrapperTable.m_AcquireInstance(hInstance)); + } + + /** + * CWrapper::InjectComponent - Injects an imported component for usage within this component + * @param[in] sNameSpace - NameSpace of the injected component + * @param[in] pSymbolAddressMethod - Address of the SymbolAddressMethod of the injected component + */ + inline void CWrapper::InjectComponent(const std::string & sNameSpace, const RTTI_pvoid pSymbolAddressMethod) + { + CheckError(nullptr,m_WrapperTable.m_InjectComponent(sNameSpace.c_str(), pSymbolAddressMethod)); + + bool bNameSpaceFound = false; + if (!bNameSpaceFound) + throw ERTTIException(RTTI_ERROR_COULDNOTLOADLIBRARY, "Unknown namespace " + sNameSpace); + } + + /** + * CWrapper::GetSymbolLookupMethod - Returns the address of the SymbolLookupMethod + * @return Address of the SymbolAddressMethod + */ + inline RTTI_pvoid CWrapper::GetSymbolLookupMethod() + { + RTTI_pvoid resultSymbolLookupMethod = 0; + CheckError(nullptr,m_WrapperTable.m_GetSymbolLookupMethod(&resultSymbolLookupMethod)); + + return resultSymbolLookupMethod; + } + + /** + * CWrapper::CreateZoo - Create a new zoo with animals + * @return + */ + inline PZoo CWrapper::CreateZoo() + { + RTTIHandle hInstance = nullptr; + CheckError(nullptr,m_WrapperTable.m_CreateZoo(&hInstance)); + + if (!hInstance) { + CheckError(nullptr,RTTI_ERROR_INVALIDPARAM); + } + return std::make_shared(this, hInstance); + } + + inline void CWrapper::CheckError(CBase * pBaseClass, RTTIResult nResult) + { + if (nResult != 0) { + std::string sErrorMessage; + if (pBaseClass != nullptr) { + GetLastError(pBaseClass, sErrorMessage); + } + throw ERTTIException(nResult, sErrorMessage); + } + } + + + inline RTTIResult CWrapper::initWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable) + { + if (pWrapperTable == nullptr) + return RTTI_ERROR_INVALIDPARAM; + + pWrapperTable->m_LibraryHandle = nullptr; + pWrapperTable->m_Tiger_Roar = nullptr; + pWrapperTable->m_AnimalIterator_GetNextAnimal = nullptr; + pWrapperTable->m_Zoo_Iterator = nullptr; + pWrapperTable->m_GetVersion = nullptr; + pWrapperTable->m_GetLastError = nullptr; + pWrapperTable->m_ReleaseInstance = nullptr; + pWrapperTable->m_AcquireInstance = nullptr; + pWrapperTable->m_InjectComponent = nullptr; + pWrapperTable->m_GetSymbolLookupMethod = nullptr; + pWrapperTable->m_CreateZoo = nullptr; + + return RTTI_SUCCESS; + } + + inline RTTIResult CWrapper::releaseWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable) + { + if (pWrapperTable == nullptr) + return RTTI_ERROR_INVALIDPARAM; + + if (pWrapperTable->m_LibraryHandle != nullptr) { + #ifdef _WIN32 + HMODULE hModule = (HMODULE) pWrapperTable->m_LibraryHandle; + FreeLibrary(hModule); + #else // _WIN32 + dlclose(pWrapperTable->m_LibraryHandle); + #endif // _WIN32 + return initWrapperTable(pWrapperTable); + } + + return RTTI_SUCCESS; + } + + inline RTTIResult CWrapper::loadWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable, const char * pLibraryFileName) + { + if (pWrapperTable == nullptr) + return RTTI_ERROR_INVALIDPARAM; + if (pLibraryFileName == nullptr) + return RTTI_ERROR_INVALIDPARAM; + + #ifdef _WIN32 + // Convert filename to UTF16-string + int nLength = (int)strlen(pLibraryFileName); + int nBufferSize = nLength * 2 + 2; + std::vector wsLibraryFileName(nBufferSize); + int nResult = MultiByteToWideChar(CP_UTF8, 0, pLibraryFileName, nLength, &wsLibraryFileName[0], nBufferSize); + if (nResult == 0) + return RTTI_ERROR_COULDNOTLOADLIBRARY; + + HMODULE hLibrary = LoadLibraryW(wsLibraryFileName.data()); + if (hLibrary == 0) + return RTTI_ERROR_COULDNOTLOADLIBRARY; + #else // _WIN32 + void* hLibrary = dlopen(pLibraryFileName, RTLD_LAZY); + if (hLibrary == 0) + return RTTI_ERROR_COULDNOTLOADLIBRARY; + dlerror(); + #endif // _WIN32 + + #ifdef _WIN32 + pWrapperTable->m_Tiger_Roar = (PRTTITiger_RoarPtr) GetProcAddress(hLibrary, "rtti_tiger_roar"); + #else // _WIN32 + pWrapperTable->m_Tiger_Roar = (PRTTITiger_RoarPtr) dlsym(hLibrary, "rtti_tiger_roar"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_Tiger_Roar == nullptr) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_AnimalIterator_GetNextAnimal = (PRTTIAnimalIterator_GetNextAnimalPtr) GetProcAddress(hLibrary, "rtti_animaliterator_getnextanimal"); + #else // _WIN32 + pWrapperTable->m_AnimalIterator_GetNextAnimal = (PRTTIAnimalIterator_GetNextAnimalPtr) dlsym(hLibrary, "rtti_animaliterator_getnextanimal"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_AnimalIterator_GetNextAnimal == nullptr) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_Zoo_Iterator = (PRTTIZoo_IteratorPtr) GetProcAddress(hLibrary, "rtti_zoo_iterator"); + #else // _WIN32 + pWrapperTable->m_Zoo_Iterator = (PRTTIZoo_IteratorPtr) dlsym(hLibrary, "rtti_zoo_iterator"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_Zoo_Iterator == nullptr) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_GetVersion = (PRTTIGetVersionPtr) GetProcAddress(hLibrary, "rtti_getversion"); + #else // _WIN32 + pWrapperTable->m_GetVersion = (PRTTIGetVersionPtr) dlsym(hLibrary, "rtti_getversion"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_GetVersion == nullptr) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_GetLastError = (PRTTIGetLastErrorPtr) GetProcAddress(hLibrary, "rtti_getlasterror"); + #else // _WIN32 + pWrapperTable->m_GetLastError = (PRTTIGetLastErrorPtr) dlsym(hLibrary, "rtti_getlasterror"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_GetLastError == nullptr) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_ReleaseInstance = (PRTTIReleaseInstancePtr) GetProcAddress(hLibrary, "rtti_releaseinstance"); + #else // _WIN32 + pWrapperTable->m_ReleaseInstance = (PRTTIReleaseInstancePtr) dlsym(hLibrary, "rtti_releaseinstance"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_ReleaseInstance == nullptr) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_AcquireInstance = (PRTTIAcquireInstancePtr) GetProcAddress(hLibrary, "rtti_acquireinstance"); + #else // _WIN32 + pWrapperTable->m_AcquireInstance = (PRTTIAcquireInstancePtr) dlsym(hLibrary, "rtti_acquireinstance"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_AcquireInstance == nullptr) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_InjectComponent = (PRTTIInjectComponentPtr) GetProcAddress(hLibrary, "rtti_injectcomponent"); + #else // _WIN32 + pWrapperTable->m_InjectComponent = (PRTTIInjectComponentPtr) dlsym(hLibrary, "rtti_injectcomponent"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_InjectComponent == nullptr) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_GetSymbolLookupMethod = (PRTTIGetSymbolLookupMethodPtr) GetProcAddress(hLibrary, "rtti_getsymbollookupmethod"); + #else // _WIN32 + pWrapperTable->m_GetSymbolLookupMethod = (PRTTIGetSymbolLookupMethodPtr) dlsym(hLibrary, "rtti_getsymbollookupmethod"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_GetSymbolLookupMethod == nullptr) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_CreateZoo = (PRTTICreateZooPtr) GetProcAddress(hLibrary, "rtti_createzoo"); + #else // _WIN32 + pWrapperTable->m_CreateZoo = (PRTTICreateZooPtr) dlsym(hLibrary, "rtti_createzoo"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_CreateZoo == nullptr) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + pWrapperTable->m_LibraryHandle = hLibrary; + return RTTI_SUCCESS; + } + + inline RTTIResult CWrapper::loadWrapperTableFromSymbolLookupMethod(sRTTIDynamicWrapperTable * pWrapperTable, void* pSymbolLookupMethod) +{ + if (pWrapperTable == nullptr) + return RTTI_ERROR_INVALIDPARAM; + if (pSymbolLookupMethod == nullptr) + return RTTI_ERROR_INVALIDPARAM; + + typedef RTTIResult(*SymbolLookupType)(const char*, void**); + + SymbolLookupType pLookup = (SymbolLookupType)pSymbolLookupMethod; + + RTTIResult eLookupError = RTTI_SUCCESS; + eLookupError = (*pLookup)("rtti_tiger_roar", (void**)&(pWrapperTable->m_Tiger_Roar)); + if ( (eLookupError != 0) || (pWrapperTable->m_Tiger_Roar == nullptr) ) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + eLookupError = (*pLookup)("rtti_animaliterator_getnextanimal", (void**)&(pWrapperTable->m_AnimalIterator_GetNextAnimal)); + if ( (eLookupError != 0) || (pWrapperTable->m_AnimalIterator_GetNextAnimal == nullptr) ) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + eLookupError = (*pLookup)("rtti_zoo_iterator", (void**)&(pWrapperTable->m_Zoo_Iterator)); + if ( (eLookupError != 0) || (pWrapperTable->m_Zoo_Iterator == nullptr) ) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + eLookupError = (*pLookup)("rtti_getversion", (void**)&(pWrapperTable->m_GetVersion)); + if ( (eLookupError != 0) || (pWrapperTable->m_GetVersion == nullptr) ) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + eLookupError = (*pLookup)("rtti_getlasterror", (void**)&(pWrapperTable->m_GetLastError)); + if ( (eLookupError != 0) || (pWrapperTable->m_GetLastError == nullptr) ) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + eLookupError = (*pLookup)("rtti_releaseinstance", (void**)&(pWrapperTable->m_ReleaseInstance)); + if ( (eLookupError != 0) || (pWrapperTable->m_ReleaseInstance == nullptr) ) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + eLookupError = (*pLookup)("rtti_acquireinstance", (void**)&(pWrapperTable->m_AcquireInstance)); + if ( (eLookupError != 0) || (pWrapperTable->m_AcquireInstance == nullptr) ) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + eLookupError = (*pLookup)("rtti_injectcomponent", (void**)&(pWrapperTable->m_InjectComponent)); + if ( (eLookupError != 0) || (pWrapperTable->m_InjectComponent == nullptr) ) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + eLookupError = (*pLookup)("rtti_getsymbollookupmethod", (void**)&(pWrapperTable->m_GetSymbolLookupMethod)); + if ( (eLookupError != 0) || (pWrapperTable->m_GetSymbolLookupMethod == nullptr) ) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + eLookupError = (*pLookup)("rtti_createzoo", (void**)&(pWrapperTable->m_CreateZoo)); + if ( (eLookupError != 0) || (pWrapperTable->m_CreateZoo == nullptr) ) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + return RTTI_SUCCESS; +} + + + + /** + * Method definitions for class CBase + */ + + /** + * Method definitions for class CAnimal + */ + + /** + * Method definitions for class CMammal + */ + + /** + * Method definitions for class CReptile + */ + + /** + * Method definitions for class CGiraffe + */ + + /** + * Method definitions for class CTiger + */ + + /** + * CTiger::Roar - Roar like a tiger + */ + void CTiger::Roar() + { + CheckError(m_pWrapper->m_WrapperTable.m_Tiger_Roar(m_pHandle)); + } + + /** + * Method definitions for class CSnake + */ + + /** + * Method definitions for class CTurtle + */ + + /** + * Method definitions for class CAnimalIterator + */ + + /** + * CAnimalIterator::GetNextAnimal - Return next animal + * @return + */ + PAnimal CAnimalIterator::GetNextAnimal() + { + RTTIHandle hAnimal = nullptr; + CheckError(m_pWrapper->m_WrapperTable.m_AnimalIterator_GetNextAnimal(m_pHandle, &hAnimal)); + + if (hAnimal) { + return std::make_shared(m_pWrapper, hAnimal); + } else { + return nullptr; + } + } + + /** + * Method definitions for class CZoo + */ + + /** + * CZoo::Iterator - Return an iterator over all zoo animals + * @return + */ + PAnimalIterator CZoo::Iterator() + { + RTTIHandle hIterator = nullptr; + CheckError(m_pWrapper->m_WrapperTable.m_Zoo_Iterator(m_pHandle, &hIterator)); + + if (!hIterator) { + CheckError(RTTI_ERROR_INVALIDPARAM); + } + return std::make_shared(m_pWrapper, hIterator); + } + +} // namespace RTTI + +#endif // __RTTI_CPPHEADER_DYNAMIC_CPP + diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_types.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_types.hpp new file mode 100644 index 00000000..19fec9a2 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_types.hpp @@ -0,0 +1,125 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated C++-Header file with basic types in +order to allow an easy use of RTTI + +Interface version: 1.0.0 + +*/ + +#ifndef __RTTI_TYPES_HEADER_CPP +#define __RTTI_TYPES_HEADER_CPP + + +/************************************************************************************************************************* + Scalar types definition +**************************************************************************************************************************/ + +#ifdef RTTI_USELEGACYINTEGERTYPES + +typedef unsigned char RTTI_uint8; +typedef unsigned short RTTI_uint16 ; +typedef unsigned int RTTI_uint32; +typedef unsigned long long RTTI_uint64; +typedef char RTTI_int8; +typedef short RTTI_int16; +typedef int RTTI_int32; +typedef long long RTTI_int64; + +#else // RTTI_USELEGACYINTEGERTYPES + +#include + +typedef uint8_t RTTI_uint8; +typedef uint16_t RTTI_uint16; +typedef uint32_t RTTI_uint32; +typedef uint64_t RTTI_uint64; +typedef int8_t RTTI_int8; +typedef int16_t RTTI_int16; +typedef int32_t RTTI_int32; +typedef int64_t RTTI_int64 ; + +#endif // RTTI_USELEGACYINTEGERTYPES + +typedef float RTTI_single; +typedef double RTTI_double; + +/************************************************************************************************************************* + General type definitions +**************************************************************************************************************************/ + +typedef RTTI_int32 RTTIResult; +typedef void * RTTIHandle; +typedef void * RTTI_pvoid; + +/************************************************************************************************************************* + Version for RTTI +**************************************************************************************************************************/ + +#define RTTI_VERSION_MAJOR 1 +#define RTTI_VERSION_MINOR 0 +#define RTTI_VERSION_MICRO 0 +#define RTTI_VERSION_PRERELEASEINFO "" +#define RTTI_VERSION_BUILDINFO "" + +/************************************************************************************************************************* + Error constants for RTTI +**************************************************************************************************************************/ + +#define RTTI_SUCCESS 0 +#define RTTI_ERROR_NOTIMPLEMENTED 1 +#define RTTI_ERROR_INVALIDPARAM 2 +#define RTTI_ERROR_INVALIDCAST 3 +#define RTTI_ERROR_BUFFERTOOSMALL 4 +#define RTTI_ERROR_GENERICEXCEPTION 5 +#define RTTI_ERROR_COULDNOTLOADLIBRARY 6 +#define RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT 7 +#define RTTI_ERROR_INCOMPATIBLEBINARYVERSION 8 + +/************************************************************************************************************************* + Error strings for RTTI +**************************************************************************************************************************/ + +inline const char * RTTI_GETERRORSTRING (RTTIResult nErrorCode) { + switch (nErrorCode) { + case RTTI_SUCCESS: return "no error"; + case RTTI_ERROR_NOTIMPLEMENTED: return "functionality not implemented"; + case RTTI_ERROR_INVALIDPARAM: return "an invalid parameter was passed"; + case RTTI_ERROR_INVALIDCAST: return "a type cast failed"; + case RTTI_ERROR_BUFFERTOOSMALL: return "a provided buffer is too small"; + case RTTI_ERROR_GENERICEXCEPTION: return "a generic exception occurred"; + case RTTI_ERROR_COULDNOTLOADLIBRARY: return "the library could not be loaded"; + case RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT: return "a required exported symbol could not be found in the library"; + case RTTI_ERROR_INCOMPATIBLEBINARYVERSION: return "the version of the binary interface does not match the bindings interface"; + default: return "unknown error"; + } +} + +/************************************************************************************************************************* + Declaration of handle classes +**************************************************************************************************************************/ + +typedef RTTIHandle RTTI_Base; +typedef RTTIHandle RTTI_Animal; +typedef RTTIHandle RTTI_Mammal; +typedef RTTIHandle RTTI_Reptile; +typedef RTTIHandle RTTI_Giraffe; +typedef RTTIHandle RTTI_Tiger; +typedef RTTIHandle RTTI_Snake; +typedef RTTIHandle RTTI_Turtle; +typedef RTTIHandle RTTI_AnimalIterator; +typedef RTTIHandle RTTI_Zoo; + +namespace RTTI { + +} // namespace RTTI; + +// define legacy C-names for enums, structs and function types + +#endif // __RTTI_TYPES_HEADER_CPP diff --git a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py new file mode 100644 index 00000000..ddd1f9fc --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py @@ -0,0 +1,392 @@ +'''++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Python file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +''' + + +import ctypes +import platform +import enum +import os + +name = "rtti" + +'''Definition of domain specific exception +''' +class ERTTIException(Exception): + def __init__(self, code, message = ''): + self._code = code + self._message = message + + def __str__(self): + if self._message: + return 'RTTIException ' + str(self._code) + ': '+ str(self._message) + return 'RTTIException ' + str(self._code) + +'''Definition of binding API version +''' +class BindingVersion(enum.IntEnum): + MAJOR = 1 + MINOR = 0 + MICRO = 0 + +'''Definition Error Codes +''' +class ErrorCodes(enum.IntEnum): + SUCCESS = 0 + NOTIMPLEMENTED = 1 + INVALIDPARAM = 2 + INVALIDCAST = 3 + BUFFERTOOSMALL = 4 + GENERICEXCEPTION = 5 + COULDNOTLOADLIBRARY = 6 + COULDNOTFINDLIBRARYEXPORT = 7 + INCOMPATIBLEBINARYVERSION = 8 + +'''Definition of Function Table +''' +class FunctionTable: + rtti_getversion = None + rtti_getlasterror = None + rtti_releaseinstance = None + rtti_acquireinstance = None + rtti_injectcomponent = None + rtti_getsymbollookupmethod = None + rtti_createzoo = None + rtti_tiger_roar = None + rtti_animaliterator_getnextanimal = None + rtti_zoo_iterator = None + + +'''Wrapper Class Implementation +''' +class Wrapper: + + def __init__(self, libraryName = None, symbolLookupMethodAddress = None): + ending = '' + if platform.system() == 'Windows': + ending = 'dll' + elif platform.system() == 'Linux': + ending = 'so' + elif platform.system() == 'Darwin': + ending = 'dylib' + else: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY) + + if (not libraryName) and (not symbolLookupMethodAddress): + libraryName = os.path.join(os.path.dirname(os.path.realpath(__file__)),'rtti') + + if libraryName is not None: + path = libraryName + '.' + ending + try: + self.lib = ctypes.CDLL(path) + except Exception as e: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(e) + '| "'+path + '"' ) + + self._loadFunctionTable() + elif symbolLookupMethodAddress is not None: + self.lib = FunctionTable() + self._loadFunctionTableFromMethod(symbolLookupMethodAddress) + else: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(e)) + + self._checkBinaryVersion() + + def _loadFunctionTableFromMethod(self, symbolLookupMethodAddress): + try: + symbolLookupMethodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_char_p, ctypes.POINTER(ctypes.c_void_p)) + symbolLookupMethod = symbolLookupMethodType(int(symbolLookupMethodAddress)) + + methodAddress = ctypes.c_void_p() + + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_getversion")), methodAddress) + if err != 0: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32)) + self.lib.rtti_getversion = methodType(int(methodAddress.value)) + + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_getlasterror")), methodAddress) + if err != 0: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.c_uint64, ctypes.POINTER(ctypes.c_uint64), ctypes.c_char_p, ctypes.POINTER(ctypes.c_bool)) + self.lib.rtti_getlasterror = methodType(int(methodAddress.value)) + + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_releaseinstance")), methodAddress) + if err != 0: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p) + self.lib.rtti_releaseinstance = methodType(int(methodAddress.value)) + + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_acquireinstance")), methodAddress) + if err != 0: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p) + self.lib.rtti_acquireinstance = methodType(int(methodAddress.value)) + + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_injectcomponent")), methodAddress) + if err != 0: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_char_p, ctypes.c_void_p) + self.lib.rtti_injectcomponent = methodType(int(methodAddress.value)) + + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_getsymbollookupmethod")), methodAddress) + if err != 0: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.POINTER(ctypes.c_void_p)) + self.lib.rtti_getsymbollookupmethod = methodType(int(methodAddress.value)) + + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_createzoo")), methodAddress) + if err != 0: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.POINTER(ctypes.c_void_p)) + self.lib.rtti_createzoo = methodType(int(methodAddress.value)) + + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_tiger_roar")), methodAddress) + if err != 0: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p) + self.lib.rtti_tiger_roar = methodType(int(methodAddress.value)) + + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_animaliterator_getnextanimal")), methodAddress) + if err != 0: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p)) + self.lib.rtti_animaliterator_getnextanimal = methodType(int(methodAddress.value)) + + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_zoo_iterator")), methodAddress) + if err != 0: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p)) + self.lib.rtti_zoo_iterator = methodType(int(methodAddress.value)) + + except AttributeError as ae: + raise ERTTIException(ErrorCodes.COULDNOTFINDLIBRARYEXPORT, ae.args[0]) + + def _loadFunctionTable(self): + try: + self.lib.rtti_getversion.restype = ctypes.c_int32 + self.lib.rtti_getversion.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32)] + + self.lib.rtti_getlasterror.restype = ctypes.c_int32 + self.lib.rtti_getlasterror.argtypes = [ctypes.c_void_p, ctypes.c_uint64, ctypes.POINTER(ctypes.c_uint64), ctypes.c_char_p, ctypes.POINTER(ctypes.c_bool)] + + self.lib.rtti_releaseinstance.restype = ctypes.c_int32 + self.lib.rtti_releaseinstance.argtypes = [ctypes.c_void_p] + + self.lib.rtti_acquireinstance.restype = ctypes.c_int32 + self.lib.rtti_acquireinstance.argtypes = [ctypes.c_void_p] + + self.lib.rtti_injectcomponent.restype = ctypes.c_int32 + self.lib.rtti_injectcomponent.argtypes = [ctypes.c_char_p, ctypes.c_void_p] + + self.lib.rtti_getsymbollookupmethod.restype = ctypes.c_int32 + self.lib.rtti_getsymbollookupmethod.argtypes = [ctypes.POINTER(ctypes.c_void_p)] + + self.lib.rtti_createzoo.restype = ctypes.c_int32 + self.lib.rtti_createzoo.argtypes = [ctypes.POINTER(ctypes.c_void_p)] + + self.lib.rtti_tiger_roar.restype = ctypes.c_int32 + self.lib.rtti_tiger_roar.argtypes = [ctypes.c_void_p] + + self.lib.rtti_animaliterator_getnextanimal.restype = ctypes.c_int32 + self.lib.rtti_animaliterator_getnextanimal.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p)] + + self.lib.rtti_zoo_iterator.restype = ctypes.c_int32 + self.lib.rtti_zoo_iterator.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p)] + + except AttributeError as ae: + raise ERTTIException(ErrorCodes.COULDNOTFINDLIBRARYEXPORT, ae.args[0]) + + def _checkBinaryVersion(self): + nMajor, nMinor, _ = self.GetVersion() + if (nMajor != BindingVersion.MAJOR) or (nMinor < BindingVersion.MINOR): + raise ERTTIException(ErrorCodes.INCOMPATIBLEBINARYVERSION) + + def checkError(self, instance, errorCode): + if errorCode != ErrorCodes.SUCCESS.value: + if instance: + if instance._wrapper != self: + raise ERTTIException(ErrorCodes.INVALIDCAST, 'invalid wrapper call') + message,_ = self.GetLastError(instance) + raise ERTTIException(errorCode, message) + + def GetVersion(self): + pMajor = ctypes.c_uint32() + pMinor = ctypes.c_uint32() + pMicro = ctypes.c_uint32() + self.checkError(None, self.lib.rtti_getversion(pMajor, pMinor, pMicro)) + + return pMajor.value, pMinor.value, pMicro.value + + def GetLastError(self, InstanceObject): + InstanceHandle = None + if InstanceObject: + InstanceHandle = InstanceObject._handle + else: + raise ERTTIException(ErrorCodes.INVALIDPARAM, 'Invalid return/output value') + nErrorMessageBufferSize = ctypes.c_uint64(0) + nErrorMessageNeededChars = ctypes.c_uint64(0) + pErrorMessageBuffer = ctypes.c_char_p(None) + pHasError = ctypes.c_bool() + self.checkError(None, self.lib.rtti_getlasterror(InstanceHandle, nErrorMessageBufferSize, nErrorMessageNeededChars, pErrorMessageBuffer, pHasError)) + nErrorMessageBufferSize = ctypes.c_uint64(nErrorMessageNeededChars.value) + pErrorMessageBuffer = (ctypes.c_char * (nErrorMessageNeededChars.value))() + self.checkError(None, self.lib.rtti_getlasterror(InstanceHandle, nErrorMessageBufferSize, nErrorMessageNeededChars, pErrorMessageBuffer, pHasError)) + + return pErrorMessageBuffer.value.decode(), pHasError.value + + def ReleaseInstance(self, InstanceObject): + InstanceHandle = None + if InstanceObject: + InstanceHandle = InstanceObject._handle + else: + raise ERTTIException(ErrorCodes.INVALIDPARAM, 'Invalid return/output value') + self.checkError(None, self.lib.rtti_releaseinstance(InstanceHandle)) + + + def AcquireInstance(self, InstanceObject): + InstanceHandle = None + if InstanceObject: + InstanceHandle = InstanceObject._handle + else: + raise ERTTIException(ErrorCodes.INVALIDPARAM, 'Invalid return/output value') + self.checkError(None, self.lib.rtti_acquireinstance(InstanceHandle)) + + + def InjectComponent(self, NameSpace, SymbolAddressMethod): + pNameSpace = ctypes.c_char_p(str.encode(NameSpace)) + pSymbolAddressMethod = ctypes.c_void_p(SymbolAddressMethod) + self.checkError(None, self.lib.rtti_injectcomponent(pNameSpace, pSymbolAddressMethod)) + + bNameSpaceFound = False + if not bNameSpaceFound: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, "Unknown namespace " + NameSpace) + + + def GetSymbolLookupMethod(self): + pSymbolLookupMethod = ctypes.c_void_p() + self.checkError(None, self.lib.rtti_getsymbollookupmethod(pSymbolLookupMethod)) + + return pSymbolLookupMethod.value + + def CreateZoo(self): + InstanceHandle = ctypes.c_void_p() + self.checkError(None, self.lib.rtti_createzoo(InstanceHandle)) + if InstanceHandle: + InstanceObject = Zoo(InstanceHandle, self) + else: + raise ERTTIException(ErrorCodes.INVALIDCAST, 'Invalid return/output value') + + return InstanceObject + + + +''' Class Implementation for Base +''' +class Base: + def __init__(self, handle, wrapper): + if not handle or not wrapper: + raise ERTTIException(ErrorCodes.INVALIDPARAM) + self._handle = handle + self._wrapper = wrapper + + def __del__(self): + self._wrapper.ReleaseInstance(self) + + +''' Class Implementation for Animal +''' +class Animal(Base): + def __init__(self, handle, wrapper): + Base.__init__(self, handle, wrapper) + + +''' Class Implementation for Mammal +''' +class Mammal(Animal): + def __init__(self, handle, wrapper): + Animal.__init__(self, handle, wrapper) + + +''' Class Implementation for Reptile +''' +class Reptile(Animal): + def __init__(self, handle, wrapper): + Animal.__init__(self, handle, wrapper) + + +''' Class Implementation for Giraffe +''' +class Giraffe(Mammal): + def __init__(self, handle, wrapper): + Mammal.__init__(self, handle, wrapper) + + +''' Class Implementation for Tiger +''' +class Tiger(Mammal): + def __init__(self, handle, wrapper): + Mammal.__init__(self, handle, wrapper) + def Roar(self): + self._wrapper.checkError(self, self._wrapper.lib.rtti_tiger_roar(self._handle)) + + + + +''' Class Implementation for Snake +''' +class Snake(Reptile): + def __init__(self, handle, wrapper): + Reptile.__init__(self, handle, wrapper) + + +''' Class Implementation for Turtle +''' +class Turtle(Reptile): + def __init__(self, handle, wrapper): + Reptile.__init__(self, handle, wrapper) + + +''' Class Implementation for AnimalIterator +''' +class AnimalIterator(Base): + def __init__(self, handle, wrapper): + Base.__init__(self, handle, wrapper) + def GetNextAnimal(self): + AnimalHandle = ctypes.c_void_p() + self._wrapper.checkError(self, self._wrapper.lib.rtti_animaliterator_getnextanimal(self._handle, AnimalHandle)) + if AnimalHandle: + AnimalObject = Animal(AnimalHandle, self._wrapper) + else: + AnimalObject = None + + return AnimalObject + + + +''' Class Implementation for Zoo +''' +class Zoo(Base): + def __init__(self, handle, wrapper): + Base.__init__(self, handle, wrapper) + def Iterator(self): + IteratorHandle = ctypes.c_void_p() + self._wrapper.checkError(self, self._wrapper.lib.rtti_zoo_iterator(self._handle, IteratorHandle)) + if IteratorHandle: + IteratorObject = AnimalIterator(IteratorHandle, self._wrapper) + else: + raise ERTTIException(ErrorCodes.INVALIDCAST, 'Invalid return/output value') + + return IteratorObject + + diff --git a/Examples/RTTI/RTTI_component/Bindings/Python/__pycache__/RTTI.cpython-38.pyc b/Examples/RTTI/RTTI_component/Bindings/Python/__pycache__/RTTI.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..00cb7ea83cd56eaa6d70601d73333f4b2cf1e16a GIT binary patch literal 11311 zcmb_i%X1q?dY>17!4Lq!he(N{ZAiOu1lcCFj#ryfc^yFzDZ?f~g`{kG${Toy8Bzej z0o*f?Lnq6l4MY#p+qyMP%?EY=~IAG zW*Sf$Pzq4SoCY)vC=DoU&H$RR(!iAgJZsJYp0hH5rvcBKR{&q(a2D`_xd?dCnnwK$ z;H%~}z}GlD3wX)A4*0s2Mg1J$W%C`t?{Ih?@Vn-FfZyZeT>+dkZvei*;RRFL5%M<; z2@Lw+15GP7TgR++@XXEKD&}(^-}(4XuJCZ@OHC^@8aZC!hF zHLTn-!^!PgmYqAWY>OGLW#;ydbM7-MS7^JVgP{yNX8>J)jK|0BGxX$BsM)zD zGcA^Ln>nM=XuhE4mf;+0xwd2Fn)|u!-QAL=m2B5y`$p9Y2fl}q@2uR>v^S(YWlv!) zrc2+^M+R^o$$1x?w}b*!L7(o(PIx3v3EF zemq)z0?9b5`&P{{8pg9D!(0V7SHa|u_8lKydubfC8kVz4)8iS&2*k45tMu8ry0Sul z4{Ekqvk#orpp<&9w2m>YO3kjhmCALZf^1C?<6>uVkn)wVRTV1Md+3{(z!`7{A6=m? zu$!jnf)RD;R9qBHX;I*iK+q0sw_gVq%jHgHfW^6vbT5~eSpwKR8Jff5_Xpk;(IB<-Ev&({?jTECCPd83L7evHZ{ z&ys{VGE2BqQ_WN)I0w zwhNoyQ~(tVJG*-3!ISlM$b4&SXS1-ep=TehmDjdQ#kHr!wa2@qt+F>)+2-+0%;!u3))EL?l~cx!vtyH+X}w>BRac1sU7)*h6~X#UmO_6|^uWi$!* zBP54}9sU^APi8t6y+NjnPz@1G7r}H9Oc%j)5lk1sbP-G!^^_@s@sgKbZ`)OJ zO}oZk!z$;~!|a?UFIYLS+`v71Ghso)aNt29HgBF6F{=SLYt?MWHSDStlp59V+ch>^ zTC?j`)$O?)Zz)9T93Sm9;kBEG?beY6uWou7URPxnmXl7i>G?BqYX=squ%^Mh8@z#G z*N%)v4O24QCZieK)=SKUN`pzGcO`5vRt%);_mCV?@=-BB`>Dl9s^Qkg- z=6d35tZdB}4qR%Zp~p6AcKf9+IZZwO&|oiWHUxIusO>TGMxMCRk-NE@KZ-Z=^Pbvj z818$I(%r3JvIIjhW1MC{3EHTi}(PE zR9eA12KAFqq^{(~yW%N+T-jsiP`xg-k=?`@d>|=lS2>kVV%-?bKxW^$P~G~Jn;^9# z73t&VcvI(8LL&@(ohv8tZX9DN^)!u!XeCpbj*KLajP%>dBh_QTpAE*z(uh5}W`HL? zW~|xBSTL$Vs$Plg&o3GcMmjqCxd=w$<^Z37@o)cVjPntU@i7?x{Q``T8DuJtndg-V z*2D-_iG4g7Yfn?g(Z3MEtB%2Y0sR-^U5wyOj=}q%ljjQ#jGO7z2uAL9qZ<86W}jSy zG0-yKUPiUxS_Jph$ZTcy>i>Xy32y%`-2U}L4YT|`9Df3ie}Q9M?k4K*n9{YVyHEU( z2;F_?u>Tb9zz+~_(N~_b+mwAk8TlSYVH8`TY?U$!Nb~QqPw~=|#q}rU;_f$(*Stg( zyB7D)KK9fqoTI@iEidtStAs#tn~I({YbJ_hwDCPJ+#hYWh8;YbwtYOY=SHJ#v0u`d zG)uxlRd+vuW3TLCr_27BDSMfM>$2Kj+qHOT%zjEZ6@wi(dDY*`(8{hajC$-{tRnjC zXt|#D1FFEIdoqGIUGvMRk0%);Zv8&Ss3AEmWaQSD;Ivg~0nR%s-WF$ruMhc`#+^Hr z4Svn{Y8S?QWqV~yk*@`5R_y$=w=|3_d;QgIU_(huM{l_}L)7z1?Cimn@a<$>uE3F> zk+X$68uxV|)3y`s61_eu^{FS3w4et}4$xEpVOcnc@m^}ASK9A&;E$V*)MN%~GLf2T zUIV=KNk)A;8K~WKV zMCBA<=qhZ02THy@eNGjdl&w=%rtB@<0^6d-h$#d=WFr$}kCEji-@>-3fbZCO#si(d zK-oVaIpkveK>u zR^b%uaeLFKHyOQaHgBpfE5&K<|SfL;xm_$v{4$x^wYc5Pzb$3J%C*iq-h4AeB4wH5=ZyX69b_JE2?^ z2Y>m5FV!4|VH?PBW)sx=#NVW{6gaejjVyPv`IsLQtKlA2Px1{eol7usD{PmtL5=V< zPBcgGuc&rNO$5Zc3fv%+LhQ_j?CCcg5jVxTT-^8Z0aL^_?Sxzuy}={?24~K&*@0`2 z&lDULf(z&JInHdswOCg|lIyX390&R0kNXxyM#G*`)?1r6J9;8-1tM>8k?V21tJu{K zQpt9J;XjZZ;)B4$cNLo5C$6t*)o1`uM>Rc<{PzH`kCPzkEGCUFJLQTlJgzTjS2;si zeon!A_yuvF#Z3WaF?=P!jyTw$ayBH-G-5(m>BhS8a|BDGK>ZMuBXl7gb?i9nQ}e

c;9*XX$gH8?R68(^0rw{_%P#P%37*ZDy}F+it7v=KN)z4%YG+oF6_jY_ky! z3vQssXZ(;;>WhHK0i=;SA_EFOytrvmbODtmJ@7K6;0$GJkB&+D@aKFqebMIHw&@=S zKWOjoTWqJ+vGl706=lmZEwhLL9DS}e+C@*cJ~td*J}m98Fpd94a_EGTyqqGc@M0SO zsW>7f#a@;=^Py@-&1gXWWbSkp!Ihg1sxFd0WTbG(#$fQ!1Cl5i`D?5a-=HrTq~jHF zUYy;1){^IcE&Ja4TWa|$$_7>0o8IQ}7SiLSnG`P9|ok?SOA4A(63iL6LTn*KwsYEH@B@zn_NZ#g_sx#kiPo2t?+0 zE^$G@M7uHPb60hfbKW&~Co4b94mawCL(3KjqsBU%TmugMC36 zU)1|j{ea3yk@`m~!SRKjq;rcM!llpc@Uz1py!B5nbgk8IFy9*2VtTLFV!he6%@J)W z@w3X_t(8U$_I-R7=CB}<&h+(VsP%xOC%@RU1zLVWM-PTZ9J{agHZ)^h5TZEb_Bs^rQ>mKz1M# za!W}msWTH2+iRDX%H{m@&{4R5pL3svq9BkJDC0^>Ya=6<$-bk^plpw_DrFXB{VDM; z(jWFSWF;hiwWCVfyXw076E&vNGovQ))6_U`MR*1t(xm%H&N8yzi8HRXalR~@xP`4`UJ5-#|a# z8$ZEU;B@u4zaV;v7k(%fA)M2kM%z3|fkZ~irqN|#nx@!407QN7p>LWmpKBH$2!G(1 zx`+t;wZRW|Bu2CF`9DoxeTLJxbkk>AjY?&e#wOYYv6Bi$7+R8o+T;>8R6mSRLk6fSeR=~jr$s!KP-(zzU= z{I$f#^(T9Pc9F^UIDR)m^|U`&kK5(f%2>kt4D8cf2mYUjxKxo5d^w6YjU(L4T$W-Q z_hO2F8O{=Np7sapQ_LEJeCiW;go;nYt{{-$OA(mZrW^mpsNKDdOqosdnEslEvNf<%HRllT_C zGqy|DjF%#meNSXg65@6^OHi2MgY@VdSY6SqA2QItoP_R=-gS!3ggTx72Z6Hh3}e1C z><3VER^j{ValTR6#x3e@WI~!hAu68a79GMk&P6a({3YQE+@i#&WU>(Grgef_jP2OQ z;ia{V)cayB`&ESG3?Hi}gYsk-;R5fsVNd87!IvU0zT0N*Wj#cjsGFo*W;i`^e*P$L zL)mkpBxIE=D^r?;NHh4p0orKS|z$zRTl4l(>hN)N;7g3`so(RvgQ*pm!w38W&D z^BJ;!wCY`AKAAp#DGvGd_O8-z!9aYKmZ7r_z5tq6(et}zUY)JVL_!;rq^tzrn@ z@@UNpLRCHGPc_)i2avznj~EpXT+)cZ%lJnIzsC{LOXU&N3Q)+)O?7Q~zJ?KErGU=Qc7WOaD-SpQI?+)NEol Uote)3jqqJ2olOM4DgK`MUmrjtPXGV_ literal 0 HcmV?d00001 diff --git a/Examples/RTTI/RTTI_component/Examples/CppDynamic/CMakeLists.txt b/Examples/RTTI/RTTI_component/Examples/CppDynamic/CMakeLists.txt new file mode 100644 index 00000000..b739dd40 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/CppDynamic/CMakeLists.txt @@ -0,0 +1,26 @@ +#[[++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated CMake Project that demonstrates the + usage of the Dynamic C++ bindings of RTTI + +Interface version: 1.0.0 + + +]] + +cmake_minimum_required(VERSION 3.5) + +set(CMAKE_CURRENT_BINDING_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../Bindings/CppDynamic) +project(RTTIExample_CPPDynamic) +set(CMAKE_CXX_STANDARD 11) +add_executable(RTTIExample_CPPDynamic "${CMAKE_CURRENT_SOURCE_DIR}/RTTI_example.cpp") +if (UNIX) + target_link_libraries(RTTIExample_CPPDynamic ${CMAKE_DL_LIBS}) +endif (UNIX) +target_include_directories(RTTIExample_CPPDynamic PRIVATE "${CMAKE_CURRENT_BINDING_DIR}") diff --git a/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp b/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp new file mode 100644 index 00000000..cb354a3b --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp @@ -0,0 +1,38 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated C++ application that demonstrates the + usage of the Dynamic C++ bindings of RTTI + +Interface version: 1.0.0 + +*/ + +#include +#include "rtti_dynamic.hpp" + + +int main() +{ + try + { + std::string libpath = (""); // TODO: put the location of the RTTI-library file here. + auto wrapper = RTTI::CWrapper::loadLibrary(libpath + "/rtti."); // TODO: add correct suffix of the library + RTTI_uint32 nMajor, nMinor, nMicro; + wrapper->GetVersion(nMajor, nMinor, nMicro); + std::cout << "RTTI.Version = " << nMajor << "." << nMinor << "." << nMicro; + std::cout << std::endl; + } + catch (std::exception &e) + { + std::cout << e.what() << std::endl; + return 1; + } + return 0; +} + diff --git a/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py b/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py new file mode 100644 index 00000000..6327a52e --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py @@ -0,0 +1,36 @@ +'''++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Python application that demonstrates the + usage of the Python bindings of RTTI + +Interface version: 1.0.0 + +''' + + +import os +import sys +sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "..", "Bindings", "Python")) +import RTTI + + +def main(): + libpath = '' # TODO add the location of the shared library binary here + wrapper = RTTI.Wrapper(libraryName = os.path.join(libpath, "rtti")) + + major, minor, micro = wrapper.GetVersion() + print("RTTI version: {:d}.{:d}.{:d}".format(major, minor, micro), end="") + print("") + + +if __name__ == "__main__": + try: + main() + except RTTI.ERTTIException as e: + print(e) diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/CMakeLists.txt b/Examples/RTTI/RTTI_component/Implementations/Cpp/CMakeLists.txt new file mode 100644 index 00000000..d9db9617 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/CMakeLists.txt @@ -0,0 +1,46 @@ +#[[++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated CMakeLists file for the development of RTTI. + +Interface version: 1.0.0 + + +]] + +cmake_minimum_required(VERSION 3.5) + +### The implementation of the RTTI component +project(RTTI) + +set (CMAKE_CXX_STANDARD 11) + +# The location of autogenerated interfaces +set(CMAKE_CURRENT_AUTOGENERATED_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Interfaces) + +file(GLOB RTTI_SRC + ${CMAKE_CURRENT_SOURCE_DIR}/Stub/*.cpp +) +file(GLOB RTTI_HDR + ${CMAKE_CURRENT_SOURCE_DIR}/Stub/*.hpp +) +set(RTTI_SRC ${RTTI_SRC} ${RTTI_SRC} + ${CMAKE_CURRENT_AUTOGENERATED_DIR}/rtti_interfaceexception.cpp + ${CMAKE_CURRENT_AUTOGENERATED_DIR}/rtti_interfacewrapper.cpp +) + +add_library(rtti SHARED ${RTTI_SRC}) +# Do not prefix the binary's name with "lib" on Unix systems: +set_target_properties(rtti PROPERTIES PREFIX "" IMPORT_PREFIX "" ) +# The following two properties are crucial to reduce the number of undesirably exported symbols +set_target_properties(rtti PROPERTIES CXX_VISIBILITY_PRESET hidden) +set_target_properties(rtti PROPERTIES VISIBILITY_INLINES_HIDDEN ON) +# This makes sure symbols are exported +target_compile_options(rtti PRIVATE "-D__RTTI_EXPORTS") +target_include_directories(rtti PRIVATE ${CMAKE_CURRENT_AUTOGENERATED_DIR}) +target_include_directories(rtti PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Stub) diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp new file mode 100644 index 00000000..9e3e457e --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp @@ -0,0 +1,174 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated C++-Header file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +#ifndef __RTTI_HEADER_CPP +#define __RTTI_HEADER_CPP + +#ifdef __RTTI_EXPORTS +#ifdef _WIN32 +#define RTTI_DECLSPEC __declspec (dllexport) +#else // _WIN32 +#define RTTI_DECLSPEC __attribute__((visibility("default"))) +#endif // _WIN32 +#else // __RTTI_EXPORTS +#define RTTI_DECLSPEC +#endif // __RTTI_EXPORTS + +#include "rtti_types.hpp" + + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************************************* + Class definition for Base +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Animal +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Mammal +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Reptile +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Giraffe +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Tiger +**************************************************************************************************************************/ + +/** +* Roar like a tiger +* +* @param[in] pTiger - Tiger instance. +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_tiger_roar(RTTI_Tiger pTiger); + +/************************************************************************************************************************* + Class definition for Snake +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Turtle +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for AnimalIterator +**************************************************************************************************************************/ + +/** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_animaliterator_getnextanimal(RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal); + +/************************************************************************************************************************* + Class definition for Zoo +**************************************************************************************************************************/ + +/** +* Return an iterator over all zoo animals +* +* @param[in] pZoo - Zoo instance. +* @param[out] pIterator - +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_zoo_iterator(RTTI_Zoo pZoo, RTTI_AnimalIterator * pIterator); + +/************************************************************************************************************************* + Global functions +**************************************************************************************************************************/ + +/** +* retrieves the binary version of this library. +* +* @param[out] pMajor - returns the major version of this library +* @param[out] pMinor - returns the minor version of this library +* @param[out] pMicro - returns the micro version of this library +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_getversion(RTTI_uint32 * pMajor, RTTI_uint32 * pMinor, RTTI_uint32 * pMicro); + +/** +* Returns the last error recorded on this object +* +* @param[in] pInstance - Instance Handle +* @param[in] nErrorMessageBufferSize - size of the buffer (including trailing 0) +* @param[out] pErrorMessageNeededChars - will be filled with the count of the written bytes, or needed buffer size. +* @param[out] pErrorMessageBuffer - buffer of Message of the last error, may be NULL +* @param[out] pHasError - Is there a last error to query +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_getlasterror(RTTI_Base pInstance, const RTTI_uint32 nErrorMessageBufferSize, RTTI_uint32* pErrorMessageNeededChars, char * pErrorMessageBuffer, bool * pHasError); + +/** +* Releases shared ownership of an Instance +* +* @param[in] pInstance - Instance Handle +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_releaseinstance(RTTI_Base pInstance); + +/** +* Acquires shared ownership of an Instance +* +* @param[in] pInstance - Instance Handle +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_acquireinstance(RTTI_Base pInstance); + +/** +* Injects an imported component for usage within this component +* +* @param[in] pNameSpace - NameSpace of the injected component +* @param[in] pSymbolAddressMethod - Address of the SymbolAddressMethod of the injected component +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_injectcomponent(const char * pNameSpace, RTTI_pvoid pSymbolAddressMethod); + +/** +* Returns the address of the SymbolLookupMethod +* +* @param[out] pSymbolLookupMethod - Address of the SymbolAddressMethod +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_getsymbollookupmethod(RTTI_pvoid * pSymbolLookupMethod); + +/** +* Create a new zoo with animals +* +* @param[out] pInstance - +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_createzoo(RTTI_Zoo * pInstance); + +#ifdef __cplusplus +} +#endif + +#endif // __RTTI_HEADER_CPP + diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaceexception.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaceexception.cpp new file mode 100644 index 00000000..4db45b80 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaceexception.cpp @@ -0,0 +1,45 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated C++ Implementation file with the basic internal + exception type in order to allow an easy use of RTTI + +Interface version: 1.0.0 + +*/ + + +#include + +#include "rtti_interfaceexception.hpp" + +/************************************************************************************************************************* + Class ERTTIInterfaceException +**************************************************************************************************************************/ +ERTTIInterfaceException::ERTTIInterfaceException(RTTIResult errorCode) + : m_errorMessage(RTTI_GETERRORSTRING (errorCode)) +{ + m_errorCode = errorCode; +} + +ERTTIInterfaceException::ERTTIInterfaceException(RTTIResult errorCode, std::string errorMessage) + : m_errorMessage(errorMessage + " (" + std::to_string (errorCode) + ")") +{ + m_errorCode = errorCode; +} + +RTTIResult ERTTIInterfaceException::getErrorCode () +{ + return m_errorCode; +} + +const char * ERTTIInterfaceException::what () const noexcept +{ + return m_errorMessage.c_str(); +} + diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaceexception.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaceexception.hpp new file mode 100644 index 00000000..a6f4795c --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaceexception.hpp @@ -0,0 +1,60 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated C++ Header file with the basic internal + exception type in order to allow an easy use of RTTI + +Interface version: 1.0.0 + +*/ + +#ifndef __RTTI_INTERFACEEXCEPTION_HEADER +#define __RTTI_INTERFACEEXCEPTION_HEADER + +#include +#include +#include "rtti_types.hpp" + +/************************************************************************************************************************* + Class ERTTIInterfaceException +**************************************************************************************************************************/ + + +class ERTTIInterfaceException : public std::exception { +protected: + /** + * Error code for the Exception. + */ + RTTIResult m_errorCode; + /** + * Error message for the Exception. + */ + std::string m_errorMessage; + +public: + /** + * Exception Constructor. + */ + ERTTIInterfaceException(RTTIResult errorCode); + + /** + * Custom Exception Constructor. + */ + ERTTIInterfaceException(RTTIResult errorCode, std::string errorMessage); + + /** + * Returns error code + */ + RTTIResult getErrorCode(); + /** + * Returns error message + */ + const char* what() const noexcept override; +}; + +#endif // __RTTI_INTERFACEEXCEPTION_HEADER diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp new file mode 100644 index 00000000..4b48aa2b --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp @@ -0,0 +1,367 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated C++ header file in order to allow easy +development of RTTI. The implementer of RTTI needs to +derive concrete classes from the abstract classes in this header. + +Interface version: 1.0.0 + +*/ + + +#ifndef __RTTI_CPPINTERFACES +#define __RTTI_CPPINTERFACES + +#include +#include + +#include "rtti_types.hpp" + + + +namespace RTTI { +namespace Impl { + +/** + Forward declarations of class interfaces +*/ +class IBase; +class IAnimal; +class IMammal; +class IReptile; +class IGiraffe; +class ITiger; +class ISnake; +class ITurtle; +class IAnimalIterator; +class IZoo; + + + +/************************************************************************************************************************* + Parameter Cache definitions +**************************************************************************************************************************/ + +class ParameterCache { + public: + virtual ~ParameterCache() {} +}; + +template class ParameterCache_1 : public ParameterCache { + private: + T1 m_param1; + public: + ParameterCache_1 (const T1 & param1) + : m_param1 (param1) + { + } + + void retrieveData (T1 & param1) + { + param1 = m_param1; + } +}; + +template class ParameterCache_2 : public ParameterCache { + private: + T1 m_param1; + T2 m_param2; + public: + ParameterCache_2 (const T1 & param1, const T2 & param2) + : m_param1 (param1), m_param2 (param2) + { + } + + void retrieveData (T1 & param1, T2 & param2) + { + param1 = m_param1; + param2 = m_param2; + } +}; + +template class ParameterCache_3 : public ParameterCache { + private: + T1 m_param1; + T2 m_param2; + T3 m_param3; + public: + ParameterCache_3 (const T1 & param1, const T2 & param2, const T3 & param3) + : m_param1 (param1), m_param2 (param2), m_param3 (param3) + { + } + + void retrieveData (T1 & param1, T2 & param2, T3 & param3) + { + param1 = m_param1; + param2 = m_param2; + param3 = m_param3; + } +}; + + +/************************************************************************************************************************* + Class interface for Base +**************************************************************************************************************************/ + +class IBase { +public: + /** + * IBase::~IBase - virtual destructor of IBase + */ + virtual ~IBase() {}; + + /** + * IBase::ReleaseBaseClassInterface - Releases ownership of a base class interface. Deletes the reference, if necessary. + * @param[in] pIBase - The base class instance to release + */ + static void ReleaseBaseClassInterface(IBase* pIBase) + { + if (pIBase) { + pIBase->DecRefCount(); + } + }; + + /** + * IBase::AcquireBaseClassInterface - Acquires shared ownership of a base class interface. + * @param[in] pIBase - The base class instance to acquire + */ + static void AcquireBaseClassInterface(IBase* pIBase) + { + if (pIBase) { + pIBase->IncRefCount(); + } + }; + + + /** + * IBase::GetLastErrorMessage - Returns the last error registered of this class instance + * @param[out] sErrorMessage - Message of the last error registered + * @return Has an error been registered already + */ + virtual bool GetLastErrorMessage(std::string & sErrorMessage) = 0; + + /** + * IBase::ClearErrorMessages - Clears all registered messages of this class instance + */ + virtual void ClearErrorMessages() = 0; + + /** + * IBase::RegisterErrorMessage - Registers an error message with this class instance + * @param[in] sErrorMessage - Error message to register + */ + virtual void RegisterErrorMessage(const std::string & sErrorMessage) = 0; + + /** + * IBase::IncRefCount - Increases the reference count of a class instance + */ + virtual void IncRefCount() = 0; + + /** + * IBase::DecRefCount - Decreases the reference count of a class instance and free releases it, if the last reference has been removed + * @return Has the object been released + */ + virtual bool DecRefCount() = 0; +}; + + +/** + Definition of a shared pointer class for IBase +*/ +template +class IBaseSharedPtr : public std::shared_ptr +{ +public: + explicit IBaseSharedPtr(T* t = nullptr) + : std::shared_ptr(t, IBase::ReleaseBaseClassInterface) + { + t->IncRefCount(); + } + + // Reset function, as it also needs to properly set the deleter. + void reset(T* t = nullptr) + { + std::shared_ptr::reset(t, IBase::ReleaseBaseClassInterface); + } + + // Get-function that increases the Base class's reference count + T* getCoOwningPtr() + { + T* t = this->get(); + t->IncRefCount(); + return t; + } +}; + + +typedef IBaseSharedPtr PIBase; + + +/************************************************************************************************************************* + Class interface for Animal +**************************************************************************************************************************/ + +class IAnimal : public virtual IBase { +public: +}; + +typedef IBaseSharedPtr PIAnimal; + + +/************************************************************************************************************************* + Class interface for Mammal +**************************************************************************************************************************/ + +class IMammal : public virtual IAnimal { +public: +}; + +typedef IBaseSharedPtr PIMammal; + + +/************************************************************************************************************************* + Class interface for Reptile +**************************************************************************************************************************/ + +class IReptile : public virtual IAnimal { +public: +}; + +typedef IBaseSharedPtr PIReptile; + + +/************************************************************************************************************************* + Class interface for Giraffe +**************************************************************************************************************************/ + +class IGiraffe : public virtual IMammal { +public: +}; + +typedef IBaseSharedPtr PIGiraffe; + + +/************************************************************************************************************************* + Class interface for Tiger +**************************************************************************************************************************/ + +class ITiger : public virtual IMammal { +public: + /** + * ITiger::Roar - Roar like a tiger + */ + virtual void Roar() = 0; + +}; + +typedef IBaseSharedPtr PITiger; + + +/************************************************************************************************************************* + Class interface for Snake +**************************************************************************************************************************/ + +class ISnake : public virtual IReptile { +public: +}; + +typedef IBaseSharedPtr PISnake; + + +/************************************************************************************************************************* + Class interface for Turtle +**************************************************************************************************************************/ + +class ITurtle : public virtual IReptile { +public: +}; + +typedef IBaseSharedPtr PITurtle; + + +/************************************************************************************************************************* + Class interface for AnimalIterator +**************************************************************************************************************************/ + +class IAnimalIterator : public virtual IBase { +public: + /** + * IAnimalIterator::GetNextAnimal - Return next animal + * @return + */ + virtual IAnimal * GetNextAnimal() = 0; + +}; + +typedef IBaseSharedPtr PIAnimalIterator; + + +/************************************************************************************************************************* + Class interface for Zoo +**************************************************************************************************************************/ + +class IZoo : public virtual IBase { +public: + /** + * IZoo::Iterator - Return an iterator over all zoo animals + * @return + */ + virtual IAnimalIterator * Iterator() = 0; + +}; + +typedef IBaseSharedPtr PIZoo; + + +/************************************************************************************************************************* + Global functions declarations +**************************************************************************************************************************/ +class CWrapper { +public: + /** + * Irtti::GetVersion - retrieves the binary version of this library. + * @param[out] nMajor - returns the major version of this library + * @param[out] nMinor - returns the minor version of this library + * @param[out] nMicro - returns the micro version of this library + */ + static void GetVersion(RTTI_uint32 & nMajor, RTTI_uint32 & nMinor, RTTI_uint32 & nMicro); + + /** + * Irtti::GetLastError - Returns the last error recorded on this object + * @param[in] pInstance - Instance Handle + * @param[out] sErrorMessage - Message of the last error + * @return Is there a last error to query + */ + static bool GetLastError(IBase* pInstance, std::string & sErrorMessage); + + /** + * Irtti::ReleaseInstance - Releases shared ownership of an Instance + * @param[in] pInstance - Instance Handle + */ + static void ReleaseInstance(IBase* pInstance); + + /** + * Irtti::AcquireInstance - Acquires shared ownership of an Instance + * @param[in] pInstance - Instance Handle + */ + static void AcquireInstance(IBase* pInstance); + + /** + * Irtti::CreateZoo - Create a new zoo with animals + * @return + */ + static IZoo * CreateZoo(); + +}; + +RTTIResult RTTI_GetProcAddress (const char * pProcName, void ** ppProcAddress); + +} // namespace Impl +} // namespace RTTI + +#endif // __RTTI_CPPINTERFACES diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp new file mode 100644 index 00000000..9fe72034 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp @@ -0,0 +1,407 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated C++ implementation file in order to allow easy +development of RTTI. The functions in this file need to be implemented. It needs to be generated only once. + +Interface version: 1.0.0 + +*/ + +#include "rtti_abi.hpp" +#include "rtti_interfaces.hpp" +#include "rtti_interfaceexception.hpp" + +#include + +using namespace RTTI::Impl; + +RTTIResult handleRTTIException(IBase * pIBaseClass, ERTTIInterfaceException & Exception) +{ + RTTIResult errorCode = Exception.getErrorCode(); + + if (pIBaseClass != nullptr) + pIBaseClass->RegisterErrorMessage(Exception.what()); + + return errorCode; +} + +RTTIResult handleStdException(IBase * pIBaseClass, std::exception & Exception) +{ + RTTIResult errorCode = RTTI_ERROR_GENERICEXCEPTION; + + if (pIBaseClass != nullptr) + pIBaseClass->RegisterErrorMessage(Exception.what()); + + return errorCode; +} + +RTTIResult handleUnhandledException(IBase * pIBaseClass) +{ + RTTIResult errorCode = RTTI_ERROR_GENERICEXCEPTION; + + if (pIBaseClass != nullptr) + pIBaseClass->RegisterErrorMessage("Unhandled Exception"); + + return errorCode; +} + + + +/************************************************************************************************************************* + Class implementation for Base +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class implementation for Animal +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class implementation for Mammal +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class implementation for Reptile +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class implementation for Giraffe +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class implementation for Tiger +**************************************************************************************************************************/ +RTTIResult rtti_tiger_roar(RTTI_Tiger pTiger) +{ + IBase* pIBaseClass = (IBase *)pTiger; + + try { + ITiger* pITiger = dynamic_cast(pIBaseClass); + if (!pITiger) + throw ERTTIInterfaceException(RTTI_ERROR_INVALIDCAST); + + pITiger->Roar(); + + return RTTI_SUCCESS; + } + catch (ERTTIInterfaceException & Exception) { + return handleRTTIException(pIBaseClass, Exception); + } + catch (std::exception & StdException) { + return handleStdException(pIBaseClass, StdException); + } + catch (...) { + return handleUnhandledException(pIBaseClass); + } +} + + +/************************************************************************************************************************* + Class implementation for Snake +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class implementation for Turtle +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class implementation for AnimalIterator +**************************************************************************************************************************/ +RTTIResult rtti_animaliterator_getnextanimal(RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal) +{ + IBase* pIBaseClass = (IBase *)pAnimalIterator; + + try { + if (pAnimal == nullptr) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDPARAM); + IBase* pBaseAnimal(nullptr); + IAnimalIterator* pIAnimalIterator = dynamic_cast(pIBaseClass); + if (!pIAnimalIterator) + throw ERTTIInterfaceException(RTTI_ERROR_INVALIDCAST); + + pBaseAnimal = pIAnimalIterator->GetNextAnimal(); + + *pAnimal = (IBase*)(pBaseAnimal); + return RTTI_SUCCESS; + } + catch (ERTTIInterfaceException & Exception) { + return handleRTTIException(pIBaseClass, Exception); + } + catch (std::exception & StdException) { + return handleStdException(pIBaseClass, StdException); + } + catch (...) { + return handleUnhandledException(pIBaseClass); + } +} + + +/************************************************************************************************************************* + Class implementation for Zoo +**************************************************************************************************************************/ +RTTIResult rtti_zoo_iterator(RTTI_Zoo pZoo, RTTI_AnimalIterator * pIterator) +{ + IBase* pIBaseClass = (IBase *)pZoo; + + try { + if (pIterator == nullptr) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDPARAM); + IBase* pBaseIterator(nullptr); + IZoo* pIZoo = dynamic_cast(pIBaseClass); + if (!pIZoo) + throw ERTTIInterfaceException(RTTI_ERROR_INVALIDCAST); + + pBaseIterator = pIZoo->Iterator(); + + *pIterator = (IBase*)(pBaseIterator); + return RTTI_SUCCESS; + } + catch (ERTTIInterfaceException & Exception) { + return handleRTTIException(pIBaseClass, Exception); + } + catch (std::exception & StdException) { + return handleStdException(pIBaseClass, StdException); + } + catch (...) { + return handleUnhandledException(pIBaseClass); + } +} + + + +/************************************************************************************************************************* + Function table lookup implementation +**************************************************************************************************************************/ + +RTTIResult RTTI::Impl::RTTI_GetProcAddress (const char * pProcName, void ** ppProcAddress) +{ + if (pProcName == nullptr) + return RTTI_ERROR_INVALIDPARAM; + if (ppProcAddress == nullptr) + return RTTI_ERROR_INVALIDPARAM; + *ppProcAddress = nullptr; + std::string sProcName (pProcName); + + if (sProcName == "rtti_tiger_roar") + *ppProcAddress = (void*) &rtti_tiger_roar; + if (sProcName == "rtti_animaliterator_getnextanimal") + *ppProcAddress = (void*) &rtti_animaliterator_getnextanimal; + if (sProcName == "rtti_zoo_iterator") + *ppProcAddress = (void*) &rtti_zoo_iterator; + if (sProcName == "rtti_getversion") + *ppProcAddress = (void*) &rtti_getversion; + if (sProcName == "rtti_getlasterror") + *ppProcAddress = (void*) &rtti_getlasterror; + if (sProcName == "rtti_releaseinstance") + *ppProcAddress = (void*) &rtti_releaseinstance; + if (sProcName == "rtti_acquireinstance") + *ppProcAddress = (void*) &rtti_acquireinstance; + if (sProcName == "rtti_injectcomponent") + *ppProcAddress = (void*) &rtti_injectcomponent; + if (sProcName == "rtti_getsymbollookupmethod") + *ppProcAddress = (void*) &rtti_getsymbollookupmethod; + if (sProcName == "rtti_createzoo") + *ppProcAddress = (void*) &rtti_createzoo; + + if (*ppProcAddress == nullptr) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + return RTTI_SUCCESS; +} + +/************************************************************************************************************************* + Global functions implementation +**************************************************************************************************************************/ +RTTIResult rtti_getversion(RTTI_uint32 * pMajor, RTTI_uint32 * pMinor, RTTI_uint32 * pMicro) +{ + IBase* pIBaseClass = nullptr; + + try { + if (!pMajor) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDPARAM); + if (!pMinor) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDPARAM); + if (!pMicro) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDPARAM); + CWrapper::GetVersion(*pMajor, *pMinor, *pMicro); + + return RTTI_SUCCESS; + } + catch (ERTTIInterfaceException & Exception) { + return handleRTTIException(pIBaseClass, Exception); + } + catch (std::exception & StdException) { + return handleStdException(pIBaseClass, StdException); + } + catch (...) { + return handleUnhandledException(pIBaseClass); + } +} + +RTTIResult rtti_getlasterror(RTTI_Base pInstance, const RTTI_uint32 nErrorMessageBufferSize, RTTI_uint32* pErrorMessageNeededChars, char * pErrorMessageBuffer, bool * pHasError) +{ + IBase* pIBaseClass = nullptr; + + try { + if ( (!pErrorMessageBuffer) && !(pErrorMessageNeededChars) ) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDPARAM); + if (pHasError == nullptr) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDPARAM); + IBase* pIBaseClassInstance = (IBase *)pInstance; + IBase* pIInstance = dynamic_cast(pIBaseClassInstance); + if (!pIInstance) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDCAST); + + std::string sErrorMessage(""); + *pHasError = CWrapper::GetLastError(pIInstance, sErrorMessage); + + if (pErrorMessageNeededChars) + *pErrorMessageNeededChars = (RTTI_uint32) (sErrorMessage.size()+1); + if (pErrorMessageBuffer) { + if (sErrorMessage.size() >= nErrorMessageBufferSize) + throw ERTTIInterfaceException (RTTI_ERROR_BUFFERTOOSMALL); + for (size_t iErrorMessage = 0; iErrorMessage < sErrorMessage.size(); iErrorMessage++) + pErrorMessageBuffer[iErrorMessage] = sErrorMessage[iErrorMessage]; + pErrorMessageBuffer[sErrorMessage.size()] = 0; + } + return RTTI_SUCCESS; + } + catch (ERTTIInterfaceException & Exception) { + return handleRTTIException(pIBaseClass, Exception); + } + catch (std::exception & StdException) { + return handleStdException(pIBaseClass, StdException); + } + catch (...) { + return handleUnhandledException(pIBaseClass); + } +} + +RTTIResult rtti_releaseinstance(RTTI_Base pInstance) +{ + IBase* pIBaseClass = nullptr; + + try { + IBase* pIBaseClassInstance = (IBase *)pInstance; + IBase* pIInstance = dynamic_cast(pIBaseClassInstance); + if (!pIInstance) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDCAST); + + CWrapper::ReleaseInstance(pIInstance); + + return RTTI_SUCCESS; + } + catch (ERTTIInterfaceException & Exception) { + return handleRTTIException(pIBaseClass, Exception); + } + catch (std::exception & StdException) { + return handleStdException(pIBaseClass, StdException); + } + catch (...) { + return handleUnhandledException(pIBaseClass); + } +} + +RTTIResult rtti_acquireinstance(RTTI_Base pInstance) +{ + IBase* pIBaseClass = nullptr; + + try { + IBase* pIBaseClassInstance = (IBase *)pInstance; + IBase* pIInstance = dynamic_cast(pIBaseClassInstance); + if (!pIInstance) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDCAST); + + CWrapper::AcquireInstance(pIInstance); + + return RTTI_SUCCESS; + } + catch (ERTTIInterfaceException & Exception) { + return handleRTTIException(pIBaseClass, Exception); + } + catch (std::exception & StdException) { + return handleStdException(pIBaseClass, StdException); + } + catch (...) { + return handleUnhandledException(pIBaseClass); + } +} + +RTTIResult rtti_injectcomponent(const char * pNameSpace, RTTI_pvoid pSymbolAddressMethod) +{ + IBase* pIBaseClass = nullptr; + + try { + if (pNameSpace == nullptr) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDPARAM); + std::string sNameSpace(pNameSpace); + + bool bNameSpaceFound = false; + + + if (!bNameSpaceFound) + throw ERTTIInterfaceException(RTTI_ERROR_COULDNOTLOADLIBRARY); + + return RTTI_SUCCESS; + } + catch (ERTTIInterfaceException & Exception) { + return handleRTTIException(pIBaseClass, Exception); + } + catch (std::exception & StdException) { + return handleStdException(pIBaseClass, StdException); + } + catch (...) { + return handleUnhandledException(pIBaseClass); + } +} + +RTTIResult rtti_getsymbollookupmethod(RTTI_pvoid * pSymbolLookupMethod) +{ + IBase* pIBaseClass = nullptr; + + try { + if (pSymbolLookupMethod == nullptr) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDPARAM); + *pSymbolLookupMethod = (void*)&RTTI::Impl::RTTI_GetProcAddress; + return RTTI_SUCCESS; + } + catch (ERTTIInterfaceException & Exception) { + return handleRTTIException(pIBaseClass, Exception); + } + catch (std::exception & StdException) { + return handleStdException(pIBaseClass, StdException); + } + catch (...) { + return handleUnhandledException(pIBaseClass); + } +} + +RTTIResult rtti_createzoo(RTTI_Zoo * pInstance) +{ + IBase* pIBaseClass = nullptr; + + try { + if (pInstance == nullptr) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDPARAM); + IBase* pBaseInstance(nullptr); + pBaseInstance = CWrapper::CreateZoo(); + + *pInstance = (IBase*)(pBaseInstance); + return RTTI_SUCCESS; + } + catch (ERTTIInterfaceException & Exception) { + return handleRTTIException(pIBaseClass, Exception); + } + catch (std::exception & StdException) { + return handleStdException(pIBaseClass, StdException); + } + catch (...) { + return handleUnhandledException(pIBaseClass); + } +} + + diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_types.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_types.hpp new file mode 100644 index 00000000..19fec9a2 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_types.hpp @@ -0,0 +1,125 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated C++-Header file with basic types in +order to allow an easy use of RTTI + +Interface version: 1.0.0 + +*/ + +#ifndef __RTTI_TYPES_HEADER_CPP +#define __RTTI_TYPES_HEADER_CPP + + +/************************************************************************************************************************* + Scalar types definition +**************************************************************************************************************************/ + +#ifdef RTTI_USELEGACYINTEGERTYPES + +typedef unsigned char RTTI_uint8; +typedef unsigned short RTTI_uint16 ; +typedef unsigned int RTTI_uint32; +typedef unsigned long long RTTI_uint64; +typedef char RTTI_int8; +typedef short RTTI_int16; +typedef int RTTI_int32; +typedef long long RTTI_int64; + +#else // RTTI_USELEGACYINTEGERTYPES + +#include + +typedef uint8_t RTTI_uint8; +typedef uint16_t RTTI_uint16; +typedef uint32_t RTTI_uint32; +typedef uint64_t RTTI_uint64; +typedef int8_t RTTI_int8; +typedef int16_t RTTI_int16; +typedef int32_t RTTI_int32; +typedef int64_t RTTI_int64 ; + +#endif // RTTI_USELEGACYINTEGERTYPES + +typedef float RTTI_single; +typedef double RTTI_double; + +/************************************************************************************************************************* + General type definitions +**************************************************************************************************************************/ + +typedef RTTI_int32 RTTIResult; +typedef void * RTTIHandle; +typedef void * RTTI_pvoid; + +/************************************************************************************************************************* + Version for RTTI +**************************************************************************************************************************/ + +#define RTTI_VERSION_MAJOR 1 +#define RTTI_VERSION_MINOR 0 +#define RTTI_VERSION_MICRO 0 +#define RTTI_VERSION_PRERELEASEINFO "" +#define RTTI_VERSION_BUILDINFO "" + +/************************************************************************************************************************* + Error constants for RTTI +**************************************************************************************************************************/ + +#define RTTI_SUCCESS 0 +#define RTTI_ERROR_NOTIMPLEMENTED 1 +#define RTTI_ERROR_INVALIDPARAM 2 +#define RTTI_ERROR_INVALIDCAST 3 +#define RTTI_ERROR_BUFFERTOOSMALL 4 +#define RTTI_ERROR_GENERICEXCEPTION 5 +#define RTTI_ERROR_COULDNOTLOADLIBRARY 6 +#define RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT 7 +#define RTTI_ERROR_INCOMPATIBLEBINARYVERSION 8 + +/************************************************************************************************************************* + Error strings for RTTI +**************************************************************************************************************************/ + +inline const char * RTTI_GETERRORSTRING (RTTIResult nErrorCode) { + switch (nErrorCode) { + case RTTI_SUCCESS: return "no error"; + case RTTI_ERROR_NOTIMPLEMENTED: return "functionality not implemented"; + case RTTI_ERROR_INVALIDPARAM: return "an invalid parameter was passed"; + case RTTI_ERROR_INVALIDCAST: return "a type cast failed"; + case RTTI_ERROR_BUFFERTOOSMALL: return "a provided buffer is too small"; + case RTTI_ERROR_GENERICEXCEPTION: return "a generic exception occurred"; + case RTTI_ERROR_COULDNOTLOADLIBRARY: return "the library could not be loaded"; + case RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT: return "a required exported symbol could not be found in the library"; + case RTTI_ERROR_INCOMPATIBLEBINARYVERSION: return "the version of the binary interface does not match the bindings interface"; + default: return "unknown error"; + } +} + +/************************************************************************************************************************* + Declaration of handle classes +**************************************************************************************************************************/ + +typedef RTTIHandle RTTI_Base; +typedef RTTIHandle RTTI_Animal; +typedef RTTIHandle RTTI_Mammal; +typedef RTTIHandle RTTI_Reptile; +typedef RTTIHandle RTTI_Giraffe; +typedef RTTIHandle RTTI_Tiger; +typedef RTTIHandle RTTI_Snake; +typedef RTTIHandle RTTI_Turtle; +typedef RTTIHandle RTTI_AnimalIterator; +typedef RTTIHandle RTTI_Zoo; + +namespace RTTI { + +} // namespace RTTI; + +// define legacy C-names for enums, structs and function types + +#endif // __RTTI_TYPES_HEADER_CPP diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti.cpp new file mode 100644 index 00000000..351fabd9 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti.cpp @@ -0,0 +1,54 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated C++ implementation file in order to allow easy +development of RTTI. It needs to be generated only once. + +Interface version: 1.0.0 + +*/ + +#include "rtti_abi.hpp" +#include "rtti_interfaces.hpp" +#include "rtti_interfaceexception.hpp" + +using namespace RTTI; +using namespace RTTI::Impl; + +void CWrapper::GetVersion(RTTI_uint32 & nMajor, RTTI_uint32 & nMinor, RTTI_uint32 & nMicro) +{ + nMajor = RTTI_VERSION_MAJOR; + nMinor = RTTI_VERSION_MINOR; + nMicro = RTTI_VERSION_MICRO; +} + +bool CWrapper::GetLastError(IBase* pInstance, std::string & sErrorMessage) +{ + if (pInstance) { + return pInstance->GetLastErrorMessage (sErrorMessage); + } else { + return false; + } +} + +void CWrapper::ReleaseInstance(IBase* pInstance) +{ + IBase::ReleaseBaseClassInterface(pInstance); +} + +void CWrapper::AcquireInstance(IBase* pInstance) +{ + IBase::AcquireBaseClassInterface(pInstance); +} + +IZoo * CWrapper::CreateZoo() +{ + throw ERTTIInterfaceException(RTTI_ERROR_NOTIMPLEMENTED); +} + + diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animal.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animal.cpp new file mode 100644 index 00000000..4cfd0a35 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animal.cpp @@ -0,0 +1,22 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is a stub class definition of CAnimal + +*/ + +#include "rtti_animal.hpp" +#include "rtti_interfaceexception.hpp" + +// Include custom headers here. + + +using namespace RTTI::Impl; + +/************************************************************************************************************************* + Class definition of CAnimal +**************************************************************************************************************************/ + diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animal.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animal.hpp new file mode 100644 index 00000000..251a3c02 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animal.hpp @@ -0,0 +1,67 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of CAnimal + +*/ + + +#ifndef __RTTI_ANIMAL +#define __RTTI_ANIMAL + +#include "rtti_interfaces.hpp" + +// Parent classes +#include "rtti_base.hpp" +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4250) +#endif + +// Include custom headers here. + + +namespace RTTI { +namespace Impl { + + +/************************************************************************************************************************* + Class declaration of CAnimal +**************************************************************************************************************************/ + +class CAnimal : public virtual IAnimal, public virtual CBase { +private: + + /** + * Put private members here. + */ + +protected: + + /** + * Put protected members here. + */ + +public: + + /** + * Put additional public members here. They will not be visible in the external API. + */ + + + /** + * Public member functions to implement. + */ + +}; + +} // namespace Impl +} // namespace RTTI + +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#endif // __RTTI_ANIMAL diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.cpp new file mode 100644 index 00000000..409bdbab --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.cpp @@ -0,0 +1,27 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is a stub class definition of CAnimalIterator + +*/ + +#include "rtti_animaliterator.hpp" +#include "rtti_interfaceexception.hpp" + +// Include custom headers here. + + +using namespace RTTI::Impl; + +/************************************************************************************************************************* + Class definition of CAnimalIterator +**************************************************************************************************************************/ + +IAnimal * CAnimalIterator::GetNextAnimal() +{ + throw ERTTIInterfaceException(RTTI_ERROR_NOTIMPLEMENTED); +} + diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.hpp new file mode 100644 index 00000000..fd41a6c1 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.hpp @@ -0,0 +1,69 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of CAnimalIterator + +*/ + + +#ifndef __RTTI_ANIMALITERATOR +#define __RTTI_ANIMALITERATOR + +#include "rtti_interfaces.hpp" + +// Parent classes +#include "rtti_base.hpp" +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4250) +#endif + +// Include custom headers here. + + +namespace RTTI { +namespace Impl { + + +/************************************************************************************************************************* + Class declaration of CAnimalIterator +**************************************************************************************************************************/ + +class CAnimalIterator : public virtual IAnimalIterator, public virtual CBase { +private: + + /** + * Put private members here. + */ + +protected: + + /** + * Put protected members here. + */ + +public: + + /** + * Put additional public members here. They will not be visible in the external API. + */ + + + /** + * Public member functions to implement. + */ + + IAnimal * GetNextAnimal() override; + +}; + +} // namespace Impl +} // namespace RTTI + +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#endif // __RTTI_ANIMALITERATOR diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_base.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_base.cpp new file mode 100644 index 00000000..92094e94 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_base.cpp @@ -0,0 +1,61 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is a stub class definition of CBase + +*/ + +#include "rtti_base.hpp" +#include "rtti_interfaceexception.hpp" + +// Include custom headers here. + + +using namespace RTTI::Impl; + +/************************************************************************************************************************* + Class definition of CBase +**************************************************************************************************************************/ + +bool CBase::GetLastErrorMessage(std::string & sErrorMessage) +{ + if (m_pLastError.get() != nullptr) { + sErrorMessage = *m_pLastError; + return true; + } else { + sErrorMessage = ""; + return false; + } +} + +void CBase::ClearErrorMessages() +{ + m_pLastError.reset(); +} + +void CBase::RegisterErrorMessage(const std::string & sErrorMessage) +{ + if (m_pLastError.get() == nullptr) { + m_pLastError.reset(new std::string()); + } + *m_pLastError = sErrorMessage; +} + +void CBase::IncRefCount() +{ + ++m_nReferenceCount; +} + +bool CBase::DecRefCount() +{ + m_nReferenceCount--; + if (!m_nReferenceCount) { + delete this; + return true; + } + return false; +} + diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_base.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_base.hpp new file mode 100644 index 00000000..d065e6e6 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_base.hpp @@ -0,0 +1,74 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of CBase + +*/ + + +#ifndef __RTTI_BASE +#define __RTTI_BASE + +#include "rtti_interfaces.hpp" +#include +#include +#include + + +// Include custom headers here. + + +namespace RTTI { +namespace Impl { + + +/************************************************************************************************************************* + Class declaration of CBase +**************************************************************************************************************************/ + +class CBase : public virtual IBase { +private: + + std::unique_ptr m_pLastError; + uint32_t m_nReferenceCount = 1; + + /** + * Put private members here. + */ + +protected: + + /** + * Put protected members here. + */ + +public: + + /** + * Put additional public members here. They will not be visible in the external API. + */ + + bool GetLastErrorMessage(std::string & sErrorMessage) override; + + void ClearErrorMessages() override; + + void RegisterErrorMessage(const std::string & sErrorMessage) override; + + void IncRefCount() override; + + bool DecRefCount() override; + + + /** + * Public member functions to implement. + */ + +}; + +} // namespace Impl +} // namespace RTTI + +#endif // __RTTI_BASE diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_giraffe.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_giraffe.cpp new file mode 100644 index 00000000..ca8ca759 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_giraffe.cpp @@ -0,0 +1,22 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is a stub class definition of CGiraffe + +*/ + +#include "rtti_giraffe.hpp" +#include "rtti_interfaceexception.hpp" + +// Include custom headers here. + + +using namespace RTTI::Impl; + +/************************************************************************************************************************* + Class definition of CGiraffe +**************************************************************************************************************************/ + diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_giraffe.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_giraffe.hpp new file mode 100644 index 00000000..f9d70fc0 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_giraffe.hpp @@ -0,0 +1,67 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of CGiraffe + +*/ + + +#ifndef __RTTI_GIRAFFE +#define __RTTI_GIRAFFE + +#include "rtti_interfaces.hpp" + +// Parent classes +#include "rtti_mammal.hpp" +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4250) +#endif + +// Include custom headers here. + + +namespace RTTI { +namespace Impl { + + +/************************************************************************************************************************* + Class declaration of CGiraffe +**************************************************************************************************************************/ + +class CGiraffe : public virtual IGiraffe, public virtual CMammal { +private: + + /** + * Put private members here. + */ + +protected: + + /** + * Put protected members here. + */ + +public: + + /** + * Put additional public members here. They will not be visible in the external API. + */ + + + /** + * Public member functions to implement. + */ + +}; + +} // namespace Impl +} // namespace RTTI + +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#endif // __RTTI_GIRAFFE diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_mammal.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_mammal.cpp new file mode 100644 index 00000000..a955239c --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_mammal.cpp @@ -0,0 +1,22 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is a stub class definition of CMammal + +*/ + +#include "rtti_mammal.hpp" +#include "rtti_interfaceexception.hpp" + +// Include custom headers here. + + +using namespace RTTI::Impl; + +/************************************************************************************************************************* + Class definition of CMammal +**************************************************************************************************************************/ + diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_mammal.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_mammal.hpp new file mode 100644 index 00000000..a99d4af4 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_mammal.hpp @@ -0,0 +1,67 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of CMammal + +*/ + + +#ifndef __RTTI_MAMMAL +#define __RTTI_MAMMAL + +#include "rtti_interfaces.hpp" + +// Parent classes +#include "rtti_animal.hpp" +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4250) +#endif + +// Include custom headers here. + + +namespace RTTI { +namespace Impl { + + +/************************************************************************************************************************* + Class declaration of CMammal +**************************************************************************************************************************/ + +class CMammal : public virtual IMammal, public virtual CAnimal { +private: + + /** + * Put private members here. + */ + +protected: + + /** + * Put protected members here. + */ + +public: + + /** + * Put additional public members here. They will not be visible in the external API. + */ + + + /** + * Public member functions to implement. + */ + +}; + +} // namespace Impl +} // namespace RTTI + +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#endif // __RTTI_MAMMAL diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_reptile.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_reptile.cpp new file mode 100644 index 00000000..9ec7119a --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_reptile.cpp @@ -0,0 +1,22 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is a stub class definition of CReptile + +*/ + +#include "rtti_reptile.hpp" +#include "rtti_interfaceexception.hpp" + +// Include custom headers here. + + +using namespace RTTI::Impl; + +/************************************************************************************************************************* + Class definition of CReptile +**************************************************************************************************************************/ + diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_reptile.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_reptile.hpp new file mode 100644 index 00000000..83e7bc9d --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_reptile.hpp @@ -0,0 +1,67 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of CReptile + +*/ + + +#ifndef __RTTI_REPTILE +#define __RTTI_REPTILE + +#include "rtti_interfaces.hpp" + +// Parent classes +#include "rtti_animal.hpp" +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4250) +#endif + +// Include custom headers here. + + +namespace RTTI { +namespace Impl { + + +/************************************************************************************************************************* + Class declaration of CReptile +**************************************************************************************************************************/ + +class CReptile : public virtual IReptile, public virtual CAnimal { +private: + + /** + * Put private members here. + */ + +protected: + + /** + * Put protected members here. + */ + +public: + + /** + * Put additional public members here. They will not be visible in the external API. + */ + + + /** + * Public member functions to implement. + */ + +}; + +} // namespace Impl +} // namespace RTTI + +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#endif // __RTTI_REPTILE diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_snake.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_snake.cpp new file mode 100644 index 00000000..14992979 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_snake.cpp @@ -0,0 +1,22 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is a stub class definition of CSnake + +*/ + +#include "rtti_snake.hpp" +#include "rtti_interfaceexception.hpp" + +// Include custom headers here. + + +using namespace RTTI::Impl; + +/************************************************************************************************************************* + Class definition of CSnake +**************************************************************************************************************************/ + diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_snake.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_snake.hpp new file mode 100644 index 00000000..52dfc01b --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_snake.hpp @@ -0,0 +1,67 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of CSnake + +*/ + + +#ifndef __RTTI_SNAKE +#define __RTTI_SNAKE + +#include "rtti_interfaces.hpp" + +// Parent classes +#include "rtti_reptile.hpp" +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4250) +#endif + +// Include custom headers here. + + +namespace RTTI { +namespace Impl { + + +/************************************************************************************************************************* + Class declaration of CSnake +**************************************************************************************************************************/ + +class CSnake : public virtual ISnake, public virtual CReptile { +private: + + /** + * Put private members here. + */ + +protected: + + /** + * Put protected members here. + */ + +public: + + /** + * Put additional public members here. They will not be visible in the external API. + */ + + + /** + * Public member functions to implement. + */ + +}; + +} // namespace Impl +} // namespace RTTI + +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#endif // __RTTI_SNAKE diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.cpp new file mode 100644 index 00000000..85a085a3 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.cpp @@ -0,0 +1,27 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is a stub class definition of CTiger + +*/ + +#include "rtti_tiger.hpp" +#include "rtti_interfaceexception.hpp" + +// Include custom headers here. + + +using namespace RTTI::Impl; + +/************************************************************************************************************************* + Class definition of CTiger +**************************************************************************************************************************/ + +void CTiger::Roar() +{ + throw ERTTIInterfaceException(RTTI_ERROR_NOTIMPLEMENTED); +} + diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.hpp new file mode 100644 index 00000000..b8dbbec2 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.hpp @@ -0,0 +1,69 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of CTiger + +*/ + + +#ifndef __RTTI_TIGER +#define __RTTI_TIGER + +#include "rtti_interfaces.hpp" + +// Parent classes +#include "rtti_mammal.hpp" +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4250) +#endif + +// Include custom headers here. + + +namespace RTTI { +namespace Impl { + + +/************************************************************************************************************************* + Class declaration of CTiger +**************************************************************************************************************************/ + +class CTiger : public virtual ITiger, public virtual CMammal { +private: + + /** + * Put private members here. + */ + +protected: + + /** + * Put protected members here. + */ + +public: + + /** + * Put additional public members here. They will not be visible in the external API. + */ + + + /** + * Public member functions to implement. + */ + + void Roar() override; + +}; + +} // namespace Impl +} // namespace RTTI + +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#endif // __RTTI_TIGER diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_turtle.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_turtle.cpp new file mode 100644 index 00000000..f5f097d7 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_turtle.cpp @@ -0,0 +1,22 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is a stub class definition of CTurtle + +*/ + +#include "rtti_turtle.hpp" +#include "rtti_interfaceexception.hpp" + +// Include custom headers here. + + +using namespace RTTI::Impl; + +/************************************************************************************************************************* + Class definition of CTurtle +**************************************************************************************************************************/ + diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_turtle.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_turtle.hpp new file mode 100644 index 00000000..d71de044 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_turtle.hpp @@ -0,0 +1,67 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of CTurtle + +*/ + + +#ifndef __RTTI_TURTLE +#define __RTTI_TURTLE + +#include "rtti_interfaces.hpp" + +// Parent classes +#include "rtti_reptile.hpp" +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4250) +#endif + +// Include custom headers here. + + +namespace RTTI { +namespace Impl { + + +/************************************************************************************************************************* + Class declaration of CTurtle +**************************************************************************************************************************/ + +class CTurtle : public virtual ITurtle, public virtual CReptile { +private: + + /** + * Put private members here. + */ + +protected: + + /** + * Put protected members here. + */ + +public: + + /** + * Put additional public members here. They will not be visible in the external API. + */ + + + /** + * Public member functions to implement. + */ + +}; + +} // namespace Impl +} // namespace RTTI + +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#endif // __RTTI_TURTLE diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.cpp new file mode 100644 index 00000000..8ecba8c6 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.cpp @@ -0,0 +1,27 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is a stub class definition of CZoo + +*/ + +#include "rtti_zoo.hpp" +#include "rtti_interfaceexception.hpp" + +// Include custom headers here. + + +using namespace RTTI::Impl; + +/************************************************************************************************************************* + Class definition of CZoo +**************************************************************************************************************************/ + +IAnimalIterator * CZoo::Iterator() +{ + throw ERTTIInterfaceException(RTTI_ERROR_NOTIMPLEMENTED); +} + diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.hpp new file mode 100644 index 00000000..236586cf --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.hpp @@ -0,0 +1,69 @@ +/*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of CZoo + +*/ + + +#ifndef __RTTI_ZOO +#define __RTTI_ZOO + +#include "rtti_interfaces.hpp" + +// Parent classes +#include "rtti_base.hpp" +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4250) +#endif + +// Include custom headers here. + + +namespace RTTI { +namespace Impl { + + +/************************************************************************************************************************* + Class declaration of CZoo +**************************************************************************************************************************/ + +class CZoo : public virtual IZoo, public virtual CBase { +private: + + /** + * Put private members here. + */ + +protected: + + /** + * Put protected members here. + */ + +public: + + /** + * Put additional public members here. They will not be visible in the external API. + */ + + + /** + * Public member functions to implement. + */ + + IAnimalIterator * Iterator() override; + +}; + +} // namespace Impl +} // namespace RTTI + +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#endif // __RTTI_ZOO diff --git a/Examples/RTTI/RTTI_component/license.txt b/Examples/RTTI/RTTI_component/license.txt new file mode 100644 index 00000000..3eefc675 --- /dev/null +++ b/Examples/RTTI/RTTI_component/license.txt @@ -0,0 +1,5 @@ +Copyright (C) 2020 ADSK + +All rights reserved. + + From 59cef79e4c5e100605bcec65bcfa040f06666c47 Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Mon, 7 Dec 2020 18:31:26 +0100 Subject: [PATCH 002/143] Implement stubs --- .../Implementations/Cpp/Stub/rtti.cpp | 23 ++++++++++++++++++- .../Cpp/Stub/rtti_animaliterator.cpp | 16 ++++++++++--- .../Cpp/Stub/rtti_animaliterator.hpp | 8 ++++--- .../Implementations/Cpp/Stub/rtti_tiger.cpp | 4 ++-- .../Implementations/Cpp/Stub/rtti_zoo.cpp | 10 +++++--- .../Implementations/Cpp/Stub/rtti_zoo.hpp | 6 +++-- 6 files changed, 53 insertions(+), 14 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti.cpp index 351fabd9..27d39e4d 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti.cpp @@ -17,6 +17,12 @@ Interface version: 1.0.0 #include "rtti_interfaces.hpp" #include "rtti_interfaceexception.hpp" +#include "rtti_giraffe.hpp" +#include "rtti_snake.hpp" +#include "rtti_tiger.hpp" +#include "rtti_turtle.hpp" +#include "rtti_zoo.hpp" + using namespace RTTI; using namespace RTTI::Impl; @@ -48,7 +54,22 @@ void CWrapper::AcquireInstance(IBase* pInstance) IZoo * CWrapper::CreateZoo() { - throw ERTTIInterfaceException(RTTI_ERROR_NOTIMPLEMENTED); + auto zoo = new CZoo(); + + auto& animals = zoo->Animals(); + + animals.emplace_back(new CGiraffe); + animals.emplace_back(new CTiger); + animals.emplace_back(new CTiger); + animals.emplace_back(new CSnake); + animals.emplace_back(new CTurtle); + animals.emplace_back(new CTurtle); + animals.emplace_back(new CTurtle); + animals.emplace_back(new CSnake); + animals.emplace_back(new CTiger); + animals.emplace_back(new CGiraffe); + + return zoo; } diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.cpp index 409bdbab..f7cd5cc2 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.cpp @@ -12,16 +12,26 @@ Abstract: This is a stub class definition of CAnimalIterator #include "rtti_interfaceexception.hpp" // Include custom headers here. - +#include "rtti_animal.hpp" using namespace RTTI::Impl; /************************************************************************************************************************* Class definition of CAnimalIterator **************************************************************************************************************************/ +CAnimalIterator::CAnimalIterator(std::vector::iterator begin, std::vector::iterator end) + : m_Current(begin) + , m_End(end) +{ +} IAnimal * CAnimalIterator::GetNextAnimal() { - throw ERTTIInterfaceException(RTTI_ERROR_NOTIMPLEMENTED); + if (m_Current != m_End) { + auto i = *(m_Current++); + i->IncRefCount(); + return i; + } else { + return nullptr; + } } - diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.hpp index fd41a6c1..f7ec566b 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.hpp @@ -22,11 +22,12 @@ Abstract: This is the class declaration of CAnimalIterator #endif // Include custom headers here. - +#include namespace RTTI { namespace Impl { +class CAnimal; /************************************************************************************************************************* Class declaration of CAnimalIterator @@ -38,7 +39,8 @@ class CAnimalIterator : public virtual IAnimalIterator, public virtual CBase { /** * Put private members here. */ - + std::vector::iterator m_Current; + std::vector::iterator m_End; protected: /** @@ -50,7 +52,7 @@ class CAnimalIterator : public virtual IAnimalIterator, public virtual CBase { /** * Put additional public members here. They will not be visible in the external API. */ - + CAnimalIterator(std::vector::iterator begin, std::vector::iterator end); /** * Public member functions to implement. diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.cpp index 85a085a3..d136a99c 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.cpp @@ -12,7 +12,7 @@ Abstract: This is a stub class definition of CTiger #include "rtti_interfaceexception.hpp" // Include custom headers here. - +#include using namespace RTTI::Impl; @@ -22,6 +22,6 @@ using namespace RTTI::Impl; void CTiger::Roar() { - throw ERTTIInterfaceException(RTTI_ERROR_NOTIMPLEMENTED); + std::cout << "ROAAAAARRRRR!!" << std::endl; } diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.cpp index 8ecba8c6..a27812b2 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.cpp @@ -12,7 +12,7 @@ Abstract: This is a stub class definition of CZoo #include "rtti_interfaceexception.hpp" // Include custom headers here. - +#include "rtti_animaliterator.hpp" using namespace RTTI::Impl; @@ -20,8 +20,12 @@ using namespace RTTI::Impl; Class definition of CZoo **************************************************************************************************************************/ -IAnimalIterator * CZoo::Iterator() +std::vector &CZoo::Animals() { - throw ERTTIInterfaceException(RTTI_ERROR_NOTIMPLEMENTED); + return m_Animals; } +IAnimalIterator * CZoo::Iterator() +{ + return new CAnimalIterator(m_Animals.begin(), m_Animals.end()); +} diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.hpp index 236586cf..7f62bffa 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.hpp @@ -22,12 +22,12 @@ Abstract: This is the class declaration of CZoo #endif // Include custom headers here. - +#include namespace RTTI { namespace Impl { - +class CAnimal; /************************************************************************************************************************* Class declaration of CZoo **************************************************************************************************************************/ @@ -38,6 +38,7 @@ class CZoo : public virtual IZoo, public virtual CBase { /** * Put private members here. */ + std::vector m_Animals; protected: @@ -50,6 +51,7 @@ class CZoo : public virtual IZoo, public virtual CBase { /** * Put additional public members here. They will not be visible in the external API. */ + std::vector& Animals(); /** From be3950b7a455f39fa2fb4803f1effae46b4a04c9 Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Tue, 8 Dec 2020 11:58:14 +0100 Subject: [PATCH 003/143] Add ImplementsInterface to implementation --- .../Cpp/Interfaces/rtti_abi.hpp | 10 +++ .../Cpp/Interfaces/rtti_interfacewrapper.cpp | 88 ++++++++++++++++++- 2 files changed, 96 insertions(+), 2 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp index 9e3e457e..735b4088 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp @@ -125,6 +125,16 @@ RTTI_DECLSPEC RTTIResult rtti_getversion(RTTI_uint32 * pMajor, RTTI_uint32 * pMi */ RTTI_DECLSPEC RTTIResult rtti_getlasterror(RTTI_Base pInstance, const RTTI_uint32 nErrorMessageBufferSize, RTTI_uint32* pErrorMessageNeededChars, char * pErrorMessageBuffer, bool * pHasError); +/** +* Test whether an object implements a given interface +* +* @param[in] pObject - Instance Handle +* @param[in] pClassName - Class name of the interface to test +* @param[out] pImplementsInterface - will be set to true if pInstance implements the interface, false otherwise +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_implementsinterface(RTTI_Base pInstance, const char * pClassName, bool * pImplementsInterface); + /** * Releases shared ownership of an Instance * diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp index 9fe72034..d987b776 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp @@ -195,9 +195,11 @@ RTTIResult RTTI::Impl::RTTI_GetProcAddress (const char * pProcName, void ** ppPr *ppProcAddress = (void*) &rtti_zoo_iterator; if (sProcName == "rtti_getversion") *ppProcAddress = (void*) &rtti_getversion; - if (sProcName == "rtti_getlasterror") + if (sProcName == "rtti_getlasterror") *ppProcAddress = (void*) &rtti_getlasterror; - if (sProcName == "rtti_releaseinstance") + if (sProcName == "rtti_implementsinterface") + *ppProcAddress = (void*) &rtti_implementsinterface; + if (sProcName == "rtti_releaseinstance") *ppProcAddress = (void*) &rtti_releaseinstance; if (sProcName == "rtti_acquireinstance") *ppProcAddress = (void*) &rtti_acquireinstance; @@ -213,6 +215,88 @@ RTTIResult RTTI::Impl::RTTI_GetProcAddress (const char * pProcName, void ** ppPr return RTTI_SUCCESS; } +/************************************************************************************************************************* + RTTI implementation +**************************************************************************************************************************/ + +RTTIResult rtti_implementsinterface(RTTI_Base pInstance, const char * pClassName, bool * pImplementsInterface) +{ + IBase* pIBaseClassInstance = (IBase *)pInstance; + std::string sClassName(pClassName); + + // TODO: Optimize these lookups in a static (generated) way + switch (pClassName[0]) { + case 'a': + case 'A': + if (sClassName == "Animal") { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + if (sClassName == "AnimalIterator") { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + break; + case 'b': + case 'B': + if (sClassName == "Base") { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + break; + case 'g': + case 'G': + if (sClassName == "Giraffe") { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + break; + case 'm': + case 'M': + if (sClassName == "Mammal") { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + break; + case 'r': + case 'R': + if (sClassName == "Reptile") { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + break; + case 's': + case 'S': + if (sClassName == "Snake") { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + break; + case 't': + case 'T': + if (sClassName == "Tiger") { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + if (sClassName == "Turtle") { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + break; + case 'z': + case 'Z': + if (sClassName == "Zoo") { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + break; + default: + break; + } + + return RTTI_ERROR_INVALIDPARAM; +} + /************************************************************************************************************************* Global functions implementation **************************************************************************************************************************/ From 1524a7f420a215a158c0dee7e7bcc2fa03ae4a43 Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Tue, 8 Dec 2020 12:08:26 +0100 Subject: [PATCH 004/143] Add casts to bindings and examples --- .../Bindings/CppDynamic/rtti_dynamic.h | 11 +++ .../Bindings/CppDynamic/rtti_dynamic.hpp | 87 +++++++++++++++--- .../RTTI_component/Bindings/Python/RTTI.py | 77 +++++++++++++++- .../Python/__pycache__/RTTI.cpython-38.pyc | Bin 11311 -> 13262 bytes .../Examples/CppDynamic/RTTI_example.cpp | 12 +++ .../Examples/Python/RTTI_Example.py | 7 ++ 6 files changed, 176 insertions(+), 18 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h index 55c81793..22001b34 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h @@ -112,6 +112,16 @@ typedef RTTIResult (*PRTTIGetVersionPtr) (RTTI_uint32 * pMajor, RTTI_uint32 * pM */ typedef RTTIResult (*PRTTIGetLastErrorPtr) (RTTI_Base pInstance, const RTTI_uint32 nErrorMessageBufferSize, RTTI_uint32* pErrorMessageNeededChars, char * pErrorMessageBuffer, bool * pHasError); +/** +* Test whether an object implements a given interface +* +* @param[in] pObject - Instance Handle +* @param[in] pClassName - Class name of the interface to test +* @param[out] pImplementsInterface - will be set to true if pInstance implements the interface, false otherwise +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIImplementsInterfacePtr) (RTTI_Base pInstance, const char * pClassName, bool * pImplementsInterface); + /** * Releases shared ownership of an Instance * @@ -164,6 +174,7 @@ typedef struct { PRTTIZoo_IteratorPtr m_Zoo_Iterator; PRTTIGetVersionPtr m_GetVersion; PRTTIGetLastErrorPtr m_GetLastError; + PRTTIImplementsInterfacePtr m_ImplementsInterface; PRTTIReleaseInstancePtr m_ReleaseInstance; PRTTIAcquireInstancePtr m_AcquireInstance; PRTTIInjectComponentPtr m_InjectComponent; diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp index 64965c21..04f482b4 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp @@ -92,6 +92,11 @@ typedef PTurtle PRTTITurtle; typedef PAnimalIterator PRTTIAnimalIterator; typedef PZoo PRTTIZoo; +/************************************************************************************************************************* + rtti_cast Definition +**************************************************************************************************************************/ +template +inline std::shared_ptr rtti_cast(PBase obj); /************************************************************************************************************************* classParam Definition @@ -238,6 +243,7 @@ class CWrapper { } inline void CheckError(CBase * pBaseClass, RTTIResult nResult); + inline bool ImplementsInterface(CBase *pBaseClass, const std::string& sClassname); inline void GetVersion(RTTI_uint32 & nMajor, RTTI_uint32 & nMinor, RTTI_uint32 & nMicro); inline bool GetLastError(classParam pInstance, std::string & sErrorMessage); @@ -283,7 +289,7 @@ class CWrapper { **************************************************************************************************************************/ class CBase { public: - + static const std::string CLASSNAME; protected: /* Wrapper Object that created the class. */ CWrapper * m_pWrapper; @@ -332,6 +338,8 @@ class CBase { } friend class CWrapper; + template + friend std::shared_ptr rtti_cast(PBase obj); }; /************************************************************************************************************************* @@ -339,7 +347,8 @@ class CBase { **************************************************************************************************************************/ class CAnimal : public CBase { public: - + static const std::string CLASSNAME; + /** * CAnimal::CAnimal - Constructor for Animal class. */ @@ -355,7 +364,8 @@ class CAnimal : public CBase { **************************************************************************************************************************/ class CMammal : public CAnimal { public: - + static const std::string CLASSNAME; + /** * CMammal::CMammal - Constructor for Mammal class. */ @@ -371,7 +381,8 @@ class CMammal : public CAnimal { **************************************************************************************************************************/ class CReptile : public CAnimal { public: - + static const std::string CLASSNAME; + /** * CReptile::CReptile - Constructor for Reptile class. */ @@ -387,7 +398,8 @@ class CReptile : public CAnimal { **************************************************************************************************************************/ class CGiraffe : public CMammal { public: - + static const std::string CLASSNAME; + /** * CGiraffe::CGiraffe - Constructor for Giraffe class. */ @@ -403,7 +415,8 @@ class CGiraffe : public CMammal { **************************************************************************************************************************/ class CTiger : public CMammal { public: - + static const std::string CLASSNAME; + /** * CTiger::CTiger - Constructor for Tiger class. */ @@ -420,7 +433,8 @@ class CTiger : public CMammal { **************************************************************************************************************************/ class CSnake : public CReptile { public: - + static const std::string CLASSNAME; + /** * CSnake::CSnake - Constructor for Snake class. */ @@ -436,7 +450,8 @@ class CSnake : public CReptile { **************************************************************************************************************************/ class CTurtle : public CReptile { public: - + static const std::string CLASSNAME; + /** * CTurtle::CTurtle - Constructor for Turtle class. */ @@ -452,7 +467,8 @@ class CTurtle : public CReptile { **************************************************************************************************************************/ class CAnimalIterator : public CBase { public: - + static const std::string CLASSNAME; + /** * CAnimalIterator::CAnimalIterator - Constructor for AnimalIterator class. */ @@ -469,7 +485,8 @@ class CAnimalIterator : public CBase { **************************************************************************************************************************/ class CZoo : public CBase { public: - + static const std::string CLASSNAME; + /** * CZoo::CZoo - Constructor for Zoo class. */ @@ -480,7 +497,30 @@ class CZoo : public CBase { inline PAnimalIterator Iterator(); }; - + + const std::string CBase::CLASSNAME = "Base"; + const std::string CAnimal::CLASSNAME = "Animal"; + const std::string CMammal::CLASSNAME = "Mammal"; + const std::string CReptile::CLASSNAME = "Reptile"; + const std::string CGiraffe::CLASSNAME = "Giraffe"; + const std::string CTiger::CLASSNAME = "Tiger"; + const std::string CSnake::CLASSNAME = "Snake"; + const std::string CTurtle::CLASSNAME = "Turtle"; + const std::string CAnimalIterator::CLASSNAME = "AnimalIterator"; + const std::string CZoo::CLASSNAME = "Zoo"; + + template + std::shared_ptr rtti_cast(PBase pObj) + { + static_assert(std::is_convertible::value, "T must be convertible to RTTI::CBase"); + + if (pObj && pObj->m_pWrapper->ImplementsInterface(pObj.get(), T::CLASSNAME)){ + return std::make_shared(pObj->m_pWrapper, pObj->m_pHandle); + } + + return nullptr; + } + /** * CWrapper::GetVersion - retrieves the binary version of this library. * @param[out] nMajor - returns the major version of this library @@ -583,7 +623,15 @@ class CZoo : public CBase { throw ERTTIException(nResult, sErrorMessage); } } - + + inline bool CWrapper::ImplementsInterface(CBase *pBaseClass, const std::string& sClassname) + { + bool resultImplementsInterface = false; + CheckError(nullptr,m_WrapperTable.m_ImplementsInterface(pBaseClass->m_pHandle, sClassname.c_str(), &resultImplementsInterface)); + + return resultImplementsInterface; + } + inline RTTIResult CWrapper::initWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable) { @@ -596,6 +644,7 @@ class CZoo : public CBase { pWrapperTable->m_Zoo_Iterator = nullptr; pWrapperTable->m_GetVersion = nullptr; pWrapperTable->m_GetLastError = nullptr; + pWrapperTable->m_ImplementsInterface = nullptr; pWrapperTable->m_ReleaseInstance = nullptr; pWrapperTable->m_AcquireInstance = nullptr; pWrapperTable->m_InjectComponent = nullptr; @@ -684,7 +733,7 @@ class CZoo : public CBase { #endif // _WIN32 if (pWrapperTable->m_GetVersion == nullptr) return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; - + #ifdef _WIN32 pWrapperTable->m_GetLastError = (PRTTIGetLastErrorPtr) GetProcAddress(hLibrary, "rtti_getlasterror"); #else // _WIN32 @@ -693,7 +742,17 @@ class CZoo : public CBase { #endif // _WIN32 if (pWrapperTable->m_GetLastError == nullptr) return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; - + + #ifdef _WIN32 + pWrapperTable->m_ImplementsInterface = (PRTTIImplementsInterfacePtr) GetProcAddress(hLibrary, "rtti_implementsinterface"); + #else // _WIN32 + pWrapperTable->m_ImplementsInterface = (PRTTIImplementsInterfacePtr) dlsym(hLibrary, "rtti_implementsinterface"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_ImplementsInterface == nullptr) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 pWrapperTable->m_ReleaseInstance = (PRTTIReleaseInstancePtr) GetProcAddress(hLibrary, "rtti_releaseinstance"); #else // _WIN32 diff --git a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py index ddd1f9fc..86961d61 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py +++ b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py @@ -58,6 +58,7 @@ class ErrorCodes(enum.IntEnum): class FunctionTable: rtti_getversion = None rtti_getlasterror = None + rtti_implementsinterface = None rtti_releaseinstance = None rtti_acquireinstance = None rtti_injectcomponent = None @@ -114,13 +115,19 @@ def _loadFunctionTableFromMethod(self, symbolLookupMethodAddress): raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32)) self.lib.rtti_getversion = methodType(int(methodAddress.value)) - + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_getlasterror")), methodAddress) if err != 0: raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.c_uint64, ctypes.POINTER(ctypes.c_uint64), ctypes.c_char_p, ctypes.POINTER(ctypes.c_bool)) self.lib.rtti_getlasterror = methodType(int(methodAddress.value)) - + + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_implementsinterface")), methodAddress) + if err != 0: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.c_char_p, ctypes.POINTER(ctypes.c_bool)) + self.lib.rtti_implementsinterface = methodType(int(methodAddress.value)) + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_releaseinstance")), methodAddress) if err != 0: raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) @@ -179,7 +186,10 @@ def _loadFunctionTable(self): self.lib.rtti_getlasterror.restype = ctypes.c_int32 self.lib.rtti_getlasterror.argtypes = [ctypes.c_void_p, ctypes.c_uint64, ctypes.POINTER(ctypes.c_uint64), ctypes.c_char_p, ctypes.POINTER(ctypes.c_bool)] - + + self.lib.rtti_implementsinterface.restype = ctypes.c_int32 + self.lib.rtti_implementsinterface.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.POINTER(ctypes.c_bool)] + self.lib.rtti_releaseinstance.restype = ctypes.c_int32 self.lib.rtti_releaseinstance.argtypes = [ctypes.c_void_p] @@ -244,7 +254,21 @@ def GetLastError(self, InstanceObject): self.checkError(None, self.lib.rtti_getlasterror(InstanceHandle, nErrorMessageBufferSize, nErrorMessageNeededChars, pErrorMessageBuffer, pHasError)) return pErrorMessageBuffer.value.decode(), pHasError.value - + + def ImplementsInterface(self, InstanceObject, ClassName): + InstanceHandle = None + if InstanceObject: + InstanceHandle = InstanceObject._handle + else: + return False + + pImplementsInterface = ctypes.c_bool() + pClassName = ctypes.c_char_p(str.encode(ClassName)) + + self.checkError(None, self.lib.rtti_implementsinterface(InstanceHandle, pClassName, pImplementsInterface)) + + return pImplementsInterface.value + def ReleaseInstance(self, InstanceObject): InstanceHandle = None if InstanceObject: @@ -294,6 +318,10 @@ def CreateZoo(self): ''' Class Implementation for Base ''' class Base: + @staticmethod + def ClassName(): + return "Base" + def __init__(self, handle, wrapper): if not handle or not wrapper: raise ERTTIException(ErrorCodes.INVALIDPARAM) @@ -303,10 +331,19 @@ def __init__(self, handle, wrapper): def __del__(self): self._wrapper.ReleaseInstance(self) + @classmethod + def cast(cls, instance): + if instance and instance._wrapper.ImplementsInterface(instance, cls.ClassName()): + return Tiger(instance._handle, instance._wrapper) + return None ''' Class Implementation for Animal ''' class Animal(Base): + @staticmethod + def ClassName(): + return "Animal" + def __init__(self, handle, wrapper): Base.__init__(self, handle, wrapper) @@ -314,6 +351,10 @@ def __init__(self, handle, wrapper): ''' Class Implementation for Mammal ''' class Mammal(Animal): + @staticmethod + def ClassName(): + return "Mammal" + def __init__(self, handle, wrapper): Animal.__init__(self, handle, wrapper) @@ -321,6 +362,10 @@ def __init__(self, handle, wrapper): ''' Class Implementation for Reptile ''' class Reptile(Animal): + @staticmethod + def ClassName(): + return "Reptile" + def __init__(self, handle, wrapper): Animal.__init__(self, handle, wrapper) @@ -328,6 +373,10 @@ def __init__(self, handle, wrapper): ''' Class Implementation for Giraffe ''' class Giraffe(Mammal): + @staticmethod + def ClassName(): + return "Giraffe" + def __init__(self, handle, wrapper): Mammal.__init__(self, handle, wrapper) @@ -335,6 +384,10 @@ def __init__(self, handle, wrapper): ''' Class Implementation for Tiger ''' class Tiger(Mammal): + @staticmethod + def ClassName(): + return "Tiger" + def __init__(self, handle, wrapper): Mammal.__init__(self, handle, wrapper) def Roar(self): @@ -346,6 +399,10 @@ def Roar(self): ''' Class Implementation for Snake ''' class Snake(Reptile): + @staticmethod + def ClassName(): + return "Snake" + def __init__(self, handle, wrapper): Reptile.__init__(self, handle, wrapper) @@ -353,6 +410,10 @@ def __init__(self, handle, wrapper): ''' Class Implementation for Turtle ''' class Turtle(Reptile): + @staticmethod + def ClassName(): + return "Turtle" + def __init__(self, handle, wrapper): Reptile.__init__(self, handle, wrapper) @@ -360,6 +421,10 @@ def __init__(self, handle, wrapper): ''' Class Implementation for AnimalIterator ''' class AnimalIterator(Base): + @staticmethod + def ClassName(): + return "AnimalIterator" + def __init__(self, handle, wrapper): Base.__init__(self, handle, wrapper) def GetNextAnimal(self): @@ -377,6 +442,10 @@ def GetNextAnimal(self): ''' Class Implementation for Zoo ''' class Zoo(Base): + @staticmethod + def ClassName(): + return "Zoo" + def __init__(self, handle, wrapper): Base.__init__(self, handle, wrapper) def Iterator(self): diff --git a/Examples/RTTI/RTTI_component/Bindings/Python/__pycache__/RTTI.cpython-38.pyc b/Examples/RTTI/RTTI_component/Bindings/Python/__pycache__/RTTI.cpython-38.pyc index 00cb7ea83cd56eaa6d70601d73333f4b2cf1e16a..ccf3dfa888ea4a098e80e9c53502eb72c7fa46c6 100644 GIT binary patch delta 4174 zcmbVPZ){sv6@T~n*?xB7KdBSPaU924lQeF#Y{{~<0lGHb+N`Yc#*(J1tJQt+b3D7T z9j;$!=Q#_k6@_VM#-`o9YQDq98 zR;S!wK|UqLnJ&d;Jp`|-nk%UHUzXw?alpXMPt<~phZZ`5>;$~jaZZgZl5|xmg>HV- zahQ1xDQhvLEd}pg6;@GT+VueYF8snh39q{%?3UpEhTIpB>xVzMf-vWfu-Cxr-VfK2 zyCt~W$Q==~^PUL%7IGn&@C*(G%VgbR*tb-@6YaCIa!KB>maV#c-g4E#|6Y^qKPBZK zQY0gE-g#Bwi%i^1jPnrvyQY3|J?PEDwG@*2KV}ca+<+{Z`@fE?}1rg@9v(2y$Z*V za2Wp;!eIhVuMx=hm030j*L`~)>*oj2OMZ;V!$kHViQ9RqXgs%;;*ZhN30hJ$o~ETD zAEUM7L}Endh&%!A?(tCy3V)J_g-C$NFp)1IiOO6hegSUSe4)e0zKy@)6cULktdot& zoop}uLh$wOKUmn|G zc=LSk7#kLn4Q@8;2qg3H)4(yy+M50R@mNMgBj307& zg-YCDTXIF(Q1EUslr3vnrZU44leTQSgz3c6D_hFevQn{BWG0oBtb;l)b}Z`TXV9pb zf+vWZlQxmMiG7?%9bc3l=aEEhW*nbEe%tZLs#YwnhdY@E$xq^Qq*q3 zsu#f!t~OxVi;r(w>M;0O2nTmFFL?Sxa5lKSPix1@J~Fxte?iSY)cmoTY*CK&0E#-T zM{yiJ=zp2r18bpmvx-{w?8;7F<-v|j$9A<`EWGCRmfk7LEoj(Ka@Bo{F z@$fjJI5*OBV3w8-6QM#ju~S`gDl~qMNRo(7Bt>L}$g@xh2cpyyRBgo|5>Q!nD|iua#h*Btx)XbCn0jrC zm2ntSpH*Z&Y+w&&6kjb;+xKrTrKjaX|vu0 z%c2XEq*gRygoip_lKsrhN)CZZ>_i>Bi}ZF8@gdpnEE<}TN#;_dNX~fl}I^!S%y*0G+2YnK>=0O|{63f@&u5WCXYFoQ^RFx8mOg>{I60tXJEs^1CWFi5vp#dL9 zc4;T7CTO@m;-`vj8|=K6Ya8r(6WHaN-*U-onrQ}0?lpkjO<-4QN(i>9R0GQm%4N?w z%4yB8I38_gaVdhkZDi5@RBFx0thU*C7j}>hQ5thKC*@LC)lMDS&qw#$=%b8_6j}+@ zm*Mt3VJ5tXC!>mIwb^^nq9Q46`#zW9+R93szF%ze{bHl2ZZ(X)OAR1AV#d@VQ23uC z2=(w^fwzax_K4Y3e-+(FGG}lS1`a7t6*T_MnoU-6nl@=UhHum6*;DN>QWqnqL`B(~ z!{-;t1bwem2aIeYqJCS9;PTx=A%=@}A+McpGqKM%#pJb`|8mJAtkh#dX}y3BG^AD3 z<#*t7qam{{d!EPrSILI>=n@l>;|ZT}HZHDnqur+3*zsS?#%m4!drdQS0F=}+0T4+Q zlcG|S$4OC@Z>`P^RQX;DCOp-|l=^Jdx$QP*?{WM`Ofw4N^8wA*FFfbYx_w~>;}{K& zH)=l1r9iW}W~@aNZYba%z<>5!F~6_GM^H;C-%rxwRnOs#u}9gD;ICuTL!VZ+o1$)C zK;7??TTOL~ZvTHRoc`Y}j9X?44^Sw6)({F;yim9+{$IksqZ<<%szo~*z6D#tFj)%& zfr8ruet2i^4Er^Fym$Chqw!UW#*s8CzH>)3Xf@iqZBHchLNbvsJ$Miox0O_WJ;(P8 zHc$Tr9D*zRh8~~~NG{&x;vFX@s^~u&mz+igr*`91pPZcK6r5i8Xy0hB*S#rSaQnR- K)jyB8_xu;{*=!I1 delta 2597 zcmb7EUu;ul6u;kH+k5+W>$B#%Al#@~{%+N68DwCwHNqvUpS=r@t-Wv`rJvzPOEXN`+|X+CvoJii?Se&= z&;q6VDE+3{25SAR4{d$$O|2J}@asnL%QtvN$n@(3wRzTbqlQ0W!X=3b%T20LHKjZ& zQpy__HwkZxZ?QANP9cuk%hH5!R>+7G_=TZZfYke!|f9Lq~rn8WxoGWrhwiOc~3JMfl6n?Jq{xh|w|r5k|+f=$ce#%C*8$n_#*j zaMaEBB1L|fV1OWi5Rtf&Qu!CSM68>@ zT?Fj}rxAi8mq{LhI|hgAB@}PtliP+MFdeh7PSL_bFxvP~zaN(#z+lrIHVl6@4Y4tJ z!Rcc^!CB|~ZjC9C;S&TUx_lUzE36;I#a~u;yE<9BW?9B=;~p)5VYs^KWBseB`5ijk zd*FlS@$gyv3Q9ae=Idd!ZrmNj&rfR#0i6Sz-v#}iI`OFhM?IIi&R26nhz^XxV^14n z(BS>5Kv&D7ja0`8v;?om*#!^1*O>_xd<%s+sUe)z(GKlln)Y6DLIv_P!XyCr>7sX@v12crX0g*3c`W$spN!5K6Oz z#l@>aq$XYy*Wp_i$HE52UxiJG^X;BD1Gazqiawx@s@dh%&Dx=YVzeOPq#2Uytb!d>QZ+J!DaJu*^fYdJjWM z9-Em#4|~kSvoekoAO+XF%%lEznU{I;5-!!Jibm3pB@+tAGVPT3>l?!vf!9Lk8?{zi zznL_}cmzAki^J+s$mM)?1Ld?db2NU1=oK4CgwtD^f+c$Y(LVaoOl($50VT3B1(Pt@ z?I|W&Mg6(56sVMfP&GabV+&j@R&s&7tXDD)pKV?1m5ZpFE^}~^9K2X^P(_Yyg}ZP} zRd`Iz7Lz@@(c>)C_gpKCMs0poq`il%wQHV&yFG_k8pQ2=&&mB8+T~ru9jWr%^F<=Q z{eKYWaXh2Y8Wn6;;CgRy{F}>$ZUyP>CDMz~7an1k;aa%;Ii#0}^geR<<_6NV5_IMz z99Y@uXtdz04;S+~C9{y`{hFAGr4_ypI(D?~poz=1iK7hx?FMN*M0bT#M{;TzPG#kk cBpyfCPPnGetVersion(nMajor, nMinor, nMicro); std::cout << "RTTI.Version = " << nMajor << "." << nMinor << "." << nMicro; std::cout << std::endl; + + + auto zoo = wrapper->CreateZoo(); + auto iter = zoo->Iterator(); + + using namespace RTTI; + while (auto animal = iter->GetNextAnimal()) { + std::cout << "Animal: 0x" << std::hex << animal->handle() << std::endl; + if (auto tiger = rtti_cast(animal)) { + tiger->Roar(); + } + } } catch (std::exception &e) { diff --git a/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py b/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py index 6327a52e..1be17f6e 100644 --- a/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py +++ b/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py @@ -28,6 +28,13 @@ def main(): print("RTTI version: {:d}.{:d}.{:d}".format(major, minor, micro), end="") print("") + zoo = wrapper.CreateZoo() + iter = zoo.Iterator() + + while animal := iter.GetNextAnimal(): + print("animal: " + str(animal._handle)) + if tiger := RTTI.Tiger.cast(animal): + tiger.Roar() if __name__ == "__main__": try: From c21150b99a6a62587763916028ed16feab2a3345 Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Tue, 8 Dec 2020 14:26:39 +0100 Subject: [PATCH 005/143] Change Cpp binding static member var to function --- .../Bindings/CppDynamic/rtti_dynamic.hpp | 82 ++++++++++++++----- 1 file changed, 61 insertions(+), 21 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp index 04f482b4..9700b38b 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp @@ -289,7 +289,7 @@ class CWrapper { **************************************************************************************************************************/ class CBase { public: - static const std::string CLASSNAME; + static const std::string &getClassName(); protected: /* Wrapper Object that created the class. */ CWrapper * m_pWrapper; @@ -347,7 +347,7 @@ class CBase { **************************************************************************************************************************/ class CAnimal : public CBase { public: - static const std::string CLASSNAME; + static const std::string &getClassName(); /** * CAnimal::CAnimal - Constructor for Animal class. @@ -364,7 +364,7 @@ class CAnimal : public CBase { **************************************************************************************************************************/ class CMammal : public CAnimal { public: - static const std::string CLASSNAME; + static const std::string &getClassName(); /** * CMammal::CMammal - Constructor for Mammal class. @@ -381,7 +381,7 @@ class CMammal : public CAnimal { **************************************************************************************************************************/ class CReptile : public CAnimal { public: - static const std::string CLASSNAME; + static const std::string &getClassName(); /** * CReptile::CReptile - Constructor for Reptile class. @@ -398,7 +398,7 @@ class CReptile : public CAnimal { **************************************************************************************************************************/ class CGiraffe : public CMammal { public: - static const std::string CLASSNAME; + static const std::string &getClassName(); /** * CGiraffe::CGiraffe - Constructor for Giraffe class. @@ -415,7 +415,7 @@ class CGiraffe : public CMammal { **************************************************************************************************************************/ class CTiger : public CMammal { public: - static const std::string CLASSNAME; + static const std::string &getClassName(); /** * CTiger::CTiger - Constructor for Tiger class. @@ -433,7 +433,7 @@ class CTiger : public CMammal { **************************************************************************************************************************/ class CSnake : public CReptile { public: - static const std::string CLASSNAME; + static const std::string &getClassName(); /** * CSnake::CSnake - Constructor for Snake class. @@ -450,7 +450,7 @@ class CSnake : public CReptile { **************************************************************************************************************************/ class CTurtle : public CReptile { public: - static const std::string CLASSNAME; + static const std::string &getClassName(); /** * CTurtle::CTurtle - Constructor for Turtle class. @@ -467,7 +467,7 @@ class CTurtle : public CReptile { **************************************************************************************************************************/ class CAnimalIterator : public CBase { public: - static const std::string CLASSNAME; + static const std::string &getClassName(); /** * CAnimalIterator::CAnimalIterator - Constructor for AnimalIterator class. @@ -485,7 +485,7 @@ class CAnimalIterator : public CBase { **************************************************************************************************************************/ class CZoo : public CBase { public: - static const std::string CLASSNAME; + static const std::string &getClassName(); /** * CZoo::CZoo - Constructor for Zoo class. @@ -498,23 +498,63 @@ class CZoo : public CBase { inline PAnimalIterator Iterator(); }; - const std::string CBase::CLASSNAME = "Base"; - const std::string CAnimal::CLASSNAME = "Animal"; - const std::string CMammal::CLASSNAME = "Mammal"; - const std::string CReptile::CLASSNAME = "Reptile"; - const std::string CGiraffe::CLASSNAME = "Giraffe"; - const std::string CTiger::CLASSNAME = "Tiger"; - const std::string CSnake::CLASSNAME = "Snake"; - const std::string CTurtle::CLASSNAME = "Turtle"; - const std::string CAnimalIterator::CLASSNAME = "AnimalIterator"; - const std::string CZoo::CLASSNAME = "Zoo"; + const std::string &CBase::getClassName() +{ + static const std::string s_sClassName = "Base"; + return s_sClassName; + } + const std::string &CAnimal::getClassName() + { + static const std::string s_sClassName = "Animal"; + return s_sClassName; + } + const std::string &CMammal::getClassName() + { + static const std::string s_sClassName = "Mammal"; + return s_sClassName; + } + const std::string &CReptile::getClassName() + { + static const std::string s_sClassName = "Reptile"; + return s_sClassName; + } + const std::string &CGiraffe::getClassName() + { + static const std::string s_sClassName = "Giraffe"; + return s_sClassName; + } + const std::string &CTiger::getClassName() + { + static const std::string s_sClassName = "Tiger"; + return s_sClassName; + } + const std::string &CSnake::getClassName() + { + static const std::string s_sClassName = "Snake"; + return s_sClassName; + } + const std::string &CTurtle::getClassName() + { + static const std::string s_sClassName = "Turtle"; + return s_sClassName; + } + const std::string &CAnimalIterator::getClassName() + { + static const std::string s_sClassName = "AnimalIterator"; + return s_sClassName; + } + const std::string &CZoo::getClassName() + { + static const std::string s_sClassName = "Zoo"; + return s_sClassName; + } template std::shared_ptr rtti_cast(PBase pObj) { static_assert(std::is_convertible::value, "T must be convertible to RTTI::CBase"); - if (pObj && pObj->m_pWrapper->ImplementsInterface(pObj.get(), T::CLASSNAME)){ + if (pObj && pObj->m_pWrapper->ImplementsInterface(pObj.get(), T::getClassName())){ return std::make_shared(pObj->m_pWrapper, pObj->m_pHandle); } From 6a5743fb7b06052f0b7dc2f7e200d8f0f6b2f61c Mon Sep 17 00:00:00 2001 From: Martin Weismann Date: Tue, 15 Dec 2020 17:44:45 +0100 Subject: [PATCH 006/143] Autogenerate skeleton for ImplementsInterfaceMethod --- Examples/RTTI/RTTI.xml | 7 ++++- Source/buildimplementationcpp.go | 51 +++++++++++++++++++++++++++++--- Source/componentdefinition.go | 22 +++++++++++++- 3 files changed, 74 insertions(+), 6 deletions(-) diff --git a/Examples/RTTI/RTTI.xml b/Examples/RTTI/RTTI.xml index 42008c32..cf7cd4ae 100644 --- a/Examples/RTTI/RTTI.xml +++ b/Examples/RTTI/RTTI.xml @@ -68,7 +68,7 @@ + symbollookupmethod="GetSymbolLookupMethod" implementsinterfacemethod="ImplementsInterface"> @@ -92,6 +92,11 @@ + + + + + diff --git a/Source/buildimplementationcpp.go b/Source/buildimplementationcpp.go index 71fae07f..f25fc437 100644 --- a/Source/buildimplementationcpp.go +++ b/Source/buildimplementationcpp.go @@ -566,7 +566,7 @@ func buildCPPInterfaces(component ComponentDefinition, w LanguageWriter, NameSpa return err } if (isSpecialFunction == eSpecialMethodJournal) || (isSpecialFunction == eSpecialMethodInjection) || - (isSpecialFunction == eSpecialMethodSymbolLookup) { + (isSpecialFunction == eSpecialMethodSymbolLookup) || (isSpecialFunction == eSpecialMethodImplementsInterface ) { continue } @@ -624,7 +624,7 @@ func buildCPPGlobalStubFile(component ComponentDefinition, stubfile LanguageWrit return err } if (isSpecialFunction == eSpecialMethodJournal) || (isSpecialFunction == eSpecialMethodInjection) || - (isSpecialFunction == eSpecialMethodSymbolLookup) { + (isSpecialFunction == eSpecialMethodSymbolLookup) || (isSpecialFunction == eSpecialMethodImplementsInterface) { continue } if (isSpecialFunction == eSpecialMethodVersion) { @@ -691,6 +691,38 @@ func buildCPPInterfaceWrapperMethods(component ComponentDefinition, class Compon return nil } +func writeCImplementsInterfaceMethod(method ComponentDefinitionMethod, w LanguageWriter, NameSpace string) error { + cParams, err := GenerateCParameters(method, "", NameSpace) + if err != nil { + return err + } + + cparameters := "" + for _, cParam := range cParams { + if cparameters != "" { + cparameters = cparameters + ", " + } + cparameters = cparameters + cParam.ParamType + " " + cParam.ParamName + } + + CMethodName := fmt.Sprintf("%s_%s", strings.ToLower(NameSpace), strings.ToLower(method.MethodName)) + + w.Writeln("") + w.Writeln("/*************************************************************************************************************************") + w.Writeln(" %s", method.MethodDescription) + w.Writeln("**************************************************************************************************************************/") + w.Writeln("") + + w.Writeln("%sResult %s(%s)", NameSpace, CMethodName, cparameters) + w.Writeln("{") + w.Writeln(" // TODO") + w.Writeln(" return %s_SUCCESS;", strings.ToUpper (NameSpace)) + w.Writeln("}") + w.Writeln("") + + return nil +} + func buildCPPGetSymbolAddressMethod(component ComponentDefinition, w LanguageWriter, NameSpace string, NameSpaceImplementation string) error { w.Writeln("") @@ -719,8 +751,9 @@ func buildCPPGetSymbolAddressMethod(component ComponentDefinition, w LanguageWri method := global.Methods[j] procName := strings.ToLower(method.MethodName) - processfuncMap = append (processfuncMap, fmt.Sprintf("%s_%s", strings.ToLower(NameSpace), procName)); + processfuncMap = append (processfuncMap, fmt.Sprintf("%s_%s", strings.ToLower(NameSpace), procName)); } + w.Writeln("if (pProcName == nullptr)") w.Writeln(" return %s_ERROR_INVALIDPARAM;", strings.ToUpper(NameSpace)) @@ -850,7 +883,7 @@ func buildCPPInterfaceWrapper(component ComponentDefinition, w LanguageWriter, N method := global.Methods[j] // Check for special functions - isSpecialFunction, err := CheckHeaderSpecialFunction (method, global); + isSpecialFunction, err := CheckHeaderSpecialFunction(method, global); if err != nil { return err } @@ -861,6 +894,16 @@ func buildCPPInterfaceWrapper(component ComponentDefinition, w LanguageWriter, N doMethodJournal = false; } + + if (isSpecialFunction == eSpecialMethodImplementsInterface) { + err = writeCImplementsInterfaceMethod(method, w, NameSpace) + if err != nil { + return err + } + continue + } + + // Write Static function implementation err = writeCImplementationMethod(component, method, w, BaseName, NameSpace, NameSpaceImplementation, ClassIdentifier, "Wrapper", component.Global.BaseClassName, true, doMethodJournal, isSpecialFunction, false) if err != nil { diff --git a/Source/componentdefinition.go b/Source/componentdefinition.go index 908cb972..aa484fc2 100644 --- a/Source/componentdefinition.go +++ b/Source/componentdefinition.go @@ -58,6 +58,7 @@ const ( eSpecialMethodJournal = 7 eSpecialMethodPrerelease = 8 eSpecialMethodBuildinfo = 9 + eSpecialMethodImplementsInterface = 10 ) // ComponentDefinitionParam definition of a method parameter used in the component's API @@ -118,6 +119,7 @@ type ComponentDefinitionGlobal struct { BaseClassName string `xml:"baseclassname,attr"` StringOutBaseClassName string `xml:"stringoutclassname,attr"` ErrorMethod string `xml:"errormethod,attr"` + ImplementsInterfaceMethod string `xml:"implementsinterfacemethod,attr"` ReleaseMethod string `xml:"releasemethod,attr"` AcquireMethod string `xml:"acquiremethod,attr"` SymbolLookupMethod string `xml:"symbollookupmethod,attr"` @@ -1016,6 +1018,10 @@ func CheckHeaderSpecialFunction (method ComponentDefinitionMethod, global Compon return eSpecialMethodNone, errors.New ("No error method specified"); } + if (global.ImplementsInterfaceMethod == "") { + return eSpecialMethodNone, errors.New ("No implements inteface method specified"); + } + if (global.ReleaseMethod == global.JournalMethod) { return eSpecialMethodNone, errors.New ("Release method can not be the same as the Journal method"); } @@ -1124,6 +1130,21 @@ func CheckHeaderSpecialFunction (method ComponentDefinitionMethod, global Compon return eSpecialMethodError, nil; } + if (method.MethodName == global.ImplementsInterfaceMethod) { + if (len (method.Params) != 3) { + return eSpecialMethodNone, errors.New ("Implements Interface method does not match the expected function template"); + } + + if (method.Params[0].ParamType != "class") || (method.Params[0].ParamPass != "in") || + (method.Params[1].ParamType != "string") || (method.Params[1].ParamPass != "in") || + (method.Params[2].ParamType != "bool") || (method.Params[2].ParamPass != "return") || + (method.Params[0].ParamClass != global.BaseClassName) { + return eSpecialMethodNone, errors.New ("Implements Interface method does not match the expected function template"); + } + + return eSpecialMethodImplementsInterface, nil; + } + if len(global.PrereleaseMethod)>0 && (global.PrereleaseMethod == global.BuildinfoMethod) { return eSpecialMethodNone, errors.New ("Prerelease method can not be the same as the buildinfo method"); } @@ -1159,7 +1180,6 @@ func CheckHeaderSpecialFunction (method ComponentDefinitionMethod, global Compon return eSpecialMethodNone, nil; } - // GetLastErrorMessageMethod returns the xml definition of the GetLastErrorMessage-method func GetLastErrorMessageMethod() (ComponentDefinitionMethod) { var method ComponentDefinitionMethod From c0224d3bce8553b37b414fcb48d9cdc1cd60efad Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Mon, 4 Jan 2021 15:33:41 +0100 Subject: [PATCH 007/143] Update RTTI example with changes --- .../Bindings/CppDynamic/rtti_abi.hpp | 10 ++++ .../Bindings/CppDynamic/rtti_dynamic.h | 22 ++++---- .../Bindings/CppDynamic/rtti_dynamic.hpp | 50 +++++++++++-------- .../RTTI_component/Bindings/Python/RTTI.py | 46 ++++++++--------- .../Cpp/Interfaces/rtti_abi.hpp | 20 ++++---- .../Cpp/Interfaces/rtti_interfacewrapper.cpp | 4 +- 6 files changed, 85 insertions(+), 67 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp index 9e3e457e..c0746a29 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp @@ -158,6 +158,16 @@ RTTI_DECLSPEC RTTIResult rtti_injectcomponent(const char * pNameSpace, RTTI_pvoi */ RTTI_DECLSPEC RTTIResult rtti_getsymbollookupmethod(RTTI_pvoid * pSymbolLookupMethod); +/** +* Test whether an object implements a given interface +* +* @param[in] pObject - Instance Handle +* @param[in] pClassName - Class name of the interface to test +* @param[out] pImplementsInterface - Will be set to true if pInstance implements the interface, false otherwise +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_implementsinterface(RTTI_Base pObject, const char * pClassName, bool * pImplementsInterface); + /** * Create a new zoo with animals * diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h index 22001b34..62b011b6 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h @@ -112,16 +112,6 @@ typedef RTTIResult (*PRTTIGetVersionPtr) (RTTI_uint32 * pMajor, RTTI_uint32 * pM */ typedef RTTIResult (*PRTTIGetLastErrorPtr) (RTTI_Base pInstance, const RTTI_uint32 nErrorMessageBufferSize, RTTI_uint32* pErrorMessageNeededChars, char * pErrorMessageBuffer, bool * pHasError); -/** -* Test whether an object implements a given interface -* -* @param[in] pObject - Instance Handle -* @param[in] pClassName - Class name of the interface to test -* @param[out] pImplementsInterface - will be set to true if pInstance implements the interface, false otherwise -* @return error code or 0 (success) -*/ -typedef RTTIResult (*PRTTIImplementsInterfacePtr) (RTTI_Base pInstance, const char * pClassName, bool * pImplementsInterface); - /** * Releases shared ownership of an Instance * @@ -155,6 +145,16 @@ typedef RTTIResult (*PRTTIInjectComponentPtr) (const char * pNameSpace, RTTI_pvo */ typedef RTTIResult (*PRTTIGetSymbolLookupMethodPtr) (RTTI_pvoid * pSymbolLookupMethod); +/** +* Test whether an object implements a given interface +* +* @param[in] pObject - Instance Handle +* @param[in] pClassName - Class name of the interface to test +* @param[out] pImplementsInterface - Will be set to true if pInstance implements the interface, false otherwise +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIImplementsInterfacePtr) (RTTI_Base pObject, const char * pClassName, bool * pImplementsInterface); + /** * Create a new zoo with animals * @@ -174,11 +174,11 @@ typedef struct { PRTTIZoo_IteratorPtr m_Zoo_Iterator; PRTTIGetVersionPtr m_GetVersion; PRTTIGetLastErrorPtr m_GetLastError; - PRTTIImplementsInterfacePtr m_ImplementsInterface; PRTTIReleaseInstancePtr m_ReleaseInstance; PRTTIAcquireInstancePtr m_AcquireInstance; PRTTIInjectComponentPtr m_InjectComponent; PRTTIGetSymbolLookupMethodPtr m_GetSymbolLookupMethod; + PRTTIImplementsInterfacePtr m_ImplementsInterface; PRTTICreateZooPtr m_CreateZoo; } sRTTIDynamicWrapperTable; diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp index 9700b38b..e51b0101 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp @@ -243,7 +243,6 @@ class CWrapper { } inline void CheckError(CBase * pBaseClass, RTTIResult nResult); - inline bool ImplementsInterface(CBase *pBaseClass, const std::string& sClassname); inline void GetVersion(RTTI_uint32 & nMajor, RTTI_uint32 & nMinor, RTTI_uint32 & nMicro); inline bool GetLastError(classParam pInstance, std::string & sErrorMessage); @@ -251,6 +250,7 @@ class CWrapper { inline void AcquireInstance(classParam pInstance); inline void InjectComponent(const std::string & sNameSpace, const RTTI_pvoid pSymbolAddressMethod); inline RTTI_pvoid GetSymbolLookupMethod(); + inline bool ImplementsInterface(classParam pObject, const std::string & sClassName); inline PZoo CreateZoo(); private: @@ -638,6 +638,21 @@ class CZoo : public CBase { return resultSymbolLookupMethod; } + /** + * CWrapper::ImplementsInterface - Test whether an object implements a given interface + * @param[in] pObject - Instance Handle + * @param[in] sClassName - Class name of the interface to test + * @return Will be set to true if pInstance implements the interface, false otherwise + */ + inline bool CWrapper::ImplementsInterface(classParam pObject, const std::string & sClassName) + { + RTTIHandle hObject = pObject.GetHandle(); + bool resultImplementsInterface = 0; + CheckError(nullptr,m_WrapperTable.m_ImplementsInterface(hObject, sClassName.c_str(), &resultImplementsInterface)); + + return resultImplementsInterface; + } + /** * CWrapper::CreateZoo - Create a new zoo with animals * @return @@ -664,14 +679,6 @@ class CZoo : public CBase { } } - inline bool CWrapper::ImplementsInterface(CBase *pBaseClass, const std::string& sClassname) - { - bool resultImplementsInterface = false; - CheckError(nullptr,m_WrapperTable.m_ImplementsInterface(pBaseClass->m_pHandle, sClassname.c_str(), &resultImplementsInterface)); - - return resultImplementsInterface; - } - inline RTTIResult CWrapper::initWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable) { @@ -684,11 +691,11 @@ class CZoo : public CBase { pWrapperTable->m_Zoo_Iterator = nullptr; pWrapperTable->m_GetVersion = nullptr; pWrapperTable->m_GetLastError = nullptr; - pWrapperTable->m_ImplementsInterface = nullptr; pWrapperTable->m_ReleaseInstance = nullptr; pWrapperTable->m_AcquireInstance = nullptr; pWrapperTable->m_InjectComponent = nullptr; pWrapperTable->m_GetSymbolLookupMethod = nullptr; + pWrapperTable->m_ImplementsInterface = nullptr; pWrapperTable->m_CreateZoo = nullptr; return RTTI_SUCCESS; @@ -783,16 +790,6 @@ class CZoo : public CBase { if (pWrapperTable->m_GetLastError == nullptr) return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; - #ifdef _WIN32 - pWrapperTable->m_ImplementsInterface = (PRTTIImplementsInterfacePtr) GetProcAddress(hLibrary, "rtti_implementsinterface"); - #else // _WIN32 - pWrapperTable->m_ImplementsInterface = (PRTTIImplementsInterfacePtr) dlsym(hLibrary, "rtti_implementsinterface"); - dlerror(); - #endif // _WIN32 - if (pWrapperTable->m_ImplementsInterface == nullptr) - return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; - - #ifdef _WIN32 pWrapperTable->m_ReleaseInstance = (PRTTIReleaseInstancePtr) GetProcAddress(hLibrary, "rtti_releaseinstance"); #else // _WIN32 @@ -829,6 +826,15 @@ class CZoo : public CBase { if (pWrapperTable->m_GetSymbolLookupMethod == nullptr) return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 + pWrapperTable->m_ImplementsInterface = (PRTTIImplementsInterfacePtr) GetProcAddress(hLibrary, "rtti_implementsinterface"); + #else // _WIN32 + pWrapperTable->m_ImplementsInterface = (PRTTIImplementsInterfacePtr) dlsym(hLibrary, "rtti_implementsinterface"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_ImplementsInterface == nullptr) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 pWrapperTable->m_CreateZoo = (PRTTICreateZooPtr) GetProcAddress(hLibrary, "rtti_createzoo"); #else // _WIN32 @@ -890,6 +896,10 @@ class CZoo : public CBase { if ( (eLookupError != 0) || (pWrapperTable->m_GetSymbolLookupMethod == nullptr) ) return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + eLookupError = (*pLookup)("rtti_implementsinterface", (void**)&(pWrapperTable->m_ImplementsInterface)); + if ( (eLookupError != 0) || (pWrapperTable->m_ImplementsInterface == nullptr) ) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + eLookupError = (*pLookup)("rtti_createzoo", (void**)&(pWrapperTable->m_CreateZoo)); if ( (eLookupError != 0) || (pWrapperTable->m_CreateZoo == nullptr) ) return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; diff --git a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py index 86961d61..94c80d0e 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py +++ b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py @@ -58,11 +58,11 @@ class ErrorCodes(enum.IntEnum): class FunctionTable: rtti_getversion = None rtti_getlasterror = None - rtti_implementsinterface = None rtti_releaseinstance = None rtti_acquireinstance = None rtti_injectcomponent = None rtti_getsymbollookupmethod = None + rtti_implementsinterface = None rtti_createzoo = None rtti_tiger_roar = None rtti_animaliterator_getnextanimal = None @@ -122,12 +122,6 @@ def _loadFunctionTableFromMethod(self, symbolLookupMethodAddress): methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.c_uint64, ctypes.POINTER(ctypes.c_uint64), ctypes.c_char_p, ctypes.POINTER(ctypes.c_bool)) self.lib.rtti_getlasterror = methodType(int(methodAddress.value)) - err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_implementsinterface")), methodAddress) - if err != 0: - raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) - methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.c_char_p, ctypes.POINTER(ctypes.c_bool)) - self.lib.rtti_implementsinterface = methodType(int(methodAddress.value)) - err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_releaseinstance")), methodAddress) if err != 0: raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) @@ -152,6 +146,12 @@ def _loadFunctionTableFromMethod(self, symbolLookupMethodAddress): methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.POINTER(ctypes.c_void_p)) self.lib.rtti_getsymbollookupmethod = methodType(int(methodAddress.value)) + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_implementsinterface")), methodAddress) + if err != 0: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.c_char_p, ctypes.POINTER(ctypes.c_bool)) + self.lib.rtti_implementsinterface = methodType(int(methodAddress.value)) + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_createzoo")), methodAddress) if err != 0: raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) @@ -187,9 +187,6 @@ def _loadFunctionTable(self): self.lib.rtti_getlasterror.restype = ctypes.c_int32 self.lib.rtti_getlasterror.argtypes = [ctypes.c_void_p, ctypes.c_uint64, ctypes.POINTER(ctypes.c_uint64), ctypes.c_char_p, ctypes.POINTER(ctypes.c_bool)] - self.lib.rtti_implementsinterface.restype = ctypes.c_int32 - self.lib.rtti_implementsinterface.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.POINTER(ctypes.c_bool)] - self.lib.rtti_releaseinstance.restype = ctypes.c_int32 self.lib.rtti_releaseinstance.argtypes = [ctypes.c_void_p] @@ -202,6 +199,9 @@ def _loadFunctionTable(self): self.lib.rtti_getsymbollookupmethod.restype = ctypes.c_int32 self.lib.rtti_getsymbollookupmethod.argtypes = [ctypes.POINTER(ctypes.c_void_p)] + self.lib.rtti_implementsinterface.restype = ctypes.c_int32 + self.lib.rtti_implementsinterface.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.POINTER(ctypes.c_bool)] + self.lib.rtti_createzoo.restype = ctypes.c_int32 self.lib.rtti_createzoo.argtypes = [ctypes.POINTER(ctypes.c_void_p)] @@ -255,20 +255,6 @@ def GetLastError(self, InstanceObject): return pErrorMessageBuffer.value.decode(), pHasError.value - def ImplementsInterface(self, InstanceObject, ClassName): - InstanceHandle = None - if InstanceObject: - InstanceHandle = InstanceObject._handle - else: - return False - - pImplementsInterface = ctypes.c_bool() - pClassName = ctypes.c_char_p(str.encode(ClassName)) - - self.checkError(None, self.lib.rtti_implementsinterface(InstanceHandle, pClassName, pImplementsInterface)) - - return pImplementsInterface.value - def ReleaseInstance(self, InstanceObject): InstanceHandle = None if InstanceObject: @@ -303,6 +289,18 @@ def GetSymbolLookupMethod(self): return pSymbolLookupMethod.value + def ImplementsInterface(self, ObjectObject, ClassName): + ObjectHandle = None + if ObjectObject: + ObjectHandle = ObjectObject._handle + else: + raise ERTTIException(ErrorCodes.INVALIDPARAM, 'Invalid return/output value') + pClassName = ctypes.c_char_p(str.encode(ClassName)) + pImplementsInterface = ctypes.c_bool() + self.checkError(None, self.lib.rtti_implementsinterface(ObjectHandle, pClassName, pImplementsInterface)) + + return pImplementsInterface.value + def CreateZoo(self): InstanceHandle = ctypes.c_void_p() self.checkError(None, self.lib.rtti_createzoo(InstanceHandle)) diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp index 735b4088..c0746a29 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp @@ -125,16 +125,6 @@ RTTI_DECLSPEC RTTIResult rtti_getversion(RTTI_uint32 * pMajor, RTTI_uint32 * pMi */ RTTI_DECLSPEC RTTIResult rtti_getlasterror(RTTI_Base pInstance, const RTTI_uint32 nErrorMessageBufferSize, RTTI_uint32* pErrorMessageNeededChars, char * pErrorMessageBuffer, bool * pHasError); -/** -* Test whether an object implements a given interface -* -* @param[in] pObject - Instance Handle -* @param[in] pClassName - Class name of the interface to test -* @param[out] pImplementsInterface - will be set to true if pInstance implements the interface, false otherwise -* @return error code or 0 (success) -*/ -RTTI_DECLSPEC RTTIResult rtti_implementsinterface(RTTI_Base pInstance, const char * pClassName, bool * pImplementsInterface); - /** * Releases shared ownership of an Instance * @@ -168,6 +158,16 @@ RTTI_DECLSPEC RTTIResult rtti_injectcomponent(const char * pNameSpace, RTTI_pvoi */ RTTI_DECLSPEC RTTIResult rtti_getsymbollookupmethod(RTTI_pvoid * pSymbolLookupMethod); +/** +* Test whether an object implements a given interface +* +* @param[in] pObject - Instance Handle +* @param[in] pClassName - Class name of the interface to test +* @param[out] pImplementsInterface - Will be set to true if pInstance implements the interface, false otherwise +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_implementsinterface(RTTI_Base pObject, const char * pClassName, bool * pImplementsInterface); + /** * Create a new zoo with animals * diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp index d987b776..148caae5 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp @@ -197,8 +197,6 @@ RTTIResult RTTI::Impl::RTTI_GetProcAddress (const char * pProcName, void ** ppPr *ppProcAddress = (void*) &rtti_getversion; if (sProcName == "rtti_getlasterror") *ppProcAddress = (void*) &rtti_getlasterror; - if (sProcName == "rtti_implementsinterface") - *ppProcAddress = (void*) &rtti_implementsinterface; if (sProcName == "rtti_releaseinstance") *ppProcAddress = (void*) &rtti_releaseinstance; if (sProcName == "rtti_acquireinstance") @@ -207,6 +205,8 @@ RTTIResult RTTI::Impl::RTTI_GetProcAddress (const char * pProcName, void ** ppPr *ppProcAddress = (void*) &rtti_injectcomponent; if (sProcName == "rtti_getsymbollookupmethod") *ppProcAddress = (void*) &rtti_getsymbollookupmethod; + if (sProcName == "rtti_implementsinterface") + *ppProcAddress = (void*) &rtti_implementsinterface; if (sProcName == "rtti_createzoo") *ppProcAddress = (void*) &rtti_createzoo; From 7ba28d467ec7b28faeb9b77720ab4e1c36b36ccc Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Mon, 4 Jan 2021 17:13:21 +0100 Subject: [PATCH 008/143] Generate implementsinterface method --- .../Cpp/Interfaces/rtti_interfacewrapper.cpp | 137 +++++++----------- Source/buildimplementationcpp.go | 16 +- 2 files changed, 64 insertions(+), 89 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp index 148caae5..962153f3 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp @@ -195,9 +195,9 @@ RTTIResult RTTI::Impl::RTTI_GetProcAddress (const char * pProcName, void ** ppPr *ppProcAddress = (void*) &rtti_zoo_iterator; if (sProcName == "rtti_getversion") *ppProcAddress = (void*) &rtti_getversion; - if (sProcName == "rtti_getlasterror") + if (sProcName == "rtti_getlasterror") *ppProcAddress = (void*) &rtti_getlasterror; - if (sProcName == "rtti_releaseinstance") + if (sProcName == "rtti_releaseinstance") *ppProcAddress = (void*) &rtti_releaseinstance; if (sProcName == "rtti_acquireinstance") *ppProcAddress = (void*) &rtti_acquireinstance; @@ -215,88 +215,6 @@ RTTIResult RTTI::Impl::RTTI_GetProcAddress (const char * pProcName, void ** ppPr return RTTI_SUCCESS; } -/************************************************************************************************************************* - RTTI implementation -**************************************************************************************************************************/ - -RTTIResult rtti_implementsinterface(RTTI_Base pInstance, const char * pClassName, bool * pImplementsInterface) -{ - IBase* pIBaseClassInstance = (IBase *)pInstance; - std::string sClassName(pClassName); - - // TODO: Optimize these lookups in a static (generated) way - switch (pClassName[0]) { - case 'a': - case 'A': - if (sClassName == "Animal") { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - if (sClassName == "AnimalIterator") { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - break; - case 'b': - case 'B': - if (sClassName == "Base") { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - break; - case 'g': - case 'G': - if (sClassName == "Giraffe") { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - break; - case 'm': - case 'M': - if (sClassName == "Mammal") { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - break; - case 'r': - case 'R': - if (sClassName == "Reptile") { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - break; - case 's': - case 'S': - if (sClassName == "Snake") { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - break; - case 't': - case 'T': - if (sClassName == "Tiger") { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - if (sClassName == "Turtle") { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - break; - case 'z': - case 'Z': - if (sClassName == "Zoo") { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - break; - default: - break; - } - - return RTTI_ERROR_INVALIDPARAM; -} - /************************************************************************************************************************* Global functions implementation **************************************************************************************************************************/ @@ -464,6 +382,57 @@ RTTIResult rtti_getsymbollookupmethod(RTTI_pvoid * pSymbolLookupMethod) } } + +/************************************************************************************************************************* + Test whether an object implements a given interface +**************************************************************************************************************************/ + +RTTIResult rtti_implementsinterface(RTTI_Base pObject, const char * pClassName, bool * pImplementsInterface) +{ + IBase* pIBaseClassInstance = (IBase *)pObject; + if (strcmp(pClassName, "Base") == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + if (strcmp(pClassName, "Animal") == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + if (strcmp(pClassName, "Mammal") == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + if (strcmp(pClassName, "Reptile") == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + if (strcmp(pClassName, "Giraffe") == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + if (strcmp(pClassName, "Tiger") == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + if (strcmp(pClassName, "Snake") == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + if (strcmp(pClassName, "Turtle") == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + if (strcmp(pClassName, "AnimalIterator") == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + if (strcmp(pClassName, "Zoo") == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + return RTTI_ERROR_INVALIDPARAM; +} + RTTIResult rtti_createzoo(RTTI_Zoo * pInstance) { IBase* pIBaseClass = nullptr; diff --git a/Source/buildimplementationcpp.go b/Source/buildimplementationcpp.go index f25fc437..5802e490 100644 --- a/Source/buildimplementationcpp.go +++ b/Source/buildimplementationcpp.go @@ -691,7 +691,7 @@ func buildCPPInterfaceWrapperMethods(component ComponentDefinition, class Compon return nil } -func writeCImplementsInterfaceMethod(method ComponentDefinitionMethod, w LanguageWriter, NameSpace string) error { +func writeCImplementsInterfaceMethod(component ComponentDefinition, method ComponentDefinitionMethod, w LanguageWriter, NameSpace string) error { cParams, err := GenerateCParameters(method, "", NameSpace) if err != nil { return err @@ -715,8 +715,15 @@ func writeCImplementsInterfaceMethod(method ComponentDefinitionMethod, w Languag w.Writeln("%sResult %s(%s)", NameSpace, CMethodName, cparameters) w.Writeln("{") - w.Writeln(" // TODO") - w.Writeln(" return %s_SUCCESS;", strings.ToUpper (NameSpace)) + w.Writeln(" IBase* pIBaseClassInstance = (IBase *)pObject;") + for i := 0; i < len(component.Classes); i++ { + class := component.Classes[i] + w.Writeln(" if (strcmp(pClassName, \"%s\") == 0) {", class.ClassName) + w.Writeln(" *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr;", class.ClassName) + w.Writeln(" return RTTI_SUCCESS;") + w.Writeln(" }") + } + w.Writeln(" return %s_ERROR_INVALIDPARAM;", strings.ToUpper(NameSpace)) w.Writeln("}") w.Writeln("") @@ -894,9 +901,8 @@ func buildCPPInterfaceWrapper(component ComponentDefinition, w LanguageWriter, N doMethodJournal = false; } - if (isSpecialFunction == eSpecialMethodImplementsInterface) { - err = writeCImplementsInterfaceMethod(method, w, NameSpace) + err = writeCImplementsInterfaceMethod(component, method, w, NameSpace) if err != nil { return err } From 9589592077c9e3c41784d5eb067a3b5c7acdb88e Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Mon, 4 Jan 2021 18:27:41 +0100 Subject: [PATCH 009/143] RTTI methods in CppDynamic binding --- .../Bindings/CppDynamic/rtti_dynamic.hpp | 107 +++++++++++------- Source/buildbindingccpp.go | 46 +++++++- 2 files changed, 108 insertions(+), 45 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp index e51b0101..aa5c7e4d 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp @@ -290,6 +290,7 @@ class CWrapper { class CBase { public: static const std::string &getClassName(); + protected: /* Wrapper Object that created the class. */ CWrapper * m_pWrapper; @@ -336,7 +337,7 @@ class CBase { { return m_pWrapper; } - + friend class CWrapper; template friend std::shared_ptr rtti_cast(PBase obj); @@ -348,7 +349,7 @@ class CBase { class CAnimal : public CBase { public: static const std::string &getClassName(); - + /** * CAnimal::CAnimal - Constructor for Animal class. */ @@ -365,7 +366,7 @@ class CAnimal : public CBase { class CMammal : public CAnimal { public: static const std::string &getClassName(); - + /** * CMammal::CMammal - Constructor for Mammal class. */ @@ -382,7 +383,7 @@ class CMammal : public CAnimal { class CReptile : public CAnimal { public: static const std::string &getClassName(); - + /** * CReptile::CReptile - Constructor for Reptile class. */ @@ -399,7 +400,7 @@ class CReptile : public CAnimal { class CGiraffe : public CMammal { public: static const std::string &getClassName(); - + /** * CGiraffe::CGiraffe - Constructor for Giraffe class. */ @@ -416,7 +417,7 @@ class CGiraffe : public CMammal { class CTiger : public CMammal { public: static const std::string &getClassName(); - + /** * CTiger::CTiger - Constructor for Tiger class. */ @@ -434,7 +435,7 @@ class CTiger : public CMammal { class CSnake : public CReptile { public: static const std::string &getClassName(); - + /** * CSnake::CSnake - Constructor for Snake class. */ @@ -451,7 +452,7 @@ class CSnake : public CReptile { class CTurtle : public CReptile { public: static const std::string &getClassName(); - + /** * CTurtle::CTurtle - Constructor for Turtle class. */ @@ -468,7 +469,7 @@ class CTurtle : public CReptile { class CAnimalIterator : public CBase { public: static const std::string &getClassName(); - + /** * CAnimalIterator::CAnimalIterator - Constructor for AnimalIterator class. */ @@ -486,7 +487,7 @@ class CAnimalIterator : public CBase { class CZoo : public CBase { public: static const std::string &getClassName(); - + /** * CZoo::CZoo - Constructor for Zoo class. */ @@ -498,69 +499,87 @@ class CZoo : public CBase { inline PAnimalIterator Iterator(); }; +/************************************************************************************************************************* + RTTI static getClassName implementations +**************************************************************************************************************************/ + const std::string &CBase::getClassName() -{ - static const std::string s_sClassName = "Base"; - return s_sClassName; + { + static const std::string s_sClassName = "Base"; + return s_sClassName; } + const std::string &CAnimal::getClassName() - { - static const std::string s_sClassName = "Animal"; - return s_sClassName; + { + static const std::string s_sClassName = "Animal"; + return s_sClassName; } + const std::string &CMammal::getClassName() - { - static const std::string s_sClassName = "Mammal"; - return s_sClassName; + { + static const std::string s_sClassName = "Mammal"; + return s_sClassName; } + const std::string &CReptile::getClassName() - { - static const std::string s_sClassName = "Reptile"; - return s_sClassName; + { + static const std::string s_sClassName = "Reptile"; + return s_sClassName; } + const std::string &CGiraffe::getClassName() - { - static const std::string s_sClassName = "Giraffe"; - return s_sClassName; + { + static const std::string s_sClassName = "Giraffe"; + return s_sClassName; } + const std::string &CTiger::getClassName() - { - static const std::string s_sClassName = "Tiger"; - return s_sClassName; + { + static const std::string s_sClassName = "Tiger"; + return s_sClassName; } + const std::string &CSnake::getClassName() - { - static const std::string s_sClassName = "Snake"; - return s_sClassName; + { + static const std::string s_sClassName = "Snake"; + return s_sClassName; } + const std::string &CTurtle::getClassName() - { - static const std::string s_sClassName = "Turtle"; - return s_sClassName; + { + static const std::string s_sClassName = "Turtle"; + return s_sClassName; } + const std::string &CAnimalIterator::getClassName() - { - static const std::string s_sClassName = "AnimalIterator"; - return s_sClassName; + { + static const std::string s_sClassName = "AnimalIterator"; + return s_sClassName; } + const std::string &CZoo::getClassName() { - static const std::string s_sClassName = "Zoo"; - return s_sClassName; + static const std::string s_sClassName = "Zoo"; + return s_sClassName; } + +/************************************************************************************************************************* + RTTI cast implementation +**************************************************************************************************************************/ + template std::shared_ptr rtti_cast(PBase pObj) { static_assert(std::is_convertible::value, "T must be convertible to RTTI::CBase"); - if (pObj && pObj->m_pWrapper->ImplementsInterface(pObj.get(), T::getClassName())){ + if (pObj && pObj->m_pWrapper->ImplementsInterface(pObj.get(), T::getClassName())){ return std::make_shared(pObj->m_pWrapper, pObj->m_pHandle); } return nullptr; } - + /** * CWrapper::GetVersion - retrieves the binary version of this library. * @param[out] nMajor - returns the major version of this library @@ -678,7 +697,7 @@ class CZoo : public CBase { throw ERTTIException(nResult, sErrorMessage); } } - + inline RTTIResult CWrapper::initWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable) { @@ -780,7 +799,7 @@ class CZoo : public CBase { #endif // _WIN32 if (pWrapperTable->m_GetVersion == nullptr) return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; - + #ifdef _WIN32 pWrapperTable->m_GetLastError = (PRTTIGetLastErrorPtr) GetProcAddress(hLibrary, "rtti_getlasterror"); #else // _WIN32 @@ -789,7 +808,7 @@ class CZoo : public CBase { #endif // _WIN32 if (pWrapperTable->m_GetLastError == nullptr) return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; - + #ifdef _WIN32 pWrapperTable->m_ReleaseInstance = (PRTTIReleaseInstancePtr) GetProcAddress(hLibrary, "rtti_releaseinstance"); #else // _WIN32 diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index 7e5798a7..6e46ef0d 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -898,8 +898,10 @@ func writeDynamicCppBaseClassMethods(component ComponentDefinition, baseClass Co w.Writeln(" return m_pWrapper;") w.Writeln(" }") - w.Writeln(" ") + w.Writeln("") w.Writeln(" friend class CWrapper;") + w.Writeln(" template ") + w.Writeln(" friend std::shared_ptr %s_cast(PBase obj);", strings.ToLower(NameSpace)) return nil } @@ -1142,6 +1144,12 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s buildBindingCPPAllForwardDeclarations(component, w, NameSpace, cppClassPrefix, ClassIdentifier) + w.Writeln("/*************************************************************************************************************************") + w.Writeln(" rtti_cast Definition") + w.Writeln("**************************************************************************************************************************/") + w.Writeln("template ") + w.Writeln("inline std::shared_ptr %s_cast(PBase obj);", strings.ToLower(NameSpace)) + w.Writeln("") w.Writeln("/*************************************************************************************************************************") w.Writeln(" classParam Definition") @@ -1360,6 +1368,7 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln("**************************************************************************************************************************/") w.Writeln("class %s %s{", cppClassName, inheritanceSpecifier) w.Writeln("public:") + w.Writeln(" static const std::string &getClassName();") w.Writeln(" ") if !component.isBaseClass(class) { w.Writeln(" /**") @@ -1389,6 +1398,41 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln("};") } + w.Writeln("") + w.Writeln("/*************************************************************************************************************************") + w.Writeln(" RTTI static getClassName implementations") + w.Writeln("**************************************************************************************************************************/") + w.Writeln("") + + for i := 0; i < len(component.Classes); i++ { + class := component.Classes[i] + w.Writeln(" const std::string &C%s::getClassName()", class.ClassName) + w.Writeln(" {") + w.Writeln(" static const std::string s_sClassName = \"%s\";", class.ClassName) + w.Writeln(" return s_sClassName;") + w.Writeln(" }") + w.Writeln("") + } + + w.Writeln("") + w.Writeln("/*************************************************************************************************************************") + w.Writeln(" RTTI cast implementation") + w.Writeln("**************************************************************************************************************************/") + w.Writeln("") + + w.Writeln(" template ") + w.Writeln(" std::shared_ptr %s_cast(PBase pObj)", strings.ToLower(NameSpace)) + w.Writeln(" {") + w.Writeln(" static_assert(std::is_convertible::value, \"T must be convertible to %s::CBase\");", NameSpace) + w.Writeln("") + w.Writeln(" if (pObj && pObj->m_pWrapper->ImplementsInterface(pObj.get(), T::getClassName())){") + w.Writeln(" return std::make_shared(pObj->m_pWrapper, pObj->m_pHandle);") + w.Writeln(" }") + w.Writeln("") + w.Writeln(" return nullptr;") + w.Writeln(" }") + + for j := 0; j < len(global.Methods); j++ { method := global.Methods[j] From 3d85067b14cf7eb0a55a9bf551f0518ce1381aab Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Mon, 4 Jan 2021 18:50:31 +0100 Subject: [PATCH 010/143] Delete pycache file from example --- .../Python/__pycache__/RTTI.cpython-38.pyc | Bin 13262 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Examples/RTTI/RTTI_component/Bindings/Python/__pycache__/RTTI.cpython-38.pyc diff --git a/Examples/RTTI/RTTI_component/Bindings/Python/__pycache__/RTTI.cpython-38.pyc b/Examples/RTTI/RTTI_component/Bindings/Python/__pycache__/RTTI.cpython-38.pyc deleted file mode 100644 index ccf3dfa888ea4a098e80e9c53502eb72c7fa46c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13262 zcmcIqO>7(2cAh_y!x2eQKbHKXIE-JKhWU{k_r1J_G%poRO9@{j%9Z3enfF>|#2Lw? zDU!J}vMrX%E202JyK*0jqKg)gfC8<7qRXz@McYkL6zH}XbW?QYu3Dh0toogMhr{8I zWV>!D&7HYFbIv_K_ndRjojd8YA>sF9^PekwzbZ-pPL=3SLuDD4ds&twTQVhEwv~o# z%KWaF3cstS%I}(~*{T`)Sh6)c_N`>cocOV7CQy&t3DgsgTG!E%M2l`G(UJ^W473>b z1X?DJ6>|c$l$}N`jamw|j6I3kBx-5Yvi1~eQ%)MNGN@16GpNrv8Pq3HpS3Tbeu3As zsL$E+sLwl-=$}IUqJ0VVOT0df`epkH>Q|gB`e#sIuwOy_6<(i3{i^*c>aTKq7f{dH zuc7`Lug}@amXyC{DPYjsZyQFj)jnjky?b8n&0;=x?{ zkK^{CcMos!Db$*|7PB3e^IAEp(P%xS;g01V8o2}4$+dQKo7>wZ!zeX9hwWNbr-%3h zV7|V1-7ub#@|1mzd6+IeM}I0R%edUDC>#k&Btd}^wqmQ_%1|M$G*F>97^?f36+*W1 zsOq#m(B?~3dcXIhX9ZUgmzzb=mAg_!>MAG!cT0LAm-C7rt5jRIoj(KjkhO)<|h)H0F3YUm+n9^?$WMPbFGGTZ{M<)z|AEv`Q2St)K?x^`|XC~F46RO z0UUu?mcmZK)}_To`oCFg+O_7MyA-t2n~Uv3Osi6B*1SsP3Q<98O_JksXMT|K#onkY zR4n|_GckcP;5r_dLV^FWJhx#A_1Owy<{lePFR#?qmj7oa-nbxidF1c|NS1ml+Y5j}g^PYu~9< ze4|p?Z`lV8dQMd;UmaKt(ZkXh%1Epcv?L)$xEaxX85d`nE*lzesiI}zM=V;#KkdA0xeU_n5}{hnx6^e^O;yhPw72IML8d5Q&gFzVg`jDTQB@%V-vShd1KSWt+=@{ zc8;?c{RS@18(r4$$EfY>S&|S(W(jj@Yi8VznF%{?>UP3R+PZ1jNpr$BF#8GLSYfQi zicoWxPnul-oTs!lo)Vv)64#%`s30jlCE-3LftK^BVd4^7cZ$W8tt~TC-qt!*=N^UmrjWWKSnwO&|TGqWGBlvg%O#g)&C zE4Q~x8)bi{xN&Fg79g%|6mG4RZf+Jfzwj^h8dpo@UgOH=w>LJo{Y#~Cabx{3UYP>IAJ;^{ay#8*Z&N>rT}R4U&Jkht56R-)X_7 zx9%Ub_Z`@L+t2X6Ds$j$I<1y3=IYh<99Cg1i}|nd0amlNZ#8O|tmU;B(b9AtVJ6fX zkb}1?y#Zr|L@VI~T<#o-Q6cfwL1RV)MJl|E%YA?%6x4z};xlXn7!Vr|DAkP8Ia@tan~On}7pAw- zFk@@A=D{OVaa(5mmc<^{nh@M!qqf7yYWebFNA2dWeJ5Yb&-!}1VR^ePw(rN?LoAqm zZtD4>X5XXHO3U@Nw&mUPwR)@8^b>ZCkrVNC=yij4z~NAM11A%&dWUVtHMQccwKZP_ zNWe+TCMw;m_jCQQD*8aL!OEZ<~J*Rpfp2T8@fg^$UAVcd<5NT*G z)3h#$g}BBSqIkJr+lUBVGw$#(fssw}Whb(bxYr|}xQ5Gp2ZaO!mx9L)F2zuE`6{lI ztjJmXEh>hr<1eLTl}X$|)n)K5K9x{4R? z%E$QQ${ss~>UC+1>LpHKD@jSa+OcvJ>&CDQRQ9C@)vZr>2~s;!5mJ8vo5M|=QVU@i zcskXN;@voKY4tQ=LsXNgOhz!NBbfg2Y)thS;AaCoS;837H3c~FF}S89xUi@Osd_B4 zA3XzGk8cEj94#{u_{7@*t^xiZod+LAV3a$v5s2|I5dY(aAzp|;OpHKO*oWsp1pUw% zb<8~HB2e`)P=9eY)KC-0(LW!7n;Zl89Qx0Ndoco+8{w#aKUUezv*!yAjGO7D2*inz znX2p$&Vv|eu~?6zT5vf68!Ku^uT=J*F9G`s+{*iKD+~9H#~Ry)V@bfV%yEdXbQATf zwsI-zP7+@ydhUcfgmjtxGR%z#RNthhJQZ(I@irA?+Zcs&Y>|p3Dkv~!@1e-Q%6^QS znJli}DHpfDxV_>hs@Ot#zjDLZtFXWptF-;Z?Tr$m)=g@9(5l&JQZYuDci33k`3-v! z3_TEVVh^mwfx|u`oHSK}LS65FAKs&~gKal^;d%R+g6FZ?&VlFfV4b~AfHjNlxp`ge zu5J-sbECdt8~)0i9&I<%B8Urohp!@(G!4;4@A!%};y?<(QOD(WP>=(;4ELZbb8r(` z`7L=mczTCF8ECs2K4r%|&4z7rW1jkNTn>9L%X7-K+<858MwZy--CJKTiv=^f%7;a0}rD&?rBe@EiuL=!gq9fr=G-R1aDwrqc#!LuyFQb{4G85 zRyuquI!-`ON5*BuxIHnyOr&RWpl34DljS{tTTkvGi-GxOBfV49%V~sR3*b&g`lrYA zPe=M^2Jp^AdS*pW1iHXJ8yR!qj4>A~iNGMt!63-&?_dxR6~Z9Qdl&1Mx^n%pEe{w3 z`D=N=ASh*S3-VX^%4Vw&bbsxc3B*Mdv9V96oq``z$Ex8$oLGh>>L^q3F%=tByogC* zx9JVqWr&!PRwny(6nRA~%q?o*sfT|4VHs_Ih0DExLPTP3Dk=FbTno4|!8MKhY;aNA zMO+KC04|@s00z_^vDk2q=R`V{ex@GDN6L}fMLwsF2+O^Om`tv#_hCLgjW!Fkksy1^ zXy2bt_{PVM7X+m|3BhO^#^$N$lm1IIR^wEg@#eZ!Z!x;pn%JVsm0=#-#OQy;736+0 z@~qss64Esq3=iy_Xj+80NB{^D2*7G4V%SGrnY{tc!Ky;-4G@Gd!sdY^_7(^|PvxJ1 z_#@5JknK|`pyaMaDR*XTO<3=moqH&@Yq=`2nE8Z|Yz}DHItnD9f__2#HEK(NLu=TP zbNif+iNIa&ZMn@P->FlQg^?X%cc>WD3g6&Fa{&K_Za0NOLO`y`2Fi@wneMTtKX63c z6pVAOEaL%d5_`!bvT1Y&kN6#&Il+z$HbOnokoN=^PSsN+pux3RSHY#$W4p+03Gv6p z(xTPFzMvxXZJZsU$lHO)+g#*k9QP{H6N6N;Z9t$buSr zrDBeEz?w^~1FwDH#NQU0Cnsy@^R=kED!T2HT)E5DdBS<4nL>3gh_;K5z z=maWDdf;bDLCR-ihq5~T`X?NlIp5^kwk~qpHxG7q9kx~LIOfHHj?teC<7bmV(Uu@{uiY)`eL%V=Q9Q?evf?w_Cn z`NM(*@>iS4x@{p_eWF0J8tz>3lw=@@)57PH#tsv5hGYYU*Xl{i!Di}L^x4kc1F=2WpR?bps`CEQMX#9|}^QfpV z)pv;QzRbUeYM}dOk~DscV3{*pJVhMrC`4)s3f~_v+a5P!awi zd5st>d}9`7WKJQS>FdkT=m7^w{v=!r%lk* z0;9>fVRA0O!i|o4hlrx7kw=_WI-1I_pG&jhtrOOVp8c z2a85!LsR;k!PfY> zLd=fi9(NKruhw}VP8#5P3}3s6vzZadV3e=~6vKA^3889|9aT->{r6F}UkcRH0`DCAcQk}&+2wY(ryNKn4cM@T$!e|yk z_>=V1mp0+0183W5R4Si_ERs8^04whpa4p0f+GTJCy@>}f=yeJ;ff%SM%s5rp>mICg z9Witr>j?+s5jOG3e2Ets$;FRt)3F%m7LNVYYQtrpQ|HhmwJP=yWtt&32FR!&?oaYr z@}7KhXi@kn9O~g)36Z(sxWqbX5Y~w*1tmdWYY<;waY(I}2`BMMmlfGi^|-DoGFP|} z)g;|n#^vTvoUimy@VFl@@T0yFIKVin;tY)urVO%&lXo|i9}Xr2=yQ}jl;Jc0lezEG zmmbQg8d04midb2snXEoIfly_C8lsgulL6YEx|W{|pYyXefg#BYY4qvnvzV-R*PkO%uoF@ah6~Uy&u}j1a~ZxHq6NbPv?0Tp zH)h&gRz#0A#8qk=;l_({HL*z_5;dOFR6iUuzd^R{hxEY%2C!d}uj~O~JxhbX3K7bk zY!BgcaFj@C3~`j&UY?^L*O-Mp=LjGm8?_9Nh_-VT^-)M5I2yoyNshua@C9lkrS$`))CwDReU5}#!(JxUGM!)o3U@thJd!2SqQk@Q8gN>{R6=EV(=x=bAXexYX zJ1%n2Ht{jb??xtMhzU`18C&8hdYk+U|HNz9^wVL`!+^#ZSW}yP) zF!X!{;4U||)wJ$E=eqhWfE=FRpr!gnNIFE%A-|;Pv8uRzJa<+7VTctPAh7l{pnSIZ zCu)A5-i$a^YCC&P<aERAm;FzAGT2H4TK6ujr z-*d2&2>Ih7c2e8f?0hj3g_BJl9F~Hw!$#l&_oyrQnkYTj75sTfuF|=N>` z*!&kEUZf<3@b=g}V83W(hgly=toKtA!g|4eDRoLl<8%_4AfD;LUgUjz4ue=0TQ%Cp zV}nK?*7P=MdSw63_aS{tcb#U>EgeN*!PebOiKzx@;h-jx#t}Y~)$-HGNR;vYo_OOg ziC$`_jobn@^ch7{ItxRT54`ehi}`bai=gcrBa-`{5ykx-w^Wc~97-DnxkR2e z8dAIWh*@0i_}V4ui2O0-9(r1s=~;n555xL+P1JkC|DH%6R6=BxI1_q9o~?AhO;Z}O zDcntyod23I3@9D7=I41*p;fI^#De<)8hy=a9_+Ip@<&RvvR}g^&zkrN90aUT?<_T4 zq~Z-KZcxFKJA7NjBTnuhdCbdWGxA}KyA{sBamvS+r~aY%BK{-HSaRP&p=IeiKKv<~ amQ773rqh{h=I7GG%v^RN_?zVS3;zQH$9(qy From ef7e59180ab97b6409ba8682e1505750767dbff7 Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Tue, 5 Jan 2021 11:34:47 +0100 Subject: [PATCH 011/143] Python RTTI --- .../RTTI_component/Bindings/Python/RTTI.py | 39 ++++++++++--------- Source/buildbindingpython.go | 16 ++++++++ 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py index 94c80d0e..4954f4cd 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py +++ b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py @@ -115,13 +115,13 @@ def _loadFunctionTableFromMethod(self, symbolLookupMethodAddress): raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32)) self.lib.rtti_getversion = methodType(int(methodAddress.value)) - + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_getlasterror")), methodAddress) if err != 0: raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.c_uint64, ctypes.POINTER(ctypes.c_uint64), ctypes.c_char_p, ctypes.POINTER(ctypes.c_bool)) self.lib.rtti_getlasterror = methodType(int(methodAddress.value)) - + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_releaseinstance")), methodAddress) if err != 0: raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) @@ -186,7 +186,7 @@ def _loadFunctionTable(self): self.lib.rtti_getlasterror.restype = ctypes.c_int32 self.lib.rtti_getlasterror.argtypes = [ctypes.c_void_p, ctypes.c_uint64, ctypes.POINTER(ctypes.c_uint64), ctypes.c_char_p, ctypes.POINTER(ctypes.c_bool)] - + self.lib.rtti_releaseinstance.restype = ctypes.c_int32 self.lib.rtti_releaseinstance.argtypes = [ctypes.c_void_p] @@ -254,7 +254,7 @@ def GetLastError(self, InstanceObject): self.checkError(None, self.lib.rtti_getlasterror(InstanceHandle, nErrorMessageBufferSize, nErrorMessageNeededChars, pErrorMessageBuffer, pHasError)) return pErrorMessageBuffer.value.decode(), pHasError.value - + def ReleaseInstance(self, InstanceObject): InstanceHandle = None if InstanceObject: @@ -319,7 +319,13 @@ class Base: @staticmethod def ClassName(): return "Base" - + + @classmethod + def cast(cls, instance): + if instance and instance._wrapper.ImplementsInterface(instance, cls.ClassName()): + return cls(instance._handle, instance._wrapper) + return None + def __init__(self, handle, wrapper): if not handle or not wrapper: raise ERTTIException(ErrorCodes.INVALIDPARAM) @@ -329,11 +335,6 @@ def __init__(self, handle, wrapper): def __del__(self): self._wrapper.ReleaseInstance(self) - @classmethod - def cast(cls, instance): - if instance and instance._wrapper.ImplementsInterface(instance, cls.ClassName()): - return Tiger(instance._handle, instance._wrapper) - return None ''' Class Implementation for Animal ''' @@ -341,7 +342,7 @@ class Animal(Base): @staticmethod def ClassName(): return "Animal" - + def __init__(self, handle, wrapper): Base.__init__(self, handle, wrapper) @@ -352,7 +353,7 @@ class Mammal(Animal): @staticmethod def ClassName(): return "Mammal" - + def __init__(self, handle, wrapper): Animal.__init__(self, handle, wrapper) @@ -363,7 +364,7 @@ class Reptile(Animal): @staticmethod def ClassName(): return "Reptile" - + def __init__(self, handle, wrapper): Animal.__init__(self, handle, wrapper) @@ -374,7 +375,7 @@ class Giraffe(Mammal): @staticmethod def ClassName(): return "Giraffe" - + def __init__(self, handle, wrapper): Mammal.__init__(self, handle, wrapper) @@ -385,7 +386,7 @@ class Tiger(Mammal): @staticmethod def ClassName(): return "Tiger" - + def __init__(self, handle, wrapper): Mammal.__init__(self, handle, wrapper) def Roar(self): @@ -400,7 +401,7 @@ class Snake(Reptile): @staticmethod def ClassName(): return "Snake" - + def __init__(self, handle, wrapper): Reptile.__init__(self, handle, wrapper) @@ -411,7 +412,7 @@ class Turtle(Reptile): @staticmethod def ClassName(): return "Turtle" - + def __init__(self, handle, wrapper): Reptile.__init__(self, handle, wrapper) @@ -422,7 +423,7 @@ class AnimalIterator(Base): @staticmethod def ClassName(): return "AnimalIterator" - + def __init__(self, handle, wrapper): Base.__init__(self, handle, wrapper) def GetNextAnimal(self): @@ -443,7 +444,7 @@ class Zoo(Base): @staticmethod def ClassName(): return "Zoo" - + def __init__(self, handle, wrapper): Base.__init__(self, handle, wrapper) def Iterator(self): diff --git a/Source/buildbindingpython.go b/Source/buildbindingpython.go index 9eb7f0fd..a61b32dd 100644 --- a/Source/buildbindingpython.go +++ b/Source/buildbindingpython.go @@ -735,11 +735,27 @@ func writePythonClass(component ComponentDefinition, class ComponentDefinitionCl parentClass = pythonBaseClassName } w.Writeln("class %s(%s):", class.ClassName, parentClass) + w.Writeln(" @staticmethod") + w.Writeln(" def ClassName():") + w.Writeln(" return \"%s\"", class.ClassName) + w.Writeln(" ") w.Writeln(" def __init__(self, handle, wrapper):") w.Writeln(" %s.__init__(self, handle, wrapper)", parentClass) } else { w.Writeln("class %s:", class.ClassName) + w.Writeln(" @staticmethod") + w.Writeln(" def ClassName():") + w.Writeln(" return \"%s\"", class.ClassName) + w.Writeln(" ") + + w.Writeln(" @classmethod") + w.Writeln(" def cast(cls, instance):") + w.Writeln(" if instance and instance._wrapper.ImplementsInterface(instance, cls.ClassName()):") + w.Writeln(" return cls(instance._handle, instance._wrapper)") + w.Writeln(" return None") + w.Writeln(" ") + w.Writeln(" def __init__(self, handle, wrapper):") w.Writeln(" if not handle or not wrapper:") w.Writeln(" raise E%sException(ErrorCodes.INVALIDPARAM)", NameSpace) From 1731ad4e7e443df6d919a57d74a0f667368fd742 Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Mon, 18 Jan 2021 19:12:02 +0100 Subject: [PATCH 012/143] Fix hardcoded namespace RTTI --- Source/buildbindingccpp.go | 2 +- Source/buildimplementationcpp.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index 6e46ef0d..11d9dc11 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -1145,7 +1145,7 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln("/*************************************************************************************************************************") - w.Writeln(" rtti_cast Definition") + w.Writeln(" %s_cast Definition", strings.ToLower(NameSpace)) w.Writeln("**************************************************************************************************************************/") w.Writeln("template ") w.Writeln("inline std::shared_ptr %s_cast(PBase obj);", strings.ToLower(NameSpace)) diff --git a/Source/buildimplementationcpp.go b/Source/buildimplementationcpp.go index 5802e490..41ae25a1 100644 --- a/Source/buildimplementationcpp.go +++ b/Source/buildimplementationcpp.go @@ -720,7 +720,7 @@ func writeCImplementsInterfaceMethod(component ComponentDefinition, method Compo class := component.Classes[i] w.Writeln(" if (strcmp(pClassName, \"%s\") == 0) {", class.ClassName) w.Writeln(" *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr;", class.ClassName) - w.Writeln(" return RTTI_SUCCESS;") + w.Writeln(" return %s_SUCCESS;", strings.ToUpper(NameSpace)) w.Writeln(" }") } w.Writeln(" return %s_ERROR_INVALIDPARAM;", strings.ToUpper(NameSpace)) From a256dd7cef61d559fe59335bd594d84bea323541 Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Mon, 18 Jan 2021 20:05:00 +0100 Subject: [PATCH 013/143] Inline binding getClassName method --- Source/buildbindingccpp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index 11d9dc11..e49c9f1c 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -1368,7 +1368,7 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln("**************************************************************************************************************************/") w.Writeln("class %s %s{", cppClassName, inheritanceSpecifier) w.Writeln("public:") - w.Writeln(" static const std::string &getClassName();") + w.Writeln(" static inline const std::string &getClassName();") w.Writeln(" ") if !component.isBaseClass(class) { w.Writeln(" /**") From d462710219b55b7f014dc450782cdf7922a4ca8b Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Thu, 28 Jan 2021 17:35:17 +0100 Subject: [PATCH 014/143] Update RTTI example --- .../Bindings/CppDynamic/rtti_abi.hpp | 11 ++++ .../Bindings/CppDynamic/rtti_dynamic.h | 12 +++++ .../Bindings/CppDynamic/rtti_dynamic.hpp | 30 +++++++++++ .../RTTI_component/Bindings/Python/RTTI.py | 21 ++++++++ .../Cpp/Interfaces/rtti_abi.hpp | 11 ++++ .../Cpp/Interfaces/rtti_interfaces.hpp | 25 ++++++++++ .../Cpp/Interfaces/rtti_interfacewrapper.cpp | 50 +++++++++++++++++++ .../Implementations/Cpp/Stub/rtti.cpp | 20 ++++---- .../Implementations/Cpp/Stub/rtti_animal.cpp | 16 +++++- .../Implementations/Cpp/Stub/rtti_animal.hpp | 7 ++- .../Implementations/Cpp/Stub/rtti_base.cpp | 2 +- .../Implementations/Cpp/Stub/rtti_giraffe.cpp | 5 +- .../Implementations/Cpp/Stub/rtti_giraffe.hpp | 2 +- .../Implementations/Cpp/Stub/rtti_snake.cpp | 4 ++ .../Implementations/Cpp/Stub/rtti_snake.hpp | 2 +- .../Implementations/Cpp/Stub/rtti_tiger.cpp | 4 ++ .../Implementations/Cpp/Stub/rtti_tiger.hpp | 2 +- .../Implementations/Cpp/Stub/rtti_turtle.cpp | 5 +- .../Implementations/Cpp/Stub/rtti_turtle.hpp | 2 +- .../Implementations/Cpp/Stub/rtti_zoo.cpp | 8 +++ .../Implementations/Cpp/Stub/rtti_zoo.hpp | 4 +- 21 files changed, 222 insertions(+), 21 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp index c0746a29..a3779d4d 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp @@ -41,6 +41,17 @@ extern "C" { Class definition for Animal **************************************************************************************************************************/ +/** +* Get the name of the animal +* +* @param[in] pAnimal - Animal instance. +* @param[in] nResultBufferSize - size of the buffer (including trailing 0) +* @param[out] pResultNeededChars - will be filled with the count of the written bytes, or needed buffer size. +* @param[out] pResultBuffer - buffer of , may be NULL +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_animal_name(RTTI_Animal pAnimal, const RTTI_uint32 nResultBufferSize, RTTI_uint32* pResultNeededChars, char * pResultBuffer); + /************************************************************************************************************************* Class definition for Mammal **************************************************************************************************************************/ diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h index 62b011b6..c2c8f9b0 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h @@ -28,6 +28,17 @@ Interface version: 1.0.0 Class definition for Animal **************************************************************************************************************************/ +/** +* Get the name of the animal +* +* @param[in] pAnimal - Animal instance. +* @param[in] nResultBufferSize - size of the buffer (including trailing 0) +* @param[out] pResultNeededChars - will be filled with the count of the written bytes, or needed buffer size. +* @param[out] pResultBuffer - buffer of , may be NULL +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIAnimal_NamePtr) (RTTI_Animal pAnimal, const RTTI_uint32 nResultBufferSize, RTTI_uint32* pResultNeededChars, char * pResultBuffer); + /************************************************************************************************************************* Class definition for Mammal **************************************************************************************************************************/ @@ -169,6 +180,7 @@ typedef RTTIResult (*PRTTICreateZooPtr) (RTTI_Zoo * pInstance); typedef struct { void * m_LibraryHandle; + PRTTIAnimal_NamePtr m_Animal_Name; PRTTITiger_RoarPtr m_Tiger_Roar; PRTTIAnimalIterator_GetNextAnimalPtr m_AnimalIterator_GetNextAnimal; PRTTIZoo_IteratorPtr m_Zoo_Iterator; diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp index aa5c7e4d..aa2d3f85 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp @@ -358,6 +358,7 @@ class CAnimal : public CBase { { } + inline std::string Name(); }; /************************************************************************************************************************* @@ -705,6 +706,7 @@ class CZoo : public CBase { return RTTI_ERROR_INVALIDPARAM; pWrapperTable->m_LibraryHandle = nullptr; + pWrapperTable->m_Animal_Name = nullptr; pWrapperTable->m_Tiger_Roar = nullptr; pWrapperTable->m_AnimalIterator_GetNextAnimal = nullptr; pWrapperTable->m_Zoo_Iterator = nullptr; @@ -764,6 +766,15 @@ class CZoo : public CBase { dlerror(); #endif // _WIN32 + #ifdef _WIN32 + pWrapperTable->m_Animal_Name = (PRTTIAnimal_NamePtr) GetProcAddress(hLibrary, "rtti_animal_name"); + #else // _WIN32 + pWrapperTable->m_Animal_Name = (PRTTIAnimal_NamePtr) dlsym(hLibrary, "rtti_animal_name"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_Animal_Name == nullptr) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 pWrapperTable->m_Tiger_Roar = (PRTTITiger_RoarPtr) GetProcAddress(hLibrary, "rtti_tiger_roar"); #else // _WIN32 @@ -879,6 +890,10 @@ class CZoo : public CBase { SymbolLookupType pLookup = (SymbolLookupType)pSymbolLookupMethod; RTTIResult eLookupError = RTTI_SUCCESS; + eLookupError = (*pLookup)("rtti_animal_name", (void**)&(pWrapperTable->m_Animal_Name)); + if ( (eLookupError != 0) || (pWrapperTable->m_Animal_Name == nullptr) ) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + eLookupError = (*pLookup)("rtti_tiger_roar", (void**)&(pWrapperTable->m_Tiger_Roar)); if ( (eLookupError != 0) || (pWrapperTable->m_Tiger_Roar == nullptr) ) return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; @@ -936,6 +951,21 @@ class CZoo : public CBase { * Method definitions for class CAnimal */ + /** + * CAnimal::Name - Get the name of the animal + * @return + */ + std::string CAnimal::Name() + { + RTTI_uint32 bytesNeededResult = 0; + RTTI_uint32 bytesWrittenResult = 0; + CheckError(m_pWrapper->m_WrapperTable.m_Animal_Name(m_pHandle, 0, &bytesNeededResult, nullptr)); + std::vector bufferResult(bytesNeededResult); + CheckError(m_pWrapper->m_WrapperTable.m_Animal_Name(m_pHandle, bytesNeededResult, &bytesWrittenResult, &bufferResult[0])); + + return std::string(&bufferResult[0]); + } + /** * Method definitions for class CMammal */ diff --git a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py index 4954f4cd..ce9acf85 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py +++ b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py @@ -64,6 +64,7 @@ class FunctionTable: rtti_getsymbollookupmethod = None rtti_implementsinterface = None rtti_createzoo = None + rtti_animal_name = None rtti_tiger_roar = None rtti_animaliterator_getnextanimal = None rtti_zoo_iterator = None @@ -158,6 +159,12 @@ def _loadFunctionTableFromMethod(self, symbolLookupMethodAddress): methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.POINTER(ctypes.c_void_p)) self.lib.rtti_createzoo = methodType(int(methodAddress.value)) + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_animal_name")), methodAddress) + if err != 0: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.c_uint64, ctypes.POINTER(ctypes.c_uint64), ctypes.c_char_p) + self.lib.rtti_animal_name = methodType(int(methodAddress.value)) + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_tiger_roar")), methodAddress) if err != 0: raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) @@ -205,6 +212,9 @@ def _loadFunctionTable(self): self.lib.rtti_createzoo.restype = ctypes.c_int32 self.lib.rtti_createzoo.argtypes = [ctypes.POINTER(ctypes.c_void_p)] + self.lib.rtti_animal_name.restype = ctypes.c_int32 + self.lib.rtti_animal_name.argtypes = [ctypes.c_void_p, ctypes.c_uint64, ctypes.POINTER(ctypes.c_uint64), ctypes.c_char_p] + self.lib.rtti_tiger_roar.restype = ctypes.c_int32 self.lib.rtti_tiger_roar.argtypes = [ctypes.c_void_p] @@ -345,6 +355,17 @@ def ClassName(): def __init__(self, handle, wrapper): Base.__init__(self, handle, wrapper) + def Name(self): + nResultBufferSize = ctypes.c_uint64(0) + nResultNeededChars = ctypes.c_uint64(0) + pResultBuffer = ctypes.c_char_p(None) + self._wrapper.checkError(self, self._wrapper.lib.rtti_animal_name(self._handle, nResultBufferSize, nResultNeededChars, pResultBuffer)) + nResultBufferSize = ctypes.c_uint64(nResultNeededChars.value) + pResultBuffer = (ctypes.c_char * (nResultNeededChars.value))() + self._wrapper.checkError(self, self._wrapper.lib.rtti_animal_name(self._handle, nResultBufferSize, nResultNeededChars, pResultBuffer)) + + return pResultBuffer.value.decode() + ''' Class Implementation for Mammal diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp index c0746a29..a3779d4d 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp @@ -41,6 +41,17 @@ extern "C" { Class definition for Animal **************************************************************************************************************************/ +/** +* Get the name of the animal +* +* @param[in] pAnimal - Animal instance. +* @param[in] nResultBufferSize - size of the buffer (including trailing 0) +* @param[out] pResultNeededChars - will be filled with the count of the written bytes, or needed buffer size. +* @param[out] pResultBuffer - buffer of , may be NULL +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_animal_name(RTTI_Animal pAnimal, const RTTI_uint32 nResultBufferSize, RTTI_uint32* pResultNeededChars, char * pResultBuffer); + /************************************************************************************************************************* Class definition for Mammal **************************************************************************************************************************/ diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp index 4b48aa2b..97b074aa 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp @@ -110,6 +110,8 @@ template class ParameterCache_3 : public Paramete **************************************************************************************************************************/ class IBase { +private: + std::unique_ptr m_ParameterCache; public: /** * IBase::~IBase - virtual destructor of IBase @@ -167,6 +169,23 @@ class IBase { * @return Has the object been released */ virtual bool DecRefCount() = 0; + + /** + * IBase::_setCache - set parameter cache of object + */ + void _setCache(ParameterCache * pCache) + { + m_ParameterCache.reset(pCache); + } + + /** + * IBase::_getCache - returns parameter cache of object + */ + ParameterCache* _getCache() + { + return m_ParameterCache.get(); + } + }; @@ -208,6 +227,12 @@ typedef IBaseSharedPtr PIBase; class IAnimal : public virtual IBase { public: + /** + * IAnimal::Name - Get the name of the animal + * @return + */ + virtual std::string Name() = 0; + }; typedef IBaseSharedPtr PIAnimal; diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp index 962153f3..65cce6fe 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp @@ -60,6 +60,54 @@ RTTIResult handleUnhandledException(IBase * pIBaseClass) /************************************************************************************************************************* Class implementation for Animal **************************************************************************************************************************/ +RTTIResult rtti_animal_name(RTTI_Animal pAnimal, const RTTI_uint32 nResultBufferSize, RTTI_uint32* pResultNeededChars, char * pResultBuffer) +{ + IBase* pIBaseClass = (IBase *)pAnimal; + + try { + if ( (!pResultBuffer) && !(pResultNeededChars) ) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDPARAM); + std::string sResult(""); + IAnimal* pIAnimal = dynamic_cast(pIBaseClass); + if (!pIAnimal) + throw ERTTIInterfaceException(RTTI_ERROR_INVALIDCAST); + + bool isCacheCall = (pResultBuffer == nullptr); + if (isCacheCall) { + sResult = pIAnimal->Name(); + + pIAnimal->_setCache (new ParameterCache_1 (sResult)); + } + else { + auto cache = dynamic_cast*> (pIAnimal->_getCache ()); + if (cache == nullptr) + throw ERTTIInterfaceException(RTTI_ERROR_INVALIDCAST); + cache->retrieveData (sResult); + pIAnimal->_setCache (nullptr); + } + + if (pResultNeededChars) + *pResultNeededChars = (RTTI_uint32) (sResult.size()+1); + if (pResultBuffer) { + if (sResult.size() >= nResultBufferSize) + throw ERTTIInterfaceException (RTTI_ERROR_BUFFERTOOSMALL); + for (size_t iResult = 0; iResult < sResult.size(); iResult++) + pResultBuffer[iResult] = sResult[iResult]; + pResultBuffer[sResult.size()] = 0; + } + return RTTI_SUCCESS; + } + catch (ERTTIInterfaceException & Exception) { + return handleRTTIException(pIBaseClass, Exception); + } + catch (std::exception & StdException) { + return handleStdException(pIBaseClass, StdException); + } + catch (...) { + return handleUnhandledException(pIBaseClass); + } +} + /************************************************************************************************************************* Class implementation for Mammal @@ -187,6 +235,8 @@ RTTIResult RTTI::Impl::RTTI_GetProcAddress (const char * pProcName, void ** ppPr *ppProcAddress = nullptr; std::string sProcName (pProcName); + if (sProcName == "rtti_animal_name") + *ppProcAddress = (void*) &rtti_animal_name; if (sProcName == "rtti_tiger_roar") *ppProcAddress = (void*) &rtti_tiger_roar; if (sProcName == "rtti_animaliterator_getnextanimal") diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti.cpp index 27d39e4d..133b8aee 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti.cpp @@ -58,16 +58,16 @@ IZoo * CWrapper::CreateZoo() auto& animals = zoo->Animals(); - animals.emplace_back(new CGiraffe); - animals.emplace_back(new CTiger); - animals.emplace_back(new CTiger); - animals.emplace_back(new CSnake); - animals.emplace_back(new CTurtle); - animals.emplace_back(new CTurtle); - animals.emplace_back(new CTurtle); - animals.emplace_back(new CSnake); - animals.emplace_back(new CTiger); - animals.emplace_back(new CGiraffe); + animals.emplace_back(new CGiraffe("Gerald Giraffe")); + animals.emplace_back(new CTiger("Timmy Tiger")); + animals.emplace_back(new CTiger("Tony Tiger")); + animals.emplace_back(new CSnake("Sebastian Snake")); + animals.emplace_back(new CTurtle("Tobias Turtle")); + animals.emplace_back(new CTurtle("Theo Turtle")); + animals.emplace_back(new CTurtle("Tomás Turtle")); + animals.emplace_back(new CSnake("Slytherin Snake")); + animals.emplace_back(new CTiger("Travis Tiger")); + animals.emplace_back(new CGiraffe("Gary Giraffe")); return zoo; } diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animal.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animal.cpp index 4cfd0a35..a77f4d28 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animal.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animal.cpp @@ -12,11 +12,25 @@ Abstract: This is a stub class definition of CAnimal #include "rtti_interfaceexception.hpp" // Include custom headers here. - +#include using namespace RTTI::Impl; /************************************************************************************************************************* Class definition of CAnimal **************************************************************************************************************************/ +CAnimal::CAnimal() = default; + +CAnimal::CAnimal(std::string sName) + : m_sName(sName) +{} + +CAnimal::~CAnimal() +{ + std::cout << "Delete " << m_sName << std::endl; +} +std::string CAnimal::Name() +{ + return m_sName; +} diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animal.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animal.hpp index 251a3c02..9c839d0e 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animal.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animal.hpp @@ -38,13 +38,15 @@ class CAnimal : public virtual IAnimal, public virtual CBase { /** * Put private members here. */ - + std::string m_sName; protected: /** * Put protected members here. */ - + CAnimal(); + ~CAnimal(); + explicit CAnimal(std::string sName); public: /** @@ -55,6 +57,7 @@ class CAnimal : public virtual IAnimal, public virtual CBase { /** * Public member functions to implement. */ + std::string Name() override; }; diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_base.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_base.cpp index 92094e94..a0ab41f5 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_base.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_base.cpp @@ -12,7 +12,7 @@ Abstract: This is a stub class definition of CBase #include "rtti_interfaceexception.hpp" // Include custom headers here. - +#include using namespace RTTI::Impl; diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_giraffe.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_giraffe.cpp index ca8ca759..6c90106a 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_giraffe.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_giraffe.cpp @@ -19,4 +19,7 @@ using namespace RTTI::Impl; /************************************************************************************************************************* Class definition of CGiraffe **************************************************************************************************************************/ - +CGiraffe::CGiraffe(std::string sName) + : CAnimal(sName) +{ +} diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_giraffe.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_giraffe.hpp index f9d70fc0..7ee1c17d 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_giraffe.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_giraffe.hpp @@ -50,7 +50,7 @@ class CGiraffe : public virtual IGiraffe, public virtual CMammal { /** * Put additional public members here. They will not be visible in the external API. */ - + explicit CGiraffe(std::string sName); /** * Public member functions to implement. diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_snake.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_snake.cpp index 14992979..261208b2 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_snake.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_snake.cpp @@ -19,4 +19,8 @@ using namespace RTTI::Impl; /************************************************************************************************************************* Class definition of CSnake **************************************************************************************************************************/ +CSnake::CSnake(std::string sName) + : CAnimal(sName) +{ +} diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_snake.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_snake.hpp index 52dfc01b..d752f6cd 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_snake.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_snake.hpp @@ -50,7 +50,7 @@ class CSnake : public virtual ISnake, public virtual CReptile { /** * Put additional public members here. They will not be visible in the external API. */ - + explicit CSnake(std::string sName); /** * Public member functions to implement. diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.cpp index d136a99c..a318e5aa 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.cpp @@ -19,6 +19,10 @@ using namespace RTTI::Impl; /************************************************************************************************************************* Class definition of CTiger **************************************************************************************************************************/ +CTiger::CTiger(std::string sName) + : CAnimal(sName) +{ +} void CTiger::Roar() { diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.hpp index b8dbbec2..d49e2692 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.hpp @@ -50,7 +50,7 @@ class CTiger : public virtual ITiger, public virtual CMammal { /** * Put additional public members here. They will not be visible in the external API. */ - + explicit CTiger(std::string sName); /** * Public member functions to implement. diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_turtle.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_turtle.cpp index f5f097d7..bc14a6ad 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_turtle.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_turtle.cpp @@ -19,4 +19,7 @@ using namespace RTTI::Impl; /************************************************************************************************************************* Class definition of CTurtle **************************************************************************************************************************/ - +CTurtle::CTurtle(std::string sName) + : CAnimal(sName) +{ +} diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_turtle.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_turtle.hpp index d71de044..dd2423c6 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_turtle.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_turtle.hpp @@ -50,7 +50,7 @@ class CTurtle : public virtual ITurtle, public virtual CReptile { /** * Put additional public members here. They will not be visible in the external API. */ - + explicit CTurtle(std::string sName); /** * Public member functions to implement. diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.cpp index a27812b2..6ea8fb50 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.cpp @@ -12,6 +12,7 @@ Abstract: This is a stub class definition of CZoo #include "rtti_interfaceexception.hpp" // Include custom headers here. +#include "rtti_animal.hpp" #include "rtti_animaliterator.hpp" using namespace RTTI::Impl; @@ -19,6 +20,13 @@ using namespace RTTI::Impl; /************************************************************************************************************************* Class definition of CZoo **************************************************************************************************************************/ +CZoo::~CZoo() +{ + for(auto &&i: m_Animals) + { + i->DecRefCount(); + } +} std::vector &CZoo::Animals() { diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.hpp index 7f62bffa..1e1af969 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.hpp @@ -51,7 +51,9 @@ class CZoo : public virtual IZoo, public virtual CBase { /** * Put additional public members here. They will not be visible in the external API. */ - std::vector& Animals(); + ~CZoo(); + + std::vector& Animals(); /** From 2339361915ccb78295cb036243e75bfffe25af14 Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Thu, 28 Jan 2021 17:37:25 +0100 Subject: [PATCH 015/143] Update RTTI generated code (inline getClassName) --- .../Bindings/CppDynamic/rtti_dynamic.hpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp index aa2d3f85..7c7ffe90 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp @@ -289,7 +289,7 @@ class CWrapper { **************************************************************************************************************************/ class CBase { public: - static const std::string &getClassName(); + static inline const std::string &getClassName(); protected: /* Wrapper Object that created the class. */ @@ -348,7 +348,7 @@ class CBase { **************************************************************************************************************************/ class CAnimal : public CBase { public: - static const std::string &getClassName(); + static inline const std::string &getClassName(); /** * CAnimal::CAnimal - Constructor for Animal class. @@ -366,7 +366,7 @@ class CAnimal : public CBase { **************************************************************************************************************************/ class CMammal : public CAnimal { public: - static const std::string &getClassName(); + static inline const std::string &getClassName(); /** * CMammal::CMammal - Constructor for Mammal class. @@ -383,7 +383,7 @@ class CMammal : public CAnimal { **************************************************************************************************************************/ class CReptile : public CAnimal { public: - static const std::string &getClassName(); + static inline const std::string &getClassName(); /** * CReptile::CReptile - Constructor for Reptile class. @@ -400,7 +400,7 @@ class CReptile : public CAnimal { **************************************************************************************************************************/ class CGiraffe : public CMammal { public: - static const std::string &getClassName(); + static inline const std::string &getClassName(); /** * CGiraffe::CGiraffe - Constructor for Giraffe class. @@ -417,7 +417,7 @@ class CGiraffe : public CMammal { **************************************************************************************************************************/ class CTiger : public CMammal { public: - static const std::string &getClassName(); + static inline const std::string &getClassName(); /** * CTiger::CTiger - Constructor for Tiger class. @@ -435,7 +435,7 @@ class CTiger : public CMammal { **************************************************************************************************************************/ class CSnake : public CReptile { public: - static const std::string &getClassName(); + static inline const std::string &getClassName(); /** * CSnake::CSnake - Constructor for Snake class. @@ -452,7 +452,7 @@ class CSnake : public CReptile { **************************************************************************************************************************/ class CTurtle : public CReptile { public: - static const std::string &getClassName(); + static inline const std::string &getClassName(); /** * CTurtle::CTurtle - Constructor for Turtle class. @@ -469,7 +469,7 @@ class CTurtle : public CReptile { **************************************************************************************************************************/ class CAnimalIterator : public CBase { public: - static const std::string &getClassName(); + static inline const std::string &getClassName(); /** * CAnimalIterator::CAnimalIterator - Constructor for AnimalIterator class. @@ -487,7 +487,7 @@ class CAnimalIterator : public CBase { **************************************************************************************************************************/ class CZoo : public CBase { public: - static const std::string &getClassName(); + static inline const std::string &getClassName(); /** * CZoo::CZoo - Constructor for Zoo class. From e7042a50194f3bb5aabe81e6acb1b5acc12a8306 Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Thu, 28 Jan 2021 17:38:31 +0100 Subject: [PATCH 016/143] Fix CPP binding to inc ref count --- .../Bindings/CppDynamic/rtti_dynamic.hpp | 10 ++++++---- Source/buildbindingccpp.go | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp index 7c7ffe90..e3ba72b0 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp @@ -339,8 +339,6 @@ class CBase { } friend class CWrapper; - template - friend std::shared_ptr rtti_cast(PBase obj); }; /************************************************************************************************************************* @@ -574,8 +572,12 @@ class CZoo : public CBase { { static_assert(std::is_convertible::value, "T must be convertible to RTTI::CBase"); - if (pObj && pObj->m_pWrapper->ImplementsInterface(pObj.get(), T::getClassName())){ - return std::make_shared(pObj->m_pWrapper, pObj->m_pHandle); + if (pObj) { + CWrapper *pWrapper = pObj->wrapper(); + if (pWrapper->ImplementsInterface(pObj.get(), T::getClassName())) { + pWrapper->AcquireInstance(pObj); + return std::make_shared(pWrapper, pObj->handle()); + } } return nullptr; diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index e49c9f1c..6c24f0a3 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -900,8 +900,6 @@ func writeDynamicCppBaseClassMethods(component ComponentDefinition, baseClass Co w.Writeln("") w.Writeln(" friend class CWrapper;") - w.Writeln(" template ") - w.Writeln(" friend std::shared_ptr %s_cast(PBase obj);", strings.ToLower(NameSpace)) return nil } @@ -1425,8 +1423,12 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln(" {") w.Writeln(" static_assert(std::is_convertible::value, \"T must be convertible to %s::CBase\");", NameSpace) w.Writeln("") - w.Writeln(" if (pObj && pObj->m_pWrapper->ImplementsInterface(pObj.get(), T::getClassName())){") - w.Writeln(" return std::make_shared(pObj->m_pWrapper, pObj->m_pHandle);") + w.Writeln(" if (pObj) {") + w.Writeln(" CWrapper *pWrapper = pObj->wrapper();") + w.Writeln(" if (pWrapper->ImplementsInterface(pObj.get(), T::getClassName())) {") + w.Writeln(" pWrapper->AcquireInstance(pObj);") + w.Writeln(" return std::make_shared(pWrapper, pObj->handle());") + w.Writeln(" }") w.Writeln(" }") w.Writeln("") w.Writeln(" return nullptr;") From 883d6e08bd6a07c45527890550ab23363b2774b8 Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Thu, 28 Jan 2021 17:44:01 +0100 Subject: [PATCH 017/143] Fix Python binding to inc ref count --- Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py | 1 + Source/buildbindingpython.go | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py index ce9acf85..588ff161 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py +++ b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py @@ -333,6 +333,7 @@ def ClassName(): @classmethod def cast(cls, instance): if instance and instance._wrapper.ImplementsInterface(instance, cls.ClassName()): + instance._wrapper.AcquireInstance(instance) return cls(instance._handle, instance._wrapper) return None diff --git a/Source/buildbindingpython.go b/Source/buildbindingpython.go index a61b32dd..baa41f1c 100644 --- a/Source/buildbindingpython.go +++ b/Source/buildbindingpython.go @@ -751,9 +751,10 @@ func writePythonClass(component ComponentDefinition, class ComponentDefinitionCl w.Writeln(" @classmethod") w.Writeln(" def cast(cls, instance):") - w.Writeln(" if instance and instance._wrapper.ImplementsInterface(instance, cls.ClassName()):") - w.Writeln(" return cls(instance._handle, instance._wrapper)") - w.Writeln(" return None") + w.Writeln(" if instance and instance._wrapper.ImplementsInterface(instance, cls.ClassName()):") + w.Writeln(" instance._wrapper.AcquireInstance(instance)") + w.Writeln(" return cls(instance._handle, instance._wrapper)") + w.Writeln(" return None") w.Writeln(" ") w.Writeln(" def __init__(self, handle, wrapper):") From a40ca23454f9237a7574632bf799c5669cdf020d Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Thu, 28 Jan 2021 17:45:11 +0100 Subject: [PATCH 018/143] Update RTTI examples to print name --- .../RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp | 2 +- Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp b/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp index 78f40d9a..d5079a34 100644 --- a/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp +++ b/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp @@ -34,10 +34,10 @@ int main() using namespace RTTI; while (auto animal = iter->GetNextAnimal()) { - std::cout << "Animal: 0x" << std::hex << animal->handle() << std::endl; if (auto tiger = rtti_cast(animal)) { tiger->Roar(); } + std::cout << "Animal name: " << animal->Name() << std::endl; } } catch (std::exception &e) diff --git a/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py b/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py index 1be17f6e..984534cf 100644 --- a/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py +++ b/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py @@ -32,9 +32,9 @@ def main(): iter = zoo.Iterator() while animal := iter.GetNextAnimal(): - print("animal: " + str(animal._handle)) if tiger := RTTI.Tiger.cast(animal): tiger.Roar() + print("Animal name: " + animal.Name()) if __name__ == "__main__": try: From 40fb5f3620c248c04e4a4ae19e7ad1e4ce611328 Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Tue, 23 Feb 2021 15:35:39 +0100 Subject: [PATCH 019/143] Add missing Name method to RTTI.xml --- Examples/RTTI/RTTI.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Examples/RTTI/RTTI.xml b/Examples/RTTI/RTTI.xml index cf7cd4ae..a0677efa 100644 --- a/Examples/RTTI/RTTI.xml +++ b/Examples/RTTI/RTTI.xml @@ -32,7 +32,10 @@ - + + + + @@ -68,7 +71,8 @@ + symbollookupmethod="GetSymbolLookupMethod" implementsinterfacemethod="ImplementsInterface" + stringoutclassname="Base"> From c302c9e858d4e3c1029c5dce53d2de632f2b3f14 Mon Sep 17 00:00:00 2001 From: Martin Weismann Date: Wed, 7 Apr 2021 22:34:17 +0200 Subject: [PATCH 020/143] Fix names of special classes and methods in generation code --- Source/buildbindingccpp.go | 4 ++-- Source/buildbindingpython.go | 6 ++++-- Source/buildimplementationcpp.go | 10 +++++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index 6c24f0a3..03d58d6a 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -1425,8 +1425,8 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln("") w.Writeln(" if (pObj) {") w.Writeln(" CWrapper *pWrapper = pObj->wrapper();") - w.Writeln(" if (pWrapper->ImplementsInterface(pObj.get(), T::getClassName())) {") - w.Writeln(" pWrapper->AcquireInstance(pObj);") + w.Writeln(" if (pWrapper->%s(pObj.get(), T::getClassName())) {", global.ImplementsInterfaceMethod) + w.Writeln(" pWrapper->%s(pObj);", global.AcquireMethod) w.Writeln(" return std::make_shared(pWrapper, pObj->handle());") w.Writeln(" }") w.Writeln(" }") diff --git a/Source/buildbindingpython.go b/Source/buildbindingpython.go index baa41f1c..37820fb1 100644 --- a/Source/buildbindingpython.go +++ b/Source/buildbindingpython.go @@ -723,6 +723,8 @@ func generateCTypesParameter(param ComponentDefinitionParam, className string, m func writePythonClass(component ComponentDefinition, class ComponentDefinitionClass, w LanguageWriter, NameSpace string) error { pythonBaseClassName := fmt.Sprintf("%s", component.Global.BaseClassName) + + global := component.Global w.Writeln("''' Class Implementation for %s", class.ClassName) w.Writeln("'''") @@ -751,8 +753,8 @@ func writePythonClass(component ComponentDefinition, class ComponentDefinitionCl w.Writeln(" @classmethod") w.Writeln(" def cast(cls, instance):") - w.Writeln(" if instance and instance._wrapper.ImplementsInterface(instance, cls.ClassName()):") - w.Writeln(" instance._wrapper.AcquireInstance(instance)") + w.Writeln(" if instance and instance._wrapper.%s(instance, cls.ClassName()):", global.ImplementsInterfaceMethod) + w.Writeln(" instance._wrapper.%s(instance)", global.AcquireMethod) w.Writeln(" return cls(instance._handle, instance._wrapper)") w.Writeln(" return None") w.Writeln(" ") diff --git a/Source/buildimplementationcpp.go b/Source/buildimplementationcpp.go index 41ae25a1..62dc080b 100644 --- a/Source/buildimplementationcpp.go +++ b/Source/buildimplementationcpp.go @@ -560,7 +560,7 @@ func buildCPPInterfaces(component ComponentDefinition, w LanguageWriter, NameSpa for j := 0; j < len(global.Methods); j++ { method := global.Methods[j] - // Omit Journal Method + // Omit special functions that are automatically implemented isSpecialFunction, err := CheckHeaderSpecialFunction(method, global); if err != nil { return err @@ -618,7 +618,7 @@ func buildCPPGlobalStubFile(component ComponentDefinition, stubfile LanguageWrit thisMethodDefaultImpl := defaultImplementation - // Treat special functions + // Omit special functions that are automatically implemented isSpecialFunction, err := CheckHeaderSpecialFunction(method, component.Global); if err != nil { return err @@ -691,7 +691,7 @@ func buildCPPInterfaceWrapperMethods(component ComponentDefinition, class Compon return nil } -func writeCImplementsInterfaceMethod(component ComponentDefinition, method ComponentDefinitionMethod, w LanguageWriter, NameSpace string) error { +func writeCImplementsInterfaceMethod(component ComponentDefinition, method ComponentDefinitionMethod, w LanguageWriter, NameSpace string, IBaseClassName string) error { cParams, err := GenerateCParameters(method, "", NameSpace) if err != nil { return err @@ -715,7 +715,7 @@ func writeCImplementsInterfaceMethod(component ComponentDefinition, method Compo w.Writeln("%sResult %s(%s)", NameSpace, CMethodName, cparameters) w.Writeln("{") - w.Writeln(" IBase* pIBaseClassInstance = (IBase *)pObject;") + w.Writeln(" %s* pIBaseClassInstance = (%s *)pObject;", IBaseClassName, IBaseClassName) for i := 0; i < len(component.Classes); i++ { class := component.Classes[i] w.Writeln(" if (strcmp(pClassName, \"%s\") == 0) {", class.ClassName) @@ -902,7 +902,7 @@ func buildCPPInterfaceWrapper(component ComponentDefinition, w LanguageWriter, N } if (isSpecialFunction == eSpecialMethodImplementsInterface) { - err = writeCImplementsInterfaceMethod(component, method, w, NameSpace) + err = writeCImplementsInterfaceMethod(component, method, w, NameSpace, IBaseClassName) if err != nil { return err } From a55da70a46f09f8364d964be248f7a9f28e5707a Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Thu, 8 Apr 2021 11:03:57 +0200 Subject: [PATCH 021/143] Hash class ids in C++ bindings --- Examples/RTTI/RTTI.xml | 2 +- .../Bindings/CppDynamic/rtti_abi.hpp | 5 +- .../Bindings/CppDynamic/rtti_dynamic.h | 5 +- .../Bindings/CppDynamic/rtti_dynamic.hpp | 95 ++++++++++++++++++- .../RTTI_component/Bindings/Python/RTTI.py | 11 ++- .../Cpp/Interfaces/rtti_abi.hpp | 5 +- .../Cpp/Interfaces/rtti_interfacewrapper.cpp | 2 +- Source/buildbindingccpp.go | 28 +++++- Source/componentdefinition.go | 2 +- 9 files changed, 135 insertions(+), 20 deletions(-) diff --git a/Examples/RTTI/RTTI.xml b/Examples/RTTI/RTTI.xml index a0677efa..fb42fe2d 100644 --- a/Examples/RTTI/RTTI.xml +++ b/Examples/RTTI/RTTI.xml @@ -98,7 +98,7 @@ - + diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp index a3779d4d..ae254c13 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp @@ -173,11 +173,12 @@ RTTI_DECLSPEC RTTIResult rtti_getsymbollookupmethod(RTTI_pvoid * pSymbolLookupMe * Test whether an object implements a given interface * * @param[in] pObject - Instance Handle -* @param[in] pClassName - Class name of the interface to test +* @param[in] nClassHashBufferSize - Number of elements in buffer +* @param[in] pClassHashBuffer - uint8 buffer of Hashed class name of the interface to test * @param[out] pImplementsInterface - Will be set to true if pInstance implements the interface, false otherwise * @return error code or 0 (success) */ -RTTI_DECLSPEC RTTIResult rtti_implementsinterface(RTTI_Base pObject, const char * pClassName, bool * pImplementsInterface); +RTTI_DECLSPEC RTTIResult rtti_implementsinterface(RTTI_Base pObject, RTTI_uint64 nClassHashBufferSize, const RTTI_uint8 * pClassHashBuffer, bool * pImplementsInterface); /** * Create a new zoo with animals diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h index c2c8f9b0..859684e1 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h @@ -160,11 +160,12 @@ typedef RTTIResult (*PRTTIGetSymbolLookupMethodPtr) (RTTI_pvoid * pSymbolLookupM * Test whether an object implements a given interface * * @param[in] pObject - Instance Handle -* @param[in] pClassName - Class name of the interface to test +* @param[in] nClassHashBufferSize - Number of elements in buffer +* @param[in] pClassHashBuffer - uint8 buffer of Hashed class name of the interface to test * @param[out] pImplementsInterface - Will be set to true if pInstance implements the interface, false otherwise * @return error code or 0 (success) */ -typedef RTTIResult (*PRTTIImplementsInterfacePtr) (RTTI_Base pObject, const char * pClassName, bool * pImplementsInterface); +typedef RTTIResult (*PRTTIImplementsInterfacePtr) (RTTI_Base pObject, RTTI_uint64 nClassHashBufferSize, const RTTI_uint8 * pClassHashBuffer, bool * pImplementsInterface); /** * Create a new zoo with animals diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp index e3ba72b0..c46feb31 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp @@ -25,6 +25,7 @@ Interface version: 1.0.0 #else // _WIN32 #include #endif // _WIN32 +#include #include #include #include @@ -98,6 +99,8 @@ typedef PZoo PRTTIZoo; template inline std::shared_ptr rtti_cast(PBase obj); +using RTTI_ClassHash = std::array; + /************************************************************************************************************************* classParam Definition **************************************************************************************************************************/ @@ -250,7 +253,7 @@ class CWrapper { inline void AcquireInstance(classParam pInstance); inline void InjectComponent(const std::string & sNameSpace, const RTTI_pvoid pSymbolAddressMethod); inline RTTI_pvoid GetSymbolLookupMethod(); - inline bool ImplementsInterface(classParam pObject, const std::string & sClassName); + inline bool ImplementsInterface(classParam pObject, const CInputVector & ClassHashBuffer); inline PZoo CreateZoo(); private: @@ -290,6 +293,7 @@ class CWrapper { class CBase { public: static inline const std::string &getClassName(); + static inline const RTTI_ClassHash &getClassHash(); protected: /* Wrapper Object that created the class. */ @@ -347,6 +351,7 @@ class CBase { class CAnimal : public CBase { public: static inline const std::string &getClassName(); + static inline const RTTI_ClassHash &getClassHash(); /** * CAnimal::CAnimal - Constructor for Animal class. @@ -365,6 +370,7 @@ class CAnimal : public CBase { class CMammal : public CAnimal { public: static inline const std::string &getClassName(); + static inline const RTTI_ClassHash &getClassHash(); /** * CMammal::CMammal - Constructor for Mammal class. @@ -382,6 +388,7 @@ class CMammal : public CAnimal { class CReptile : public CAnimal { public: static inline const std::string &getClassName(); + static inline const RTTI_ClassHash &getClassHash(); /** * CReptile::CReptile - Constructor for Reptile class. @@ -399,6 +406,7 @@ class CReptile : public CAnimal { class CGiraffe : public CMammal { public: static inline const std::string &getClassName(); + static inline const RTTI_ClassHash &getClassHash(); /** * CGiraffe::CGiraffe - Constructor for Giraffe class. @@ -416,6 +424,7 @@ class CGiraffe : public CMammal { class CTiger : public CMammal { public: static inline const std::string &getClassName(); + static inline const RTTI_ClassHash &getClassHash(); /** * CTiger::CTiger - Constructor for Tiger class. @@ -434,6 +443,7 @@ class CTiger : public CMammal { class CSnake : public CReptile { public: static inline const std::string &getClassName(); + static inline const RTTI_ClassHash &getClassHash(); /** * CSnake::CSnake - Constructor for Snake class. @@ -451,6 +461,7 @@ class CSnake : public CReptile { class CTurtle : public CReptile { public: static inline const std::string &getClassName(); + static inline const RTTI_ClassHash &getClassHash(); /** * CTurtle::CTurtle - Constructor for Turtle class. @@ -468,6 +479,7 @@ class CTurtle : public CReptile { class CAnimalIterator : public CBase { public: static inline const std::string &getClassName(); + static inline const RTTI_ClassHash &getClassHash(); /** * CAnimalIterator::CAnimalIterator - Constructor for AnimalIterator class. @@ -486,6 +498,7 @@ class CAnimalIterator : public CBase { class CZoo : public CBase { public: static inline const std::string &getClassName(); + static inline const RTTI_ClassHash &getClassHash(); /** * CZoo::CZoo - Constructor for Zoo class. @@ -508,60 +521,130 @@ class CZoo : public CBase { return s_sClassName; } + const RTTI_ClassHash &CBase::getClassHash() + { + // MD5(Base): 095A1B43EFFEC73955E31E790438DE49 + static const RTTI_ClassHash s_sClassHash = { 0x9, 0x5A, 0x1B, 0x43, 0xEF, 0xFE, 0xC7, 0x39, 0x55, 0xE3, 0x1E, 0x79, 0x4, 0x38, 0xDE, 0x49, }; + return s_sClassHash; + } + const std::string &CAnimal::getClassName() { static const std::string s_sClassName = "Animal"; return s_sClassName; } + const RTTI_ClassHash &CAnimal::getClassHash() + { + // MD5(Animal): 161E7CE7BFDC89AB4B9F52C1D4C94212 + static const RTTI_ClassHash s_sClassHash = { 0x16, 0x1E, 0x7C, 0xE7, 0xBF, 0xDC, 0x89, 0xAB, 0x4B, 0x9F, 0x52, 0xC1, 0xD4, 0xC9, 0x42, 0x12, }; + return s_sClassHash; + } + const std::string &CMammal::getClassName() { static const std::string s_sClassName = "Mammal"; return s_sClassName; } + const RTTI_ClassHash &CMammal::getClassHash() + { + // MD5(Mammal): 37426113D129E79F548F4C90930FA697 + static const RTTI_ClassHash s_sClassHash = { 0x37, 0x42, 0x61, 0x13, 0xD1, 0x29, 0xE7, 0x9F, 0x54, 0x8F, 0x4C, 0x90, 0x93, 0xF, 0xA6, 0x97, }; + return s_sClassHash; + } + const std::string &CReptile::getClassName() { static const std::string s_sClassName = "Reptile"; return s_sClassName; } + const RTTI_ClassHash &CReptile::getClassHash() + { + // MD5(Reptile): AA645186A4B5F3F27952C2FA5485FAB2 + static const RTTI_ClassHash s_sClassHash = { 0xAA, 0x64, 0x51, 0x86, 0xA4, 0xB5, 0xF3, 0xF2, 0x79, 0x52, 0xC2, 0xFA, 0x54, 0x85, 0xFA, 0xB2, }; + return s_sClassHash; + } + const std::string &CGiraffe::getClassName() { static const std::string s_sClassName = "Giraffe"; return s_sClassName; } + const RTTI_ClassHash &CGiraffe::getClassHash() + { + // MD5(Giraffe): 427DEBB81D265A0EDD8789F30B11BEB6 + static const RTTI_ClassHash s_sClassHash = { 0x42, 0x7D, 0xEB, 0xB8, 0x1D, 0x26, 0x5A, 0xE, 0xDD, 0x87, 0x89, 0xF3, 0xB, 0x11, 0xBE, 0xB6, }; + return s_sClassHash; + } + const std::string &CTiger::getClassName() { static const std::string s_sClassName = "Tiger"; return s_sClassName; } + const RTTI_ClassHash &CTiger::getClassHash() + { + // MD5(Tiger): 454C9843110686BF6F67CE5115B66617 + static const RTTI_ClassHash s_sClassHash = { 0x45, 0x4C, 0x98, 0x43, 0x11, 0x6, 0x86, 0xBF, 0x6F, 0x67, 0xCE, 0x51, 0x15, 0xB6, 0x66, 0x17, }; + return s_sClassHash; + } + const std::string &CSnake::getClassName() { static const std::string s_sClassName = "Snake"; return s_sClassName; } + const RTTI_ClassHash &CSnake::getClassHash() + { + // MD5(Snake): DFA90F1B4EB3AFFBD3B46AF34ED2477C + static const RTTI_ClassHash s_sClassHash = { 0xDF, 0xA9, 0xF, 0x1B, 0x4E, 0xB3, 0xAF, 0xFB, 0xD3, 0xB4, 0x6A, 0xF3, 0x4E, 0xD2, 0x47, 0x7C, }; + return s_sClassHash; + } + const std::string &CTurtle::getClassName() { static const std::string s_sClassName = "Turtle"; return s_sClassName; } + const RTTI_ClassHash &CTurtle::getClassHash() + { + // MD5(Turtle): 06DEBA5908B007EB6F32D8D95F3F61B5 + static const RTTI_ClassHash s_sClassHash = { 0x6, 0xDE, 0xBA, 0x59, 0x8, 0xB0, 0x7, 0xEB, 0x6F, 0x32, 0xD8, 0xD9, 0x5F, 0x3F, 0x61, 0xB5, }; + return s_sClassHash; + } + const std::string &CAnimalIterator::getClassName() { static const std::string s_sClassName = "AnimalIterator"; return s_sClassName; } + const RTTI_ClassHash &CAnimalIterator::getClassHash() + { + // MD5(AnimalIterator): C2B36A84C6C032204E5C923C581071E7 + static const RTTI_ClassHash s_sClassHash = { 0xC2, 0xB3, 0x6A, 0x84, 0xC6, 0xC0, 0x32, 0x20, 0x4E, 0x5C, 0x92, 0x3C, 0x58, 0x10, 0x71, 0xE7, }; + return s_sClassHash; + } + const std::string &CZoo::getClassName() { static const std::string s_sClassName = "Zoo"; return s_sClassName; } + const RTTI_ClassHash &CZoo::getClassHash() + { + // MD5(Zoo): BFA888A354DB97C7CBEFB9D050B94CA3 + static const RTTI_ClassHash s_sClassHash = { 0xBF, 0xA8, 0x88, 0xA3, 0x54, 0xDB, 0x97, 0xC7, 0xCB, 0xEF, 0xB9, 0xD0, 0x50, 0xB9, 0x4C, 0xA3, }; + return s_sClassHash; + } + /************************************************************************************************************************* RTTI cast implementation @@ -574,7 +657,9 @@ class CZoo : public CBase { if (pObj) { CWrapper *pWrapper = pObj->wrapper(); - if (pWrapper->ImplementsInterface(pObj.get(), T::getClassName())) { + const RTTI_ClassHash & ClassHash = T::getClassHash(); + CInputVector ClassHashBuffer(ClassHash.data(), ClassHash.size()); + if (pWrapper->ImplementsInterface(pObj.get(), ClassHashBuffer)) { pWrapper->AcquireInstance(pObj); return std::make_shared(pWrapper, pObj->handle()); } @@ -663,14 +748,14 @@ class CZoo : public CBase { /** * CWrapper::ImplementsInterface - Test whether an object implements a given interface * @param[in] pObject - Instance Handle - * @param[in] sClassName - Class name of the interface to test + * @param[in] ClassHashBuffer - Hashed class name of the interface to test * @return Will be set to true if pInstance implements the interface, false otherwise */ - inline bool CWrapper::ImplementsInterface(classParam pObject, const std::string & sClassName) + inline bool CWrapper::ImplementsInterface(classParam pObject, const CInputVector & ClassHashBuffer) { RTTIHandle hObject = pObject.GetHandle(); bool resultImplementsInterface = 0; - CheckError(nullptr,m_WrapperTable.m_ImplementsInterface(hObject, sClassName.c_str(), &resultImplementsInterface)); + CheckError(nullptr,m_WrapperTable.m_ImplementsInterface(hObject, (RTTI_uint64)ClassHashBuffer.size(), ClassHashBuffer.data(), &resultImplementsInterface)); return resultImplementsInterface; } diff --git a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py index 588ff161..c9eb16db 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py +++ b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py @@ -150,7 +150,7 @@ def _loadFunctionTableFromMethod(self, symbolLookupMethodAddress): err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_implementsinterface")), methodAddress) if err != 0: raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) - methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.c_char_p, ctypes.POINTER(ctypes.c_bool)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.c_uint64, ctypes.POINTER(ctypes.c_uint8), ctypes.POINTER(ctypes.c_bool)) self.lib.rtti_implementsinterface = methodType(int(methodAddress.value)) err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_createzoo")), methodAddress) @@ -207,7 +207,7 @@ def _loadFunctionTable(self): self.lib.rtti_getsymbollookupmethod.argtypes = [ctypes.POINTER(ctypes.c_void_p)] self.lib.rtti_implementsinterface.restype = ctypes.c_int32 - self.lib.rtti_implementsinterface.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.POINTER(ctypes.c_bool)] + self.lib.rtti_implementsinterface.argtypes = [ctypes.c_void_p, ctypes.c_uint64, ctypes.POINTER(ctypes.c_uint8), ctypes.POINTER(ctypes.c_bool)] self.lib.rtti_createzoo.restype = ctypes.c_int32 self.lib.rtti_createzoo.argtypes = [ctypes.POINTER(ctypes.c_void_p)] @@ -299,15 +299,16 @@ def GetSymbolLookupMethod(self): return pSymbolLookupMethod.value - def ImplementsInterface(self, ObjectObject, ClassName): + def ImplementsInterface(self, ObjectObject, ClassHash): ObjectHandle = None if ObjectObject: ObjectHandle = ObjectObject._handle else: raise ERTTIException(ErrorCodes.INVALIDPARAM, 'Invalid return/output value') - pClassName = ctypes.c_char_p(str.encode(ClassName)) + nClassHashCount = ctypes.c_uint64(len(ClassHash)) + pClassHashBuffer = (ctypes.c_uint8*len(ClassHash))(*ClassHash) pImplementsInterface = ctypes.c_bool() - self.checkError(None, self.lib.rtti_implementsinterface(ObjectHandle, pClassName, pImplementsInterface)) + self.checkError(None, self.lib.rtti_implementsinterface(ObjectHandle, nClassHashCount, pClassHashBuffer, pImplementsInterface)) return pImplementsInterface.value diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp index a3779d4d..ae254c13 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp @@ -173,11 +173,12 @@ RTTI_DECLSPEC RTTIResult rtti_getsymbollookupmethod(RTTI_pvoid * pSymbolLookupMe * Test whether an object implements a given interface * * @param[in] pObject - Instance Handle -* @param[in] pClassName - Class name of the interface to test +* @param[in] nClassHashBufferSize - Number of elements in buffer +* @param[in] pClassHashBuffer - uint8 buffer of Hashed class name of the interface to test * @param[out] pImplementsInterface - Will be set to true if pInstance implements the interface, false otherwise * @return error code or 0 (success) */ -RTTI_DECLSPEC RTTIResult rtti_implementsinterface(RTTI_Base pObject, const char * pClassName, bool * pImplementsInterface); +RTTI_DECLSPEC RTTIResult rtti_implementsinterface(RTTI_Base pObject, RTTI_uint64 nClassHashBufferSize, const RTTI_uint8 * pClassHashBuffer, bool * pImplementsInterface); /** * Create a new zoo with animals diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp index 65cce6fe..3660c64a 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp @@ -437,7 +437,7 @@ RTTIResult rtti_getsymbollookupmethod(RTTI_pvoid * pSymbolLookupMethod) Test whether an object implements a given interface **************************************************************************************************************************/ -RTTIResult rtti_implementsinterface(RTTI_Base pObject, const char * pClassName, bool * pImplementsInterface) +RTTIResult rtti_implementsinterface(RTTI_Base pObject, RTTI_uint64 nClassHashBufferSize, const RTTI_uint8 * pClassHashBuffer, bool * pImplementsInterface) { IBase* pIBaseClassInstance = (IBase *)pObject; if (strcmp(pClassName, "Base") == 0) { diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index 03d58d6a..ddb9fb7d 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -36,6 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package main import ( + "crypto/md5" "fmt" "log" "path" @@ -1130,6 +1131,7 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln("#else // _WIN32") w.Writeln("#include ") w.Writeln("#endif // _WIN32") + w.Writeln("#include ") w.Writeln("#include ") w.Writeln("#include ") w.Writeln("#include ") @@ -1147,6 +1149,8 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln("**************************************************************************************************************************/") w.Writeln("template ") w.Writeln("inline std::shared_ptr %s_cast(PBase obj);", strings.ToLower(NameSpace)) + w.Writeln("") + w.Writeln("using %s_ClassHash = std::array<%s_uint8, %d>;", NameSpace, NameSpace, md5.Size) w.Writeln("") w.Writeln("/*************************************************************************************************************************") @@ -1367,6 +1371,7 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln("class %s %s{", cppClassName, inheritanceSpecifier) w.Writeln("public:") w.Writeln(" static inline const std::string &getClassName();") + w.Writeln(" static inline const %s_ClassHash &getClassHash();", NameSpace) w.Writeln(" ") if !component.isBaseClass(class) { w.Writeln(" /**") @@ -1410,6 +1415,25 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln(" return s_sClassName;") w.Writeln(" }") w.Writeln("") + + classHash := md5.New() + classHash.Write([]byte(class.ClassName)) + classHashBytes := classHash.Sum(nil) + + w.Writeln(" const %s_ClassHash &C%s::getClassHash()", NameSpace, class.ClassName) + w.Writeln(" {") + w.Writeln(" // MD5(%s): %X", class.ClassName, classHashBytes) + + w.BeginLine() + w.Printf(" static const %s_ClassHash s_sClassHash = {", NameSpace) + for j := 0; j < len(classHashBytes); j++ { + w.Printf(" 0x%X,", classHashBytes[j]) + } + w.Printf(" };") + w.EndLine() + w.Writeln(" return s_sClassHash;") + w.Writeln(" }") + w.Writeln("") } w.Writeln("") @@ -1425,7 +1449,9 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln("") w.Writeln(" if (pObj) {") w.Writeln(" CWrapper *pWrapper = pObj->wrapper();") - w.Writeln(" if (pWrapper->%s(pObj.get(), T::getClassName())) {", global.ImplementsInterfaceMethod) + w.Writeln(" const %s_ClassHash & ClassHash = T::getClassHash();", NameSpace) + w.Writeln(" CInputVector<%s_uint8> ClassHashBuffer(ClassHash.data(), ClassHash.size());", NameSpace) + w.Writeln(" if (pWrapper->%s(pObj.get(), ClassHashBuffer)) {", global.ImplementsInterfaceMethod) w.Writeln(" pWrapper->%s(pObj);", global.AcquireMethod) w.Writeln(" return std::make_shared(pWrapper, pObj->handle());") w.Writeln(" }") diff --git a/Source/componentdefinition.go b/Source/componentdefinition.go index 66938af4..18932433 100644 --- a/Source/componentdefinition.go +++ b/Source/componentdefinition.go @@ -1136,7 +1136,7 @@ func CheckHeaderSpecialFunction (method ComponentDefinitionMethod, global Compon } if (method.Params[0].ParamType != "class") || (method.Params[0].ParamPass != "in") || - (method.Params[1].ParamType != "string") || (method.Params[1].ParamPass != "in") || + (method.Params[1].ParamType != "basicarray") || (method.Params[1].ParamClass != "uint8") || (method.Params[1].ParamPass != "in") || (method.Params[2].ParamType != "bool") || (method.Params[2].ParamPass != "return") || (method.Params[0].ParamClass != global.BaseClassName) { return eSpecialMethodNone, errors.New ("Implements Interface method does not match the expected function template"); From 67088cb31b9919515cc4ad9a96924a38203191fa Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Thu, 8 Apr 2021 12:58:57 +0200 Subject: [PATCH 022/143] Use hash to id class in C++ implementation --- .../Bindings/CppDynamic/rtti_dynamic.hpp | 12 +- .../Cpp/Interfaces/rtti_interfacewrapper.cpp | 114 ++++++++++++------ Source/buildbindingccpp.go | 10 +- Source/buildimplementationcpp.go | 51 ++++++-- Source/componentdefinition.go | 25 +++- 5 files changed, 148 insertions(+), 64 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp index c46feb31..9606ce35 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp @@ -524,7 +524,7 @@ class CZoo : public CBase { const RTTI_ClassHash &CBase::getClassHash() { // MD5(Base): 095A1B43EFFEC73955E31E790438DE49 - static const RTTI_ClassHash s_sClassHash = { 0x9, 0x5A, 0x1B, 0x43, 0xEF, 0xFE, 0xC7, 0x39, 0x55, 0xE3, 0x1E, 0x79, 0x4, 0x38, 0xDE, 0x49, }; + static const RTTI_ClassHash s_sClassHash = { 0x09, 0x5A, 0x1B, 0x43, 0xEF, 0xFE, 0xC7, 0x39, 0x55, 0xE3, 0x1E, 0x79, 0x04, 0x38, 0xDE, 0x49, }; return s_sClassHash; } @@ -550,7 +550,7 @@ class CZoo : public CBase { const RTTI_ClassHash &CMammal::getClassHash() { // MD5(Mammal): 37426113D129E79F548F4C90930FA697 - static const RTTI_ClassHash s_sClassHash = { 0x37, 0x42, 0x61, 0x13, 0xD1, 0x29, 0xE7, 0x9F, 0x54, 0x8F, 0x4C, 0x90, 0x93, 0xF, 0xA6, 0x97, }; + static const RTTI_ClassHash s_sClassHash = { 0x37, 0x42, 0x61, 0x13, 0xD1, 0x29, 0xE7, 0x9F, 0x54, 0x8F, 0x4C, 0x90, 0x93, 0x0F, 0xA6, 0x97, }; return s_sClassHash; } @@ -576,7 +576,7 @@ class CZoo : public CBase { const RTTI_ClassHash &CGiraffe::getClassHash() { // MD5(Giraffe): 427DEBB81D265A0EDD8789F30B11BEB6 - static const RTTI_ClassHash s_sClassHash = { 0x42, 0x7D, 0xEB, 0xB8, 0x1D, 0x26, 0x5A, 0xE, 0xDD, 0x87, 0x89, 0xF3, 0xB, 0x11, 0xBE, 0xB6, }; + static const RTTI_ClassHash s_sClassHash = { 0x42, 0x7D, 0xEB, 0xB8, 0x1D, 0x26, 0x5A, 0x0E, 0xDD, 0x87, 0x89, 0xF3, 0x0B, 0x11, 0xBE, 0xB6, }; return s_sClassHash; } @@ -589,7 +589,7 @@ class CZoo : public CBase { const RTTI_ClassHash &CTiger::getClassHash() { // MD5(Tiger): 454C9843110686BF6F67CE5115B66617 - static const RTTI_ClassHash s_sClassHash = { 0x45, 0x4C, 0x98, 0x43, 0x11, 0x6, 0x86, 0xBF, 0x6F, 0x67, 0xCE, 0x51, 0x15, 0xB6, 0x66, 0x17, }; + static const RTTI_ClassHash s_sClassHash = { 0x45, 0x4C, 0x98, 0x43, 0x11, 0x06, 0x86, 0xBF, 0x6F, 0x67, 0xCE, 0x51, 0x15, 0xB6, 0x66, 0x17, }; return s_sClassHash; } @@ -602,7 +602,7 @@ class CZoo : public CBase { const RTTI_ClassHash &CSnake::getClassHash() { // MD5(Snake): DFA90F1B4EB3AFFBD3B46AF34ED2477C - static const RTTI_ClassHash s_sClassHash = { 0xDF, 0xA9, 0xF, 0x1B, 0x4E, 0xB3, 0xAF, 0xFB, 0xD3, 0xB4, 0x6A, 0xF3, 0x4E, 0xD2, 0x47, 0x7C, }; + static const RTTI_ClassHash s_sClassHash = { 0xDF, 0xA9, 0x0F, 0x1B, 0x4E, 0xB3, 0xAF, 0xFB, 0xD3, 0xB4, 0x6A, 0xF3, 0x4E, 0xD2, 0x47, 0x7C, }; return s_sClassHash; } @@ -615,7 +615,7 @@ class CZoo : public CBase { const RTTI_ClassHash &CTurtle::getClassHash() { // MD5(Turtle): 06DEBA5908B007EB6F32D8D95F3F61B5 - static const RTTI_ClassHash s_sClassHash = { 0x6, 0xDE, 0xBA, 0x59, 0x8, 0xB0, 0x7, 0xEB, 0x6F, 0x32, 0xD8, 0xD9, 0x5F, 0x3F, 0x61, 0xB5, }; + static const RTTI_ClassHash s_sClassHash = { 0x06, 0xDE, 0xBA, 0x59, 0x08, 0xB0, 0x07, 0xEB, 0x6F, 0x32, 0xD8, 0xD9, 0x5F, 0x3F, 0x61, 0xB5, }; return s_sClassHash; } diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp index 3660c64a..341e46ee 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp @@ -439,46 +439,82 @@ RTTIResult rtti_getsymbollookupmethod(RTTI_pvoid * pSymbolLookupMethod) RTTIResult rtti_implementsinterface(RTTI_Base pObject, RTTI_uint64 nClassHashBufferSize, const RTTI_uint8 * pClassHashBuffer, bool * pImplementsInterface) { + if (nClassHashBufferSize != 16) // Hash length must be as expected + return RTTI_ERROR_INVALIDPARAM; + IBase* pIBaseClassInstance = (IBase *)pObject; - if (strcmp(pClassName, "Base") == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - if (strcmp(pClassName, "Animal") == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - if (strcmp(pClassName, "Mammal") == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - if (strcmp(pClassName, "Reptile") == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - if (strcmp(pClassName, "Giraffe") == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - if (strcmp(pClassName, "Tiger") == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - if (strcmp(pClassName, "Snake") == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - if (strcmp(pClassName, "Turtle") == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - if (strcmp(pClassName, "AnimalIterator") == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - if (strcmp(pClassName, "Zoo") == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; + + switch(pClassHashBuffer[0]) { + case 0x06: + static const RTTI_uint8 s_TurtleHash[] = { 0x06, 0xDE, 0xBA, 0x59, 0x08, 0xB0, 0x07, 0xEB, 0x6F, 0x32, 0xD8, 0xD9, 0x5F, 0x3F, 0x61, 0xB5, }; + if (memcmp(pClassHashBuffer, s_TurtleHash, 16) == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + break; + case 0x09: + static const RTTI_uint8 s_BaseHash[] = { 0x09, 0x5A, 0x1B, 0x43, 0xEF, 0xFE, 0xC7, 0x39, 0x55, 0xE3, 0x1E, 0x79, 0x04, 0x38, 0xDE, 0x49, }; + if (memcmp(pClassHashBuffer, s_BaseHash, 16) == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + break; + case 0x16: + static const RTTI_uint8 s_AnimalHash[] = { 0x16, 0x1E, 0x7C, 0xE7, 0xBF, 0xDC, 0x89, 0xAB, 0x4B, 0x9F, 0x52, 0xC1, 0xD4, 0xC9, 0x42, 0x12, }; + if (memcmp(pClassHashBuffer, s_AnimalHash, 16) == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + break; + case 0x37: + static const RTTI_uint8 s_MammalHash[] = { 0x37, 0x42, 0x61, 0x13, 0xD1, 0x29, 0xE7, 0x9F, 0x54, 0x8F, 0x4C, 0x90, 0x93, 0x0F, 0xA6, 0x97, }; + if (memcmp(pClassHashBuffer, s_MammalHash, 16) == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + break; + case 0x42: + static const RTTI_uint8 s_GiraffeHash[] = { 0x42, 0x7D, 0xEB, 0xB8, 0x1D, 0x26, 0x5A, 0x0E, 0xDD, 0x87, 0x89, 0xF3, 0x0B, 0x11, 0xBE, 0xB6, }; + if (memcmp(pClassHashBuffer, s_GiraffeHash, 16) == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + break; + case 0x45: + static const RTTI_uint8 s_TigerHash[] = { 0x45, 0x4C, 0x98, 0x43, 0x11, 0x06, 0x86, 0xBF, 0x6F, 0x67, 0xCE, 0x51, 0x15, 0xB6, 0x66, 0x17, }; + if (memcmp(pClassHashBuffer, s_TigerHash, 16) == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + break; + case 0xAA: + static const RTTI_uint8 s_ReptileHash[] = { 0xAA, 0x64, 0x51, 0x86, 0xA4, 0xB5, 0xF3, 0xF2, 0x79, 0x52, 0xC2, 0xFA, 0x54, 0x85, 0xFA, 0xB2, }; + if (memcmp(pClassHashBuffer, s_ReptileHash, 16) == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + break; + case 0xBF: + static const RTTI_uint8 s_ZooHash[] = { 0xBF, 0xA8, 0x88, 0xA3, 0x54, 0xDB, 0x97, 0xC7, 0xCB, 0xEF, 0xB9, 0xD0, 0x50, 0xB9, 0x4C, 0xA3, }; + if (memcmp(pClassHashBuffer, s_ZooHash, 16) == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + break; + case 0xC2: + static const RTTI_uint8 s_AnimalIteratorHash[] = { 0xC2, 0xB3, 0x6A, 0x84, 0xC6, 0xC0, 0x32, 0x20, 0x4E, 0x5C, 0x92, 0x3C, 0x58, 0x10, 0x71, 0xE7, }; + if (memcmp(pClassHashBuffer, s_AnimalIteratorHash, 16) == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + break; + case 0xDF: + static const RTTI_uint8 s_SnakeHash[] = { 0xDF, 0xA9, 0x0F, 0x1B, 0x4E, 0xB3, 0xAF, 0xFB, 0xD3, 0xB4, 0x6A, 0xF3, 0x4E, 0xD2, 0x47, 0x7C, }; + if (memcmp(pClassHashBuffer, s_SnakeHash, 16) == 0) { + *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; + return RTTI_SUCCESS; + } + break; } return RTTI_ERROR_INVALIDPARAM; } diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index ddb9fb7d..64bbce45 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -1416,18 +1416,16 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln(" }") w.Writeln("") - classHash := md5.New() - classHash.Write([]byte(class.ClassName)) - classHashBytes := classHash.Sum(nil) + classHash := class.classHash() w.Writeln(" const %s_ClassHash &C%s::getClassHash()", NameSpace, class.ClassName) w.Writeln(" {") - w.Writeln(" // MD5(%s): %X", class.ClassName, classHashBytes) + w.Writeln(" // MD5(%s): %X", class.ClassName, classHash) w.BeginLine() w.Printf(" static const %s_ClassHash s_sClassHash = {", NameSpace) - for j := 0; j < len(classHashBytes); j++ { - w.Printf(" 0x%X,", classHashBytes[j]) + for j := 0; j < len(classHash); j++ { + w.Printf(" 0x%02X,", classHash[j]) } w.Printf(" };") w.EndLine() diff --git a/Source/buildimplementationcpp.go b/Source/buildimplementationcpp.go index 62dc080b..706e8773 100644 --- a/Source/buildimplementationcpp.go +++ b/Source/buildimplementationcpp.go @@ -35,10 +35,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package main import ( + "crypto/md5" + "errors" "fmt" "log" - "errors" "path" + "sort" "strings" ) @@ -707,6 +709,14 @@ func writeCImplementsInterfaceMethod(component ComponentDefinition, method Compo CMethodName := fmt.Sprintf("%s_%s", strings.ToLower(NameSpace), strings.ToLower(method.MethodName)) + classHashMap := make(map[string][]ComponentDefinitionClass) + + for i := 0; i < len(component.Classes); i++ { + class := component.Classes[i] + key := fmt.Sprintf("%02X", class.classHash()[0]) + classHashMap[key] = append(classHashMap[key], class) + } + w.Writeln("") w.Writeln("/*************************************************************************************************************************") w.Writeln(" %s", method.MethodDescription) @@ -715,14 +725,41 @@ func writeCImplementsInterfaceMethod(component ComponentDefinition, method Compo w.Writeln("%sResult %s(%s)", NameSpace, CMethodName, cparameters) w.Writeln("{") + w.Writeln(" if (nClassHashBufferSize != %d) // Hash length must be as expected", md5.Size) + w.Writeln(" return RTTI_ERROR_INVALIDPARAM;") + w.Writeln("") w.Writeln(" %s* pIBaseClassInstance = (%s *)pObject;", IBaseClassName, IBaseClassName) - for i := 0; i < len(component.Classes); i++ { - class := component.Classes[i] - w.Writeln(" if (strcmp(pClassName, \"%s\") == 0) {", class.ClassName) - w.Writeln(" *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr;", class.ClassName) - w.Writeln(" return %s_SUCCESS;", strings.ToUpper(NameSpace)) - w.Writeln(" }") + w.Writeln("") + w.Writeln(" switch(pClassHashBuffer[0]) {") + + keys := make([]string, 0, len(classHashMap)) + for key := range classHashMap { + keys = append(keys, key) + } + sort.Strings(keys) + + for i := range keys { + w.Writeln(" case 0x%s:", keys[i]) + classes := classHashMap[keys[i]] + for j := range classes { + class := classes[j] + hash := class.classHash() + w.BeginLine() + w.Printf(" static const RTTI_uint8 s_%sHash[] = {", class.ClassName) + for j := 0; j < len(hash); j++ { + w.Printf(" 0x%02X,", hash[j]) + } + w.Printf(" };") + w.EndLine() + + w.Writeln(" if (memcmp(pClassHashBuffer, s_%sHash, 16) == 0) {", class.ClassName) + w.Writeln(" *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr;", class.ClassName) + w.Writeln(" return RTTI_SUCCESS;") + w.Writeln(" }") + } + w.Writeln(" break;") } + w.Writeln(" }") w.Writeln(" return %s_ERROR_INVALIDPARAM;", strings.ToUpper(NameSpace)) w.Writeln("}") w.Writeln("") diff --git a/Source/componentdefinition.go b/Source/componentdefinition.go index 18932433..5e7740f2 100644 --- a/Source/componentdefinition.go +++ b/Source/componentdefinition.go @@ -34,17 +34,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package main import ( - "strconv" - "fmt" - "errors" + "crypto/md5" "encoding/xml" - "regexp" - "strings" + "errors" + "fmt" + "io/ioutil" "log" "math" "os" - "io/ioutil" "path/filepath" + "regexp" + "strconv" + "strings" ) const ( @@ -513,8 +514,10 @@ func (component *ComponentDefinition) checkClasses() (error) { classLowerNameList := make(map[string]bool, 0) classNameIndex := make(map[string]int, 0) + classHashIndex := make(map[string]int, 0) for i := 0; i < len(classes); i++ { class := classes[i]; + hashString := fmt.Sprintf("%X", class.classHash()); if !nameIsValidIdentifier(class.ClassName) { return fmt.Errorf ("invalid class name \"%s\"", class.ClassName); } @@ -524,10 +527,15 @@ func (component *ComponentDefinition) checkClasses() (error) { if len(class.ClassDescription) > 0 && !descriptionIsValid(class.ClassDescription) { return fmt.Errorf ("invalid class description \"%s\" in class \"%s\"", class.ClassDescription, class.ClassName); } + collision, hashExists := classHashIndex[hashString] + if hashExists { + return fmt.Errorf ("hash collision for classes \"%s\" and \"%s\"", classes[collision].ClassName, class.ClassName); + } classLowerNameList[strings.ToLower(class.ClassName)] = true (*classNameList)[class.ClassName] = true classNameIndex[class.ClassName] = i + classHashIndex[hashString] = i } // Check parent class definitions @@ -1386,3 +1394,8 @@ func (component *ComponentDefinition) countMaxOutParameters() (uint32) { return maxOutParameters; } +func (class *ComponentDefinitionClass) classHash() []byte { + hash := md5.New() + hash.Write([]byte(class.ClassName)) + return hash.Sum(nil) +} From d378681afe9603f235a10c1ca1cde7ed4f075fff Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Mon, 12 Apr 2021 13:44:56 +0200 Subject: [PATCH 023/143] Hash class ids in Python bindings --- .../RTTI_component/Bindings/Python/RTTI.py | 42 ++++++++++++++++++- Source/buildbindingpython.go | 16 ++++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py index c9eb16db..db3d6e2b 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py +++ b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py @@ -331,9 +331,13 @@ class Base: def ClassName(): return "Base" + @staticmethod + def ClassHash(): + return bytearray(b'\x09\x5A\x1B\x43\xEF\xFE\xC7\x39\x55\xE3\x1E\x79\x04\x38\xDE\x49') + @classmethod def cast(cls, instance): - if instance and instance._wrapper.ImplementsInterface(instance, cls.ClassName()): + if instance and instance._wrapper.ImplementsInterface(instance, cls.ClassHash()): instance._wrapper.AcquireInstance(instance) return cls(instance._handle, instance._wrapper) return None @@ -355,6 +359,10 @@ class Animal(Base): def ClassName(): return "Animal" + @staticmethod + def ClassHash(): + return bytearray(b'\x16\x1E\x7C\xE7\xBF\xDC\x89\xAB\x4B\x9F\x52\xC1\xD4\xC9\x42\x12') + def __init__(self, handle, wrapper): Base.__init__(self, handle, wrapper) def Name(self): @@ -377,6 +385,10 @@ class Mammal(Animal): def ClassName(): return "Mammal" + @staticmethod + def ClassHash(): + return bytearray(b'\x37\x42\x61\x13\xD1\x29\xE7\x9F\x54\x8F\x4C\x90\x93\x0F\xA6\x97') + def __init__(self, handle, wrapper): Animal.__init__(self, handle, wrapper) @@ -388,6 +400,10 @@ class Reptile(Animal): def ClassName(): return "Reptile" + @staticmethod + def ClassHash(): + return bytearray(b'\xAA\x64\x51\x86\xA4\xB5\xF3\xF2\x79\x52\xC2\xFA\x54\x85\xFA\xB2') + def __init__(self, handle, wrapper): Animal.__init__(self, handle, wrapper) @@ -399,6 +415,10 @@ class Giraffe(Mammal): def ClassName(): return "Giraffe" + @staticmethod + def ClassHash(): + return bytearray(b'\x42\x7D\xEB\xB8\x1D\x26\x5A\x0E\xDD\x87\x89\xF3\x0B\x11\xBE\xB6') + def __init__(self, handle, wrapper): Mammal.__init__(self, handle, wrapper) @@ -410,6 +430,10 @@ class Tiger(Mammal): def ClassName(): return "Tiger" + @staticmethod + def ClassHash(): + return bytearray(b'\x45\x4C\x98\x43\x11\x06\x86\xBF\x6F\x67\xCE\x51\x15\xB6\x66\x17') + def __init__(self, handle, wrapper): Mammal.__init__(self, handle, wrapper) def Roar(self): @@ -425,6 +449,10 @@ class Snake(Reptile): def ClassName(): return "Snake" + @staticmethod + def ClassHash(): + return bytearray(b'\xDF\xA9\x0F\x1B\x4E\xB3\xAF\xFB\xD3\xB4\x6A\xF3\x4E\xD2\x47\x7C') + def __init__(self, handle, wrapper): Reptile.__init__(self, handle, wrapper) @@ -436,6 +464,10 @@ class Turtle(Reptile): def ClassName(): return "Turtle" + @staticmethod + def ClassHash(): + return bytearray(b'\x06\xDE\xBA\x59\x08\xB0\x07\xEB\x6F\x32\xD8\xD9\x5F\x3F\x61\xB5') + def __init__(self, handle, wrapper): Reptile.__init__(self, handle, wrapper) @@ -447,6 +479,10 @@ class AnimalIterator(Base): def ClassName(): return "AnimalIterator" + @staticmethod + def ClassHash(): + return bytearray(b'\xC2\xB3\x6A\x84\xC6\xC0\x32\x20\x4E\x5C\x92\x3C\x58\x10\x71\xE7') + def __init__(self, handle, wrapper): Base.__init__(self, handle, wrapper) def GetNextAnimal(self): @@ -468,6 +504,10 @@ class Zoo(Base): def ClassName(): return "Zoo" + @staticmethod + def ClassHash(): + return bytearray(b'\xBF\xA8\x88\xA3\x54\xDB\x97\xC7\xCB\xEF\xB9\xD0\x50\xB9\x4C\xA3') + def __init__(self, handle, wrapper): Base.__init__(self, handle, wrapper) def Iterator(self): diff --git a/Source/buildbindingpython.go b/Source/buildbindingpython.go index 37820fb1..11b40cf8 100644 --- a/Source/buildbindingpython.go +++ b/Source/buildbindingpython.go @@ -730,6 +730,12 @@ func writePythonClass(component ComponentDefinition, class ComponentDefinitionCl w.Writeln("'''") parentClass := "" + hash := class.classHash() + hashString := "" + for i := range hash { + hashString = hashString + fmt.Sprintf("\\x%02X", hash[i]) + } + if (!component.isBaseClass(class)) { if (class.ParentClass != "") { parentClass = fmt.Sprintf("%s", class.ParentClass) @@ -741,6 +747,10 @@ func writePythonClass(component ComponentDefinition, class ComponentDefinitionCl w.Writeln(" def ClassName():") w.Writeln(" return \"%s\"", class.ClassName) w.Writeln(" ") + w.Writeln(" @staticmethod") + w.Writeln(" def ClassHash():") + w.Writeln(" return bytearray(b'%s')", hashString) + w.Writeln(" ") w.Writeln(" def __init__(self, handle, wrapper):") w.Writeln(" %s.__init__(self, handle, wrapper)", parentClass) @@ -750,10 +760,14 @@ func writePythonClass(component ComponentDefinition, class ComponentDefinitionCl w.Writeln(" def ClassName():") w.Writeln(" return \"%s\"", class.ClassName) w.Writeln(" ") + w.Writeln(" @staticmethod") + w.Writeln(" def ClassHash():") + w.Writeln(" return bytearray(b'%s')", hashString) + w.Writeln(" ") w.Writeln(" @classmethod") w.Writeln(" def cast(cls, instance):") - w.Writeln(" if instance and instance._wrapper.%s(instance, cls.ClassName()):", global.ImplementsInterfaceMethod) + w.Writeln(" if instance and instance._wrapper.%s(instance, cls.ClassHash()):", global.ImplementsInterfaceMethod) w.Writeln(" instance._wrapper.%s(instance)", global.AcquireMethod) w.Writeln(" return cls(instance._handle, instance._wrapper)") w.Writeln(" return None") From 8b6129f53e7fe4dfcb39f828663a07b6c60276c1 Mon Sep 17 00:00:00 2001 From: Feisal Ahmad Date: Tue, 23 Feb 2021 15:34:55 +0100 Subject: [PATCH 024/143] #148 Hack to fix compilation failure --- Source/buildimplementationcpp.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/buildimplementationcpp.go b/Source/buildimplementationcpp.go index 706e8773..5ecae520 100644 --- a/Source/buildimplementationcpp.go +++ b/Source/buildimplementationcpp.go @@ -972,6 +972,9 @@ func buildOutCacheTemplateParameters (method ComponentDefinitionMethod, NameSpac } cppParamType := getCppParamType(param, NameSpace, true); + if param.ParamType == "class" || param.ParamType == "optionalclass" { + cppParamType = "IBase*"; + } result += cppParamType; } From 15e2fcb53974c99145f9ec7740eff98b6bb83f82 Mon Sep 17 00:00:00 2001 From: Nathan Woodward Date: Mon, 19 Apr 2021 10:31:44 +0100 Subject: [PATCH 025/143] Fix initialisation order warning --- Source/buildbindingccpp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index 87b025d6..717eed8e 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -1201,7 +1201,7 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln(" * Exception Constructor.") w.Writeln(" */") w.Writeln(" E%sException(%sResult errorCode, const std::string & sErrorMessage)", NameSpace, NameSpace) - w.Writeln(" : m_originalErrorMessage(sErrorMessage), m_errorCode(errorCode)") + w.Writeln(" : m_errorCode(errorCode), m_originalErrorMessage(sErrorMessage)") w.Writeln(" {") w.Writeln(" m_errorMessage = buildErrorMessage();") w.Writeln(" }") From a34cb4a22649e54255f3b41f8ff895dca6cbe065 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov Date: Tue, 5 Oct 2021 18:05:12 -0700 Subject: [PATCH 026/143] Use correct namespace --- Source/buildimplementationcpp.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/buildimplementationcpp.go b/Source/buildimplementationcpp.go index 5ecae520..842fb2e0 100644 --- a/Source/buildimplementationcpp.go +++ b/Source/buildimplementationcpp.go @@ -726,7 +726,7 @@ func writeCImplementsInterfaceMethod(component ComponentDefinition, method Compo w.Writeln("%sResult %s(%s)", NameSpace, CMethodName, cparameters) w.Writeln("{") w.Writeln(" if (nClassHashBufferSize != %d) // Hash length must be as expected", md5.Size) - w.Writeln(" return RTTI_ERROR_INVALIDPARAM;") + w.Writeln(" return %s_ERROR_INVALIDPARAM;", strings.ToUpper(NameSpace)) w.Writeln("") w.Writeln(" %s* pIBaseClassInstance = (%s *)pObject;", IBaseClassName, IBaseClassName) w.Writeln("") @@ -745,7 +745,7 @@ func writeCImplementsInterfaceMethod(component ComponentDefinition, method Compo class := classes[j] hash := class.classHash() w.BeginLine() - w.Printf(" static const RTTI_uint8 s_%sHash[] = {", class.ClassName) + w.Printf(" static const %s_uint8 s_%sHash[] = {", NameSpace, class.ClassName) for j := 0; j < len(hash); j++ { w.Printf(" 0x%02X,", hash[j]) } @@ -754,7 +754,7 @@ func writeCImplementsInterfaceMethod(component ComponentDefinition, method Compo w.Writeln(" if (memcmp(pClassHashBuffer, s_%sHash, 16) == 0) {", class.ClassName) w.Writeln(" *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr;", class.ClassName) - w.Writeln(" return RTTI_SUCCESS;") + w.Writeln(" return %s_SUCCESS;", strings.ToUpper(NameSpace)) w.Writeln(" }") } w.Writeln(" break;") From 470a690e03582dce39788ae424df5801955ec6bf Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov Date: Wed, 6 Oct 2021 12:32:56 -0700 Subject: [PATCH 027/143] Revert "#148 Hack to fix compilation failure" This reverts commit 8b6129f53e7fe4dfcb39f828663a07b6c60276c1. --- Source/buildimplementationcpp.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/Source/buildimplementationcpp.go b/Source/buildimplementationcpp.go index 842fb2e0..16b3f908 100644 --- a/Source/buildimplementationcpp.go +++ b/Source/buildimplementationcpp.go @@ -972,9 +972,6 @@ func buildOutCacheTemplateParameters (method ComponentDefinitionMethod, NameSpac } cppParamType := getCppParamType(param, NameSpace, true); - if param.ParamType == "class" || param.ParamType == "optionalclass" { - cppParamType = "IBase*"; - } result += cppParamType; } From 554c6d3ea0bd512965fdf95567f1cfab46776a2a Mon Sep 17 00:00:00 2001 From: Martin Weismann <30837766+martinweismann@users.noreply.github.com> Date: Wed, 6 Oct 2021 10:48:32 +0200 Subject: [PATCH 028/143] Fix string cache comp. error (#148) --- Source/buildimplementationcpp.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Source/buildimplementationcpp.go b/Source/buildimplementationcpp.go index 16b3f908..18974909 100644 --- a/Source/buildimplementationcpp.go +++ b/Source/buildimplementationcpp.go @@ -960,7 +960,7 @@ func buildCPPInterfaceWrapper(component ComponentDefinition, w LanguageWriter, N } -func buildOutCacheTemplateParameters (method ComponentDefinitionMethod, NameSpace string) (string, error) { +func buildOutCacheTemplateParameters (method ComponentDefinitionMethod, NameSpace string, BaseClassName string, ClassIdentifier string) (string, error) { result := ""; for i := 0; i < len (method.Params); i++ { @@ -972,6 +972,9 @@ func buildOutCacheTemplateParameters (method ComponentDefinitionMethod, NameSpac } cppParamType := getCppParamType(param, NameSpace, true); + if param.ParamType == "class" || param.ParamType == "optionalclass" { + cppParamType = fmt.Sprintf("I%s%s*", ClassIdentifier, BaseClassName) + } result += cppParamType; } @@ -1061,7 +1064,7 @@ func writeCImplementationMethod(component ComponentDefinition, method ComponentD return errors.New ("String out parameter without being the string out base class."); } - templateParameters, err := buildOutCacheTemplateParameters (method, NameSpace); + templateParameters, err := buildOutCacheTemplateParameters (method, NameSpace, BaseClassName, ClassIdentifier); if err != nil { return err } From 3292f4d44a0c9af48ac05af9c845054ff4a6eded Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov Date: Wed, 6 Oct 2021 16:34:34 -0700 Subject: [PATCH 029/143] Export GO environment variables properly Make GOARCH, GOOS and GOARM environment visible to `go` compiler --- Build/build.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Build/build.sh b/Build/build.sh index 4eb00d75..0add0e20 100755 --- a/Build/build.sh +++ b/Build/build.sh @@ -10,24 +10,24 @@ basepath="$(cd "$(dirname "$0")" && pwd)" cd "$basepath/../Source" Sources="actutils.go automaticcomponenttoolkit.go buildbindingccpp.go buildbindingcsharp.go buildbindinggo.go buildbindingnode.go buildbindingpascal.go buildbindingpython.go buildbindingjava.go buildimplementationcpp.go buildimplementationpascal.go componentdefinition.go componentdiff.go languagewriter.go languagec.go languagecpp.go languagepascal.go" -GOARCH="amd64" +export GOARCH="amd64" echo "Build act.exe" -GOOS="windows" +export GOOS="windows" go build -o ../act.exe $Sources || failed "Error compiling act.exe" echo "Build act.linux" -GOOS="linux" +export GOOS="linux" go build -o ../act.linux $Sources || failed "Error compiling act.linux" echo "Build act.darwin" -GOOS="darwin" +export GOOS="darwin" go build -o ../act.darwin $Sources || failed "Error compiling act.darwin" echo "Build act.arm.linux" || failed "Error compiling act.arm.linux" -GOOS="linux" -GOARCH="arm" -GOARM="5" +export GOOS="linux" +export GOARCH="arm" +export GOARM="5" go build -o ../act.arm.linux $Sources cd "$startingpath" From aeba8e494a132aba7f707b7b54f8d35560c39dba Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov Date: Wed, 6 Oct 2021 21:22:33 -0700 Subject: [PATCH 030/143] Update RTTI example --- .../Bindings/CppDynamic/rtti_dynamic.hpp | 62 ++++++++++++++++--- .../Bindings/CppDynamic/rtti_types.hpp | 16 ++--- .../Examples/CppDynamic/RTTI_example.cpp | 13 +++- .../Cpp/Interfaces/rtti_types.hpp | 16 ++--- 4 files changed, 81 insertions(+), 26 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp index 9606ce35..fa4c61c4 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp @@ -141,15 +141,16 @@ class ERTTIException : public std::exception { * Error message for the Exception. */ std::string m_errorMessage; + std::string m_originalErrorMessage; public: /** * Exception Constructor. */ ERTTIException(RTTIResult errorCode, const std::string & sErrorMessage) - : m_errorMessage("RTTI Error " + std::to_string(errorCode) + " (" + sErrorMessage + ")") + : m_errorCode(errorCode), m_originalErrorMessage(sErrorMessage) { - m_errorCode = errorCode; + m_errorMessage = buildErrorMessage(); } /** @@ -168,6 +169,53 @@ class ERTTIException : public std::exception { return m_errorMessage.c_str(); } + const char* getErrorMessage() const noexcept + { + return m_originalErrorMessage.c_str(); + } + + const char* getErrorName() const noexcept + { + switch(getErrorCode()) { + case RTTI_SUCCESS: return "SUCCESS"; + case RTTI_ERROR_NOTIMPLEMENTED: return "NOTIMPLEMENTED"; + case RTTI_ERROR_INVALIDPARAM: return "INVALIDPARAM"; + case RTTI_ERROR_INVALIDCAST: return "INVALIDCAST"; + case RTTI_ERROR_BUFFERTOOSMALL: return "BUFFERTOOSMALL"; + case RTTI_ERROR_GENERICEXCEPTION: return "GENERICEXCEPTION"; + case RTTI_ERROR_COULDNOTLOADLIBRARY: return "COULDNOTLOADLIBRARY"; + case RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT: return "COULDNOTFINDLIBRARYEXPORT"; + case RTTI_ERROR_INCOMPATIBLEBINARYVERSION: return "INCOMPATIBLEBINARYVERSION"; + } + return "UNKNOWN"; + } + + const char* getErrorDescription() const noexcept + { + switch(getErrorCode()) { + case RTTI_SUCCESS: return "success"; + case RTTI_ERROR_NOTIMPLEMENTED: return "functionality not implemented"; + case RTTI_ERROR_INVALIDPARAM: return "an invalid parameter was passed"; + case RTTI_ERROR_INVALIDCAST: return "a type cast failed"; + case RTTI_ERROR_BUFFERTOOSMALL: return "a provided buffer is too small"; + case RTTI_ERROR_GENERICEXCEPTION: return "a generic exception occurred"; + case RTTI_ERROR_COULDNOTLOADLIBRARY: return "the library could not be loaded"; + case RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT: return "a required exported symbol could not be found in the library"; + case RTTI_ERROR_INCOMPATIBLEBINARYVERSION: return "the version of the binary interface does not match the bindings interface"; + } + return "unknown error"; + } + +private: + + std::string buildErrorMessage() const noexcept + { + std::string msg = m_originalErrorMessage; + if (msg.empty()) { + msg = getErrorDescription(); + } + return std::string("Error: ") + getErrorName() + ": " + msg; + } }; /************************************************************************************************************************* @@ -182,7 +230,7 @@ class CInputVector { public: - CInputVector( const std::vector& vec) + explicit CInputVector( const std::vector& vec) : m_data( vec.data() ), m_size( vec.size() ) { } @@ -214,7 +262,7 @@ using CRTTIInputVector = CInputVector; class CWrapper { public: - CWrapper(void* pSymbolLookupMethod) + explicit CWrapper(void* pSymbolLookupMethod) { CheckError(nullptr, initWrapperTable(&m_WrapperTable)); CheckError(nullptr, loadWrapperTableFromSymbolLookupMethod(&m_WrapperTable, pSymbolLookupMethod)); @@ -222,7 +270,7 @@ class CWrapper { CheckError(nullptr, checkBinaryVersion()); } - CWrapper(const std::string &sFileName) + explicit CWrapper(const std::string &sFileName) { CheckError(nullptr, initWrapperTable(&m_WrapperTable)); CheckError(nullptr, loadWrapperTable(&m_WrapperTable, sFileName.c_str())); @@ -263,7 +311,7 @@ class CWrapper { { RTTI_uint32 nMajor, nMinor, nMicro; GetVersion(nMajor, nMinor, nMicro); - if ( (nMajor != RTTI_VERSION_MAJOR) || (nMinor < RTTI_VERSION_MINOR) ) { + if (nMajor != RTTI_VERSION_MAJOR) { return RTTI_ERROR_INCOMPATIBLEBINARYVERSION; } return RTTI_SUCCESS; @@ -836,7 +884,7 @@ class CZoo : public CBase { #ifdef _WIN32 // Convert filename to UTF16-string - int nLength = (int)strlen(pLibraryFileName); + int nLength = static_cast(strnlen_s(pLibraryFileName, MAX_PATH)); int nBufferSize = nLength * 2 + 2; std::vector wsLibraryFileName(nBufferSize); int nResult = MultiByteToWideChar(CP_UTF8, 0, pLibraryFileName, nLength, &wsLibraryFileName[0], nBufferSize); diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_types.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_types.hpp index 19fec9a2..ef137b36 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_types.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_types.hpp @@ -73,14 +73,14 @@ typedef void * RTTI_pvoid; **************************************************************************************************************************/ #define RTTI_SUCCESS 0 -#define RTTI_ERROR_NOTIMPLEMENTED 1 -#define RTTI_ERROR_INVALIDPARAM 2 -#define RTTI_ERROR_INVALIDCAST 3 -#define RTTI_ERROR_BUFFERTOOSMALL 4 -#define RTTI_ERROR_GENERICEXCEPTION 5 -#define RTTI_ERROR_COULDNOTLOADLIBRARY 6 -#define RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT 7 -#define RTTI_ERROR_INCOMPATIBLEBINARYVERSION 8 +#define RTTI_ERROR_NOTIMPLEMENTED 1 /** functionality not implemented */ +#define RTTI_ERROR_INVALIDPARAM 2 /** an invalid parameter was passed */ +#define RTTI_ERROR_INVALIDCAST 3 /** a type cast failed */ +#define RTTI_ERROR_BUFFERTOOSMALL 4 /** a provided buffer is too small */ +#define RTTI_ERROR_GENERICEXCEPTION 5 /** a generic exception occurred */ +#define RTTI_ERROR_COULDNOTLOADLIBRARY 6 /** the library could not be loaded */ +#define RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT 7 /** a required exported symbol could not be found in the library */ +#define RTTI_ERROR_INCOMPATIBLEBINARYVERSION 8 /** the version of the binary interface does not match the bindings interface */ /************************************************************************************************************************* Error strings for RTTI diff --git a/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp b/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp index d5079a34..e40ee936 100644 --- a/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp +++ b/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp @@ -21,14 +21,21 @@ int main() { try { - std::string libpath = (""); // TODO: put the location of the RTTI-library file here. - auto wrapper = RTTI::CWrapper::loadLibrary(libpath + "/rtti."); // TODO: add correct suffix of the library + std::string libpath = ("."); // TODO: put the location of the RTTI-library file here. + auto wrapper = RTTI::CWrapper::loadLibrary(libpath + "/rtti." +#if defined _WIN32 + "dll" +#elif defined __APPLE__ + "dylib" +#elif defined __linux__ + "so" +#endif + ); // TODO: add correct suffix of the library RTTI_uint32 nMajor, nMinor, nMicro; wrapper->GetVersion(nMajor, nMinor, nMicro); std::cout << "RTTI.Version = " << nMajor << "." << nMinor << "." << nMicro; std::cout << std::endl; - auto zoo = wrapper->CreateZoo(); auto iter = zoo->Iterator(); diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_types.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_types.hpp index 19fec9a2..ef137b36 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_types.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_types.hpp @@ -73,14 +73,14 @@ typedef void * RTTI_pvoid; **************************************************************************************************************************/ #define RTTI_SUCCESS 0 -#define RTTI_ERROR_NOTIMPLEMENTED 1 -#define RTTI_ERROR_INVALIDPARAM 2 -#define RTTI_ERROR_INVALIDCAST 3 -#define RTTI_ERROR_BUFFERTOOSMALL 4 -#define RTTI_ERROR_GENERICEXCEPTION 5 -#define RTTI_ERROR_COULDNOTLOADLIBRARY 6 -#define RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT 7 -#define RTTI_ERROR_INCOMPATIBLEBINARYVERSION 8 +#define RTTI_ERROR_NOTIMPLEMENTED 1 /** functionality not implemented */ +#define RTTI_ERROR_INVALIDPARAM 2 /** an invalid parameter was passed */ +#define RTTI_ERROR_INVALIDCAST 3 /** a type cast failed */ +#define RTTI_ERROR_BUFFERTOOSMALL 4 /** a provided buffer is too small */ +#define RTTI_ERROR_GENERICEXCEPTION 5 /** a generic exception occurred */ +#define RTTI_ERROR_COULDNOTLOADLIBRARY 6 /** the library could not be loaded */ +#define RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT 7 /** a required exported symbol could not be found in the library */ +#define RTTI_ERROR_INCOMPATIBLEBINARYVERSION 8 /** the version of the binary interface does not match the bindings interface */ /************************************************************************************************************************* Error strings for RTTI From e674359c92db234b0f07b43a90441f3df1bcb77d Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov Date: Mon, 18 Oct 2021 15:22:02 -0700 Subject: [PATCH 031/143] Fix compilation error --- Source/buildbindingpascal.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/buildbindingpascal.go b/Source/buildbindingpascal.go index e510dca1..216a2dfb 100644 --- a/Source/buildbindingpascal.go +++ b/Source/buildbindingpascal.go @@ -675,8 +675,10 @@ func buildDynamicPascalImplementation(component ComponentDefinition, w LanguageW implementationLines = append(implementationLines, fmt.Sprintf(" ANameSpaceFound := True;")) implementationLines = append(implementationLines, fmt.Sprintf("end;")) } - implementationLines = append(implementationLines, fmt.Sprintf("if not ANameSpaceFound then")) - implementationLines = append(implementationLines, fmt.Sprintf(" raise E%sException.Create(%s_ERROR_COULDNOTLOADLIBRARY, 'Unknown namespace ' + %s);", NameSpace, strings.ToUpper(NameSpace), sParamName)) + if len(component.ImportedComponentDefinitions) > 0 { + implementationLines = append(implementationLines, fmt.Sprintf("if not ANameSpaceFound then")) + implementationLines = append(implementationLines, fmt.Sprintf(" raise E%sException.Create(%s_ERROR_COULDNOTLOADLIBRARY, 'Unknown namespace ' + %s);", NameSpace, strings.ToUpper(NameSpace), sParamName)) + } } err = writePascalClassMethodImplementation(method, w, NameSpace, "Wrapper", definitionLines, implementationLines, true) From 3cd19ac2063bc06c1d023a060fc7be75b8b9bb34 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov Date: Mon, 18 Oct 2021 16:26:42 -0700 Subject: [PATCH 032/143] Add ClassTypeId an PolymorphicFactory C++, Python and Pascal bindings and implementations --- Source/buildbindingccpp.go | 82 +++++--------------- Source/buildbindingpascal.go | 27 ++++++- Source/buildbindingpython.go | 54 ++++++-------- Source/buildimplementationcpp.go | 112 +++++++--------------------- Source/buildimplementationpascal.go | 51 ++++++++++--- Source/componentdefinition.go | 82 ++++++++++++-------- 6 files changed, 185 insertions(+), 223 deletions(-) diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index 717eed8e..91dc21ff 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -36,7 +36,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package main import ( - "crypto/md5" "fmt" "log" "path" @@ -698,7 +697,7 @@ func writeDynamicCPPMethod(method ComponentDefinitionMethod, w LanguageWriter, N if (param.ParamType == "optionalclass") { postCallCodeLines = append(postCallCodeLines, fmt.Sprintf("if (h%s) {", param.ParamName)) - postCallCodeLines = append(postCallCodeLines, fmt.Sprintf(" p%s = std::make_shared<%s%s%s>(%s, h%s);", param.ParamName, cppClassPrefix, ClassIdentifier, param.ParamClass, makeSharedParameter, param.ParamName)) + postCallCodeLines = append(postCallCodeLines, fmt.Sprintf(" p%s = %s->polymorphicFactory<%s%s%s>(h%s);", param.ParamName, makeSharedParameter, cppClassPrefix, ClassIdentifier, param.ParamClass, param.ParamName)) postCallCodeLines = append(postCallCodeLines, fmt.Sprintf("} else {")) postCallCodeLines = append(postCallCodeLines, fmt.Sprintf(" p%s = nullptr;", param.ParamName)) postCallCodeLines = append(postCallCodeLines, fmt.Sprintf("}")) @@ -706,7 +705,7 @@ func writeDynamicCPPMethod(method ComponentDefinitionMethod, w LanguageWriter, N postCallCodeLines = append(postCallCodeLines, fmt.Sprintf("if (!h%s) {", param.ParamName)) postCallCodeLines = append(postCallCodeLines, fmt.Sprintf(" %s%s_ERROR_INVALIDPARAM%s;", checkErrorCodeBegin, strings.ToUpper(NameSpace), checkErrorCodeEnd)) postCallCodeLines = append(postCallCodeLines, fmt.Sprintf("} else {")) - postCallCodeLines = append(postCallCodeLines, fmt.Sprintf(" p%s = std::make_shared<%s%s%s>(%s, h%s);", param.ParamName, cppClassPrefix, ClassIdentifier, param.ParamClass, makeSharedParameter, param.ParamName)) + postCallCodeLines = append(postCallCodeLines, fmt.Sprintf(" p%s = %s->polymorphicFactory<%s%s%s>(h%s);", param.ParamName, makeSharedParameter, cppClassPrefix, ClassIdentifier, param.ParamClass, param.ParamName)) postCallCodeLines = append(postCallCodeLines, fmt.Sprintf("}")) } @@ -776,7 +775,7 @@ func writeDynamicCPPMethod(method ComponentDefinitionMethod, w LanguageWriter, N if (param.ParamType == "optionalclass") { returnCodeLines = append(returnCodeLines, fmt.Sprintf("if (h%s) {", param.ParamName)) - returnCodeLines = append(returnCodeLines, fmt.Sprintf(" return std::make_shared<%s>(%s, h%s);", CPPClass, makeSharedParameter, param.ParamName)) + returnCodeLines = append(returnCodeLines, fmt.Sprintf(" return %s->polymorphicFactory<%s>(h%s);", makeSharedParameter, CPPClass, param.ParamName)) returnCodeLines = append(returnCodeLines, fmt.Sprintf("} else {")) returnCodeLines = append(returnCodeLines, fmt.Sprintf(" return nullptr;")) returnCodeLines = append(returnCodeLines, fmt.Sprintf("}")) @@ -784,7 +783,7 @@ func writeDynamicCPPMethod(method ComponentDefinitionMethod, w LanguageWriter, N returnCodeLines = append(returnCodeLines, fmt.Sprintf("if (!h%s) {", param.ParamName)) returnCodeLines = append(returnCodeLines, fmt.Sprintf(" %s%s_ERROR_INVALIDPARAM%s;", checkErrorCodeBegin, strings.ToUpper(NameSpace), checkErrorCodeEnd)) returnCodeLines = append(returnCodeLines, fmt.Sprintf("}")) - returnCodeLines = append(returnCodeLines, fmt.Sprintf("return std::make_shared<%s>(%s, h%s);", CPPClass, makeSharedParameter, param.ParamName)) + returnCodeLines = append(returnCodeLines, fmt.Sprintf("return %s->polymorphicFactory<%s>(h%s);", makeSharedParameter, CPPClass, param.ParamName)) } case "basicarray": @@ -1143,15 +1142,6 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s buildBindingCPPAllForwardDeclarations(component, w, NameSpace, cppClassPrefix, ClassIdentifier) - - w.Writeln("/*************************************************************************************************************************") - w.Writeln(" %s_cast Definition", strings.ToLower(NameSpace)) - w.Writeln("**************************************************************************************************************************/") - w.Writeln("template ") - w.Writeln("inline std::shared_ptr %s_cast(PBase obj);", strings.ToLower(NameSpace)) - w.Writeln("") - w.Writeln("using %s_ClassHash = std::array<%s_uint8, %d>;", NameSpace, NameSpace, md5.Size) - w.Writeln("") w.Writeln("/*************************************************************************************************************************") w.Writeln(" classParam Definition") @@ -1381,6 +1371,10 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln(" %sResult loadWrapperTable(s%sDynamicWrapperTable * pWrapperTable, const char * pLibraryFileName);", NameSpace, NameSpace) w.Writeln(" %sResult loadWrapperTableFromSymbolLookupMethod(s%sDynamicWrapperTable * pWrapperTable, void* pSymbolLookupMethod);", NameSpace, NameSpace) } + w.Writeln("") + w.Writeln(" template") + w.Writeln(" std::shared_ptr polymorphicFactory(%sHandle);", NameSpace) + w.Writeln("") for i := 0; i < len(component.Classes); i++ { @@ -1414,8 +1408,6 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln("**************************************************************************************************************************/") w.Writeln("class %s %s{", cppClassName, inheritanceSpecifier) w.Writeln("public:") - w.Writeln(" static inline const std::string &getClassName();") - w.Writeln(" static inline const %s_ClassHash &getClassHash();", NameSpace) w.Writeln(" ") if !component.isBaseClass(class) { w.Writeln(" /**") @@ -1447,61 +1439,25 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln("") w.Writeln("/*************************************************************************************************************************") - w.Writeln(" RTTI static getClassName implementations") + w.Writeln(" RTTI: Polymorphic Factory implementation") w.Writeln("**************************************************************************************************************************/") w.Writeln("") + w.Writeln("template ") + w.Writeln("std::shared_ptr %s%sWrapper::polymorphicFactory(%sHandle pHandle)", cppClassPrefix, ClassIdentifier, strings.ToUpper(NameSpace)) + w.Writeln("{") + w.Writeln(" %s_uint64 resultClassTypeId = 0;", strings.ToUpper(NameSpace)) + w.Writeln(" CheckError(nullptr, m_WrapperTable.m_Base_ClassTypeId(pHandle, &resultClassTypeId));") + w.Writeln(" switch(resultClassTypeId) {") for i := 0; i < len(component.Classes); i++ { class := component.Classes[i] - w.Writeln(" const std::string &C%s::getClassName()", class.ClassName) - w.Writeln(" {") - w.Writeln(" static const std::string s_sClassName = \"%s\";", class.ClassName) - w.Writeln(" return s_sClassName;") - w.Writeln(" }") - w.Writeln("") - - classHash := class.classHash() - - w.Writeln(" const %s_ClassHash &C%s::getClassHash()", NameSpace, class.ClassName) - w.Writeln(" {") - w.Writeln(" // MD5(%s): %X", class.ClassName, classHash) - - w.BeginLine() - w.Printf(" static const %s_ClassHash s_sClassHash = {", NameSpace) - for j := 0; j < len(classHash); j++ { - w.Printf(" 0x%02X,", classHash[j]) - } - w.Printf(" };") - w.EndLine() - w.Writeln(" return s_sClassHash;") - w.Writeln(" }") - w.Writeln("") + classTypeId, chashHashString := class.classTypeId(NameSpace) + w.Writeln(" case 0x%016XUL: return std::dynamic_pointer_cast(std::make_shared(this, pHandle)); break; // First 64 bits of SHA1 of a string: \"%s\"", classTypeId, class.ClassName, chashHashString) } - - w.Writeln("") - w.Writeln("/*************************************************************************************************************************") - w.Writeln(" RTTI cast implementation") - w.Writeln("**************************************************************************************************************************/") - w.Writeln("") - - w.Writeln(" template ") - w.Writeln(" std::shared_ptr %s_cast(PBase pObj)", strings.ToLower(NameSpace)) - w.Writeln(" {") - w.Writeln(" static_assert(std::is_convertible::value, \"T must be convertible to %s::CBase\");", NameSpace) - w.Writeln("") - w.Writeln(" if (pObj) {") - w.Writeln(" CWrapper *pWrapper = pObj->wrapper();") - w.Writeln(" const %s_ClassHash & ClassHash = T::getClassHash();", NameSpace) - w.Writeln(" CInputVector<%s_uint8> ClassHashBuffer(ClassHash.data(), ClassHash.size());", NameSpace) - w.Writeln(" if (pWrapper->%s(pObj.get(), ClassHashBuffer)) {", global.ImplementsInterfaceMethod) - w.Writeln(" pWrapper->%s(pObj);", global.AcquireMethod) - w.Writeln(" return std::make_shared(pWrapper, pObj->handle());") - w.Writeln(" }") - w.Writeln(" }") - w.Writeln("") - w.Writeln(" return nullptr;") w.Writeln(" }") + w.Writeln(" return std::make_shared(this, pHandle);") + w.Writeln("}") for j := 0; j < len(global.Methods); j++ { method := global.Methods[j] diff --git a/Source/buildbindingpascal.go b/Source/buildbindingpascal.go index 216a2dfb..68b3ab63 100644 --- a/Source/buildbindingpascal.go +++ b/Source/buildbindingpascal.go @@ -413,11 +413,36 @@ func buildDynamicPascalImplementation(component ComponentDefinition, w LanguageW writeEnumConversionInterface(component, w, NameSpace) + w.Writeln(" TPolymorphicFactory<_T:class; _B> = record") + w.Writeln(" class function Make(Wrapper: T%sWrapper; Handle: T%sHandle): _T; static;", strings.ToUpper(NameSpace), strings.ToUpper(NameSpace)) + w.Writeln(" end;") + w.Writeln("") w.Writeln("implementation") w.Writeln("") writeEnumConversionImplementation(component, w, NameSpace) + w.Writeln("") + w.Writeln("(*************************************************************************************************************************") + w.Writeln(" PolymorficFactory implementation") + w.Writeln("**************************************************************************************************************************)") + w.Writeln("") + + w.Writeln(" class function TPolymorphicFactory<_T, _B>.Make(Wrapper: T%sWrapper; Handle: T%sHandle): _T;", strings.ToUpper(NameSpace), strings.ToUpper(NameSpace)) + w.Writeln(" var") + w.Writeln(" ClassTypeId: QWord;") + w.Writeln(" Obj: TRTTIBase;") + w.Writeln(" begin") + w.Writeln(" Result := nil;") + w.Writeln(" Wrapper.CheckError(nil, Wrapper.%sBase_ClassTypeIdFunc(handle, ClassTypeId));", strings.ToUpper(NameSpace)) + w.Writeln(" case (ClassTypeId) of") + for i := 0; i < len(component.Classes); i++ { + classTypeId, chashHashString := component.Classes[i].classTypeId(NameSpace) + w.Writeln(" $%016X: begin Obj := T%s%s.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: \"%s\"", classTypeId, strings.ToUpper(NameSpace), component.Classes[i].ClassName, chashHashString) + } + w.Writeln(" end;") + w.Writeln(" if Result = nil then Result := _B.Create(Wrapper, Handle);") + w.Writeln(" end;") w.Writeln("") w.Writeln("(*************************************************************************************************************************") @@ -1032,7 +1057,7 @@ func writePascalClassMethodImplementation(method ComponentDefinitionMethod, w La initCommands = append(initCommands, "H"+param.ParamName+" := nil;") callFunctionParameters = callFunctionParameters + "H" + param.ParamName resultCommands = append(resultCommands, fmt.Sprintf(" if Assigned(H%s) then", param.ParamName)) - resultCommands = append(resultCommands, fmt.Sprintf(" Result := T%s%s.Create(%s, H%s);", theNameSpace, theParamClass, theWrapperInstance, param.ParamName)) + resultCommands = append(resultCommands, fmt.Sprintf(" Result := TPolymorphicFactory.Make(%s, H%s);", theNameSpace, theParamClass, theNameSpace, theParamClass, theWrapperInstance, param.ParamName)) default: return fmt.Errorf("invalid method parameter type \"%s\" for %s.%s (%s)", param.ParamType, ClassName, method.MethodName, param.ParamName) diff --git a/Source/buildbindingpython.go b/Source/buildbindingpython.go index 11b40cf8..10737f7b 100644 --- a/Source/buildbindingpython.go +++ b/Source/buildbindingpython.go @@ -365,6 +365,24 @@ func buildDynamicPythonImplementation(componentdefinition ComponentDefinition, w } } + w.Writeln(" def _polymorphicFactory(self, handle):") + w.Writeln(" class PolymorphicFactory():") + w.Writeln(" def getObjectById(self, classtypeid, handle, wrapper):") + w.Writeln(" methodName = 'getObjectById_' + format(classtypeid.value, '016X')") + w.Writeln(" method = getattr(self, methodName, lambda: 'Invalid class type id')") + w.Writeln(" return method(handle, wrapper)") + for i:=0; i 0 { theWrapperReference = theWrapperReference + "._" + subNameSpace + "Wrapper" subNameSpace = subNameSpace + "." } postCallLines = append(postCallLines, fmt.Sprintf("if %sHandle:", param.ParamName)) postCallLines = append(postCallLines, - fmt.Sprintf(" %sObject = %s%s(%sHandle, %s)", - param.ParamName, subNameSpace, paramClassName, param.ParamName, theWrapperReference)) + fmt.Sprintf(" %sObject = %s._polymorphicFactory(%sHandle)", + param.ParamName, wrapperReference, param.ParamName)) postCallLines = append(postCallLines, fmt.Sprintf("else:")) if (param.ParamType == "optionalclass") { postCallLines = append(postCallLines, fmt.Sprintf(" %sObject = None", param.ParamName)) diff --git a/Source/buildimplementationcpp.go b/Source/buildimplementationcpp.go index 18974909..33198a22 100644 --- a/Source/buildimplementationcpp.go +++ b/Source/buildimplementationcpp.go @@ -35,12 +35,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package main import ( - "crypto/md5" "errors" "fmt" "log" "path" - "sort" "strings" ) @@ -416,6 +414,29 @@ func writeCPPClassInterface(component ComponentDefinition, class ComponentDefini w.Writeln("") } + if (component.isBaseClass(class)) { + methodstring, _, err := buildCPPInterfaceMethodDeclaration(component.classTypeIdMethod(), class.ClassName, NameSpace, ClassIdentifier, BaseName, w.IndentString, false, true, true) + if err != nil { + return err + } + // Only IBase class has pure virtual ClassTypeId method. It's needed for proper interpretation of "override" in deriver interface classes. + w.Writeln("%s;", methodstring) + + } else { + methodstring, _, err := buildCPPInterfaceMethodDeclaration(component.classTypeIdMethod(), class.ClassName, NameSpace, ClassIdentifier, BaseName, w.IndentString, false, false, true) + if err != nil { + return err + } + classTypeId, chashHashString := class.classTypeId(NameSpace) + w.Writeln("%s", methodstring) + w.Writeln(" {") + w.Writeln(" // First 64 bits of SHA1 of a string: \"%s\"", chashHashString) + w.Writeln(" static const %s_uint64 s_%sTypeId = 0x%XUL;", strings.ToUpper(NameSpace), class.ClassName, classTypeId) + w.Writeln(" return s_%sTypeId;", class.ClassName) + w.Writeln(" }") + w.Writeln("") + } + for j := 0; j < len(class.Methods); j++ { method := class.Methods[j] methodstring, _, err := buildCPPInterfaceMethodDeclaration(method, class.ClassName, NameSpace, ClassIdentifier, BaseName, w.IndentString, false, true, true) @@ -568,7 +589,7 @@ func buildCPPInterfaces(component ComponentDefinition, w LanguageWriter, NameSpa return err } if (isSpecialFunction == eSpecialMethodJournal) || (isSpecialFunction == eSpecialMethodInjection) || - (isSpecialFunction == eSpecialMethodSymbolLookup) || (isSpecialFunction == eSpecialMethodImplementsInterface ) { + (isSpecialFunction == eSpecialMethodSymbolLookup) { continue } @@ -626,7 +647,7 @@ func buildCPPGlobalStubFile(component ComponentDefinition, stubfile LanguageWrit return err } if (isSpecialFunction == eSpecialMethodJournal) || (isSpecialFunction == eSpecialMethodInjection) || - (isSpecialFunction == eSpecialMethodSymbolLookup) || (isSpecialFunction == eSpecialMethodImplementsInterface) { + (isSpecialFunction == eSpecialMethodSymbolLookup) { continue } if (isSpecialFunction == eSpecialMethodVersion) { @@ -693,80 +714,6 @@ func buildCPPInterfaceWrapperMethods(component ComponentDefinition, class Compon return nil } -func writeCImplementsInterfaceMethod(component ComponentDefinition, method ComponentDefinitionMethod, w LanguageWriter, NameSpace string, IBaseClassName string) error { - cParams, err := GenerateCParameters(method, "", NameSpace) - if err != nil { - return err - } - - cparameters := "" - for _, cParam := range cParams { - if cparameters != "" { - cparameters = cparameters + ", " - } - cparameters = cparameters + cParam.ParamType + " " + cParam.ParamName - } - - CMethodName := fmt.Sprintf("%s_%s", strings.ToLower(NameSpace), strings.ToLower(method.MethodName)) - - classHashMap := make(map[string][]ComponentDefinitionClass) - - for i := 0; i < len(component.Classes); i++ { - class := component.Classes[i] - key := fmt.Sprintf("%02X", class.classHash()[0]) - classHashMap[key] = append(classHashMap[key], class) - } - - w.Writeln("") - w.Writeln("/*************************************************************************************************************************") - w.Writeln(" %s", method.MethodDescription) - w.Writeln("**************************************************************************************************************************/") - w.Writeln("") - - w.Writeln("%sResult %s(%s)", NameSpace, CMethodName, cparameters) - w.Writeln("{") - w.Writeln(" if (nClassHashBufferSize != %d) // Hash length must be as expected", md5.Size) - w.Writeln(" return %s_ERROR_INVALIDPARAM;", strings.ToUpper(NameSpace)) - w.Writeln("") - w.Writeln(" %s* pIBaseClassInstance = (%s *)pObject;", IBaseClassName, IBaseClassName) - w.Writeln("") - w.Writeln(" switch(pClassHashBuffer[0]) {") - - keys := make([]string, 0, len(classHashMap)) - for key := range classHashMap { - keys = append(keys, key) - } - sort.Strings(keys) - - for i := range keys { - w.Writeln(" case 0x%s:", keys[i]) - classes := classHashMap[keys[i]] - for j := range classes { - class := classes[j] - hash := class.classHash() - w.BeginLine() - w.Printf(" static const %s_uint8 s_%sHash[] = {", NameSpace, class.ClassName) - for j := 0; j < len(hash); j++ { - w.Printf(" 0x%02X,", hash[j]) - } - w.Printf(" };") - w.EndLine() - - w.Writeln(" if (memcmp(pClassHashBuffer, s_%sHash, 16) == 0) {", class.ClassName) - w.Writeln(" *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr;", class.ClassName) - w.Writeln(" return %s_SUCCESS;", strings.ToUpper(NameSpace)) - w.Writeln(" }") - } - w.Writeln(" break;") - } - w.Writeln(" }") - w.Writeln(" return %s_ERROR_INVALIDPARAM;", strings.ToUpper(NameSpace)) - w.Writeln("}") - w.Writeln("") - - return nil -} - func buildCPPGetSymbolAddressMethod(component ComponentDefinition, w LanguageWriter, NameSpace string, NameSpaceImplementation string) error { w.Writeln("") @@ -938,15 +885,6 @@ func buildCPPInterfaceWrapper(component ComponentDefinition, w LanguageWriter, N doMethodJournal = false; } - if (isSpecialFunction == eSpecialMethodImplementsInterface) { - err = writeCImplementsInterfaceMethod(component, method, w, NameSpace, IBaseClassName) - if err != nil { - return err - } - continue - } - - // Write Static function implementation err = writeCImplementationMethod(component, method, w, BaseName, NameSpace, NameSpaceImplementation, ClassIdentifier, "Wrapper", component.Global.BaseClassName, true, doMethodJournal, isSpecialFunction, false) if err != nil { diff --git a/Source/buildimplementationpascal.go b/Source/buildimplementationpascal.go index 8e55f8ff..d1bd5b08 100644 --- a/Source/buildimplementationpascal.go +++ b/Source/buildimplementationpascal.go @@ -410,7 +410,7 @@ func buildPascalInterfaceDefinition(component ComponentDefinition, w LanguageWri methods[4] = DecRefCountMethod() for _, method := range methods { - err := writePascalImplClassMethodDefinition(method, w, NameSpace, class.ClassName, false) + err := writePascalImplClassMethodDefinition(method, w, NameSpace, class.ClassName, false, false, false, false) if err != nil { return err } @@ -419,7 +419,7 @@ func buildPascalInterfaceDefinition(component ComponentDefinition, w LanguageWri for j := 0; j < len(class.Methods); j++ { method := class.Methods[j] - err := writePascalImplClassMethodDefinition(method, w, NameSpace, class.ClassName, false) + err := writePascalImplClassMethodDefinition(method, w, NameSpace, class.ClassName, false, false, false, false) if err != nil { return err } @@ -1410,16 +1410,22 @@ func buildPascalStub(component ComponentDefinition, NameSpace string, ClassIdent w.AddIndentationLevel(3) if component.isBaseClass(class) { for _, method := range baseClassMethods { - err := writePascalImplClassMethodDefinition(method, w, NameSpace, class.ClassName, false) + err := writePascalImplClassMethodDefinition(method, w, NameSpace, class.ClassName, false, false, false, false) if err != nil { return err } } + } else { + err := writePascalImplClassMethodDefinition(component.classTypeIdMethod(), w, NameSpace, class.ClassName, false, true, false, false) + if err != nil { + return err + } } for j := 0; j < len(class.Methods); j++ { method := class.Methods[j] - err := writePascalImplClassMethodDefinition(method, w, NameSpace, class.ClassName, false) + isClassTypeIdMethod := method.MethodName == component.Global.ClassTypeIdMethod + err := writePascalImplClassMethodDefinition(method, w, NameSpace, class.ClassName, false, false, isClassTypeIdMethod, isClassTypeIdMethod && component.isBaseClass(class)) if err != nil { return err } @@ -1455,10 +1461,25 @@ func buildPascalStub(component ComponentDefinition, NameSpace string, ClassIdent return err } } + } else { + outClassName := fmt.Sprintf("T%s%s", NameSpace, class.ClassName) + classTypeId, chashHashString := class.classTypeId(NameSpace) + + var methodImplementation []string + methodImplementation = append(methodImplementation, fmt.Sprintf("Result := $%016X; // First 64 bits of SHA1 of a string: \"%s\"", classTypeId, chashHashString)) + + err := writePascalClassMethodDummyStub(component.classTypeIdMethod(), w, NameSpace, class.ClassName, outClassName, false, methodImplementation) + if err != nil { + return err + } } for j := 0; j < len(class.Methods); j++ { method := class.Methods[j] + if method.MethodName == component.Global.ClassTypeIdMethod { + // Skip. This method was implemented above. + continue + } err := writePascalClassMethodDummyStub(method, w, NameSpace, class.ClassName, outClassName, false, defaultImplementation) if err != nil { return err @@ -1471,7 +1492,7 @@ func buildPascalStub(component ComponentDefinition, NameSpace string, ClassIdent return nil } -func writePascalImplClassMethodDefinition(method ComponentDefinitionMethod, w LanguageWriter, NameSpace string, ClassName string, isGlobal bool) error { +func writePascalImplClassMethodDefinition(method ComponentDefinitionMethod, w LanguageWriter, NameSpace string, ClassName string, isGlobal bool, isOverride bool, isVirtual bool, isAbstract bool) error { parameters, returnType, err := getPascalImplClassParameters(method, NameSpace, ClassName, isGlobal, true) if err != nil { @@ -1482,12 +1503,24 @@ func writePascalImplClassMethodDefinition(method ComponentDefinitionMethod, w La if isGlobal { classPrefix = "class " } - + str := ""; if returnType == "" { - w.Writeln("%sprocedure %s(%s);", classPrefix, method.MethodName, parameters) + str = fmt.Sprintf("%sprocedure %s(%s);", classPrefix, method.MethodName, parameters) } else { - w.Writeln("%sfunction %s(%s): %s;", classPrefix, method.MethodName, parameters, returnType) + str = fmt.Sprintf("%sfunction %s(%s): %s;", classPrefix, method.MethodName, parameters, returnType) } + if isOverride { + str = str + " Override;"; + } else { + if isVirtual { + str = str + " Virtual;"; + } + if isAbstract { + str = str + " Abstract;"; + } + } + + w.Writeln(str); return nil } @@ -1546,7 +1579,7 @@ func buildStubImplementation(component ComponentDefinition, w LanguageWriter, Na (isSpecialFunction == eSpecialMethodSymbolLookup) { continue } - err = writePascalImplClassMethodDefinition(method, w, NameSpace, "Wrapper", true) + err = writePascalImplClassMethodDefinition(method, w, NameSpace, "Wrapper", true, false, false, false) if err != nil { return err } diff --git a/Source/componentdefinition.go b/Source/componentdefinition.go index 6d354fd7..bf1e9c75 100644 --- a/Source/componentdefinition.go +++ b/Source/componentdefinition.go @@ -34,7 +34,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package main import ( - "crypto/md5" + "crypto/sha1" + "encoding/binary" "encoding/xml" "errors" "fmt" @@ -59,7 +60,6 @@ const ( eSpecialMethodJournal = 7 eSpecialMethodPrerelease = 8 eSpecialMethodBuildinfo = 9 - eSpecialMethodImplementsInterface = 10 ) // ComponentDefinitionParam definition of a method parameter used in the component's API @@ -120,7 +120,7 @@ type ComponentDefinitionGlobal struct { BaseClassName string `xml:"baseclassname,attr"` StringOutBaseClassName string `xml:"stringoutclassname,attr"` ErrorMethod string `xml:"errormethod,attr"` - ImplementsInterfaceMethod string `xml:"implementsinterfacemethod,attr"` + ClassTypeIdMethod string `xml:"classtypeidmethod,attr"` ReleaseMethod string `xml:"releasemethod,attr"` AcquireMethod string `xml:"acquiremethod,attr"` SymbolLookupMethod string `xml:"symbollookupmethod,attr"` @@ -516,10 +516,10 @@ func (component *ComponentDefinition) checkClasses() (error) { classLowerNameList := make(map[string]bool, 0) classNameIndex := make(map[string]int, 0) - classHashIndex := make(map[string]int, 0) + classTypeIdIndex := make(map[uint64]int, 0) for i := 0; i < len(classes); i++ { class := classes[i]; - hashString := fmt.Sprintf("%X", class.classHash()); + classTypeHash, _ := class.classTypeId(component.NameSpace); if !nameIsValidIdentifier(class.ClassName) { return fmt.Errorf ("invalid class name \"%s\"", class.ClassName); } @@ -529,15 +529,15 @@ func (component *ComponentDefinition) checkClasses() (error) { if len(class.ClassDescription) > 0 && !descriptionIsValid(class.ClassDescription) { return fmt.Errorf ("invalid class description \"%s\" in class \"%s\"", class.ClassDescription, class.ClassName); } - collision, hashExists := classHashIndex[hashString] + collision, hashExists := classTypeIdIndex[classTypeHash] if hashExists { - return fmt.Errorf ("hash collision for classes \"%s\" and \"%s\"", classes[collision].ClassName, class.ClassName); + return fmt.Errorf ("Classes \"%s\" and \"%s\" have a collision in their Class Type Id. Change class name.", classes[collision].ClassName, class.ClassName); } classLowerNameList[strings.ToLower(class.ClassName)] = true (*classNameList)[class.ClassName] = true classNameIndex[class.ClassName] = i - classHashIndex[hashString] = i + classTypeIdIndex[classTypeHash] = i } // Check parent class definitions @@ -714,6 +714,21 @@ func (component *ComponentDefinition) checkMethod(method ComponentDefinitionMeth } +func (component *ComponentDefinition) checkBaseClassMethods() (error) { + + method := component.classTypeIdMethod() + if method.MethodName == "" { + return fmt.Errorf ("ClassTypeId method is not defined in Base class"); + } + + if (method.MethodName == component.Global.ClassTypeIdMethod) { + if (len (method.Params) != 1) || (method.Params[0].ParamType != "uint64") || (method.Params[0].ParamPass != "return") { + return fmt.Errorf ("ClassTypeId method does not match the expected function template"); + } + } + return nil +} + func (component *ComponentDefinition) checkClassMethods() (error) { classes := component.Classes @@ -723,7 +738,9 @@ func (component *ComponentDefinition) checkClassMethods() (error) { methodNameList := make(map[string]bool, 0) for j := 0; j < len(class.Methods); j++ { method := class.Methods[j] - + if (!component.isBaseClass(class) && (method.MethodName == component.Global.ClassTypeIdMethod)) { + return fmt.Errorf ("class type id method \"%s\" is redefined in \"%s\".%s\"", method.MethodName, class.ClassName) + } if (methodNameList[strings.ToLower(method.MethodName)]) { return fmt.Errorf ("duplicate name for method \"%s.%s\"", class.ClassName, method.MethodName) } @@ -966,6 +983,11 @@ func (component *ComponentDefinition) CheckComponentDefinition() (error) { return err } + err = component.checkBaseClassMethods() + if err != nil { + return err + } + err = component.checkClassMethods() if err != nil { return err @@ -1028,8 +1050,8 @@ func CheckHeaderSpecialFunction (method ComponentDefinitionMethod, global Compon return eSpecialMethodNone, errors.New ("No error method specified"); } - if (global.ImplementsInterfaceMethod == "") { - return eSpecialMethodNone, errors.New ("No implements inteface method specified"); + if (global.ClassTypeIdMethod == "") { + return eSpecialMethodNone, errors.New ("No ClassTypeId method specified"); } if (global.ReleaseMethod == global.JournalMethod) { @@ -1140,21 +1162,6 @@ func CheckHeaderSpecialFunction (method ComponentDefinitionMethod, global Compon return eSpecialMethodError, nil; } - if (method.MethodName == global.ImplementsInterfaceMethod) { - if (len (method.Params) != 3) { - return eSpecialMethodNone, errors.New ("Implements Interface method does not match the expected function template"); - } - - if (method.Params[0].ParamType != "class") || (method.Params[0].ParamPass != "in") || - (method.Params[1].ParamType != "basicarray") || (method.Params[1].ParamClass != "uint8") || (method.Params[1].ParamPass != "in") || - (method.Params[2].ParamType != "bool") || (method.Params[2].ParamPass != "return") || - (method.Params[0].ParamClass != global.BaseClassName) { - return eSpecialMethodNone, errors.New ("Implements Interface method does not match the expected function template"); - } - - return eSpecialMethodImplementsInterface, nil; - } - if len(global.PrereleaseMethod)>0 && (global.PrereleaseMethod == global.BuildinfoMethod) { return eSpecialMethodNone, errors.New ("Prerelease method can not be the same as the buildinfo method"); } @@ -1396,8 +1403,23 @@ func (component *ComponentDefinition) countMaxOutParameters() (uint32) { return maxOutParameters; } -func (class *ComponentDefinitionClass) classHash() []byte { - hash := md5.New() - hash.Write([]byte(class.ClassName)) - return hash.Sum(nil) +func (component *ComponentDefinition) classTypeIdMethod() (ComponentDefinitionMethod) { + var method ComponentDefinitionMethod + baseClass := component.baseClass() + + for j := 0; j < len(baseClass.Methods); j++ { + if (baseClass.Methods[j].MethodName == component.Global.ClassTypeIdMethod) { + return baseClass.Methods[j] + break + } + } + + return method +} + +func (class *ComponentDefinitionClass) classTypeId(namespace string) (uint64, string) { + hash := sha1.New() + plainString := namespace + "::" + class.ClassName + hash.Write([]byte(plainString)) + return binary.LittleEndian.Uint64(hash.Sum(nil)), plainString } From db0262c16ee7a426e148a2ba8e915617a98b2d1c Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov Date: Mon, 18 Oct 2021 16:31:29 -0700 Subject: [PATCH 033/143] Update Python and C++ examples --- Examples/RTTI/RTTI.xml | 20 ++- .../RTTI_component/Bindings/Python/RTTI.py | 164 ++++++------------ .../Examples/CppDynamic/RTTI_example.cpp | 7 +- .../Examples/Python/RTTI_Example.py | 5 +- 4 files changed, 69 insertions(+), 127 deletions(-) diff --git a/Examples/RTTI/RTTI.xml b/Examples/RTTI/RTTI.xml index fb42fe2d..2d5bb210 100644 --- a/Examples/RTTI/RTTI.xml +++ b/Examples/RTTI/RTTI.xml @@ -10,9 +10,11 @@ + + @@ -30,6 +32,9 @@ + + + @@ -69,10 +74,12 @@ - + @@ -96,11 +103,6 @@ - - - - - diff --git a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py index db3d6e2b..fca2a1e8 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py +++ b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py @@ -62,8 +62,8 @@ class FunctionTable: rtti_acquireinstance = None rtti_injectcomponent = None rtti_getsymbollookupmethod = None - rtti_implementsinterface = None rtti_createzoo = None + rtti_base_classtypeid = None rtti_animal_name = None rtti_tiger_roar = None rtti_animaliterator_getnextanimal = None @@ -147,18 +147,18 @@ def _loadFunctionTableFromMethod(self, symbolLookupMethodAddress): methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.POINTER(ctypes.c_void_p)) self.lib.rtti_getsymbollookupmethod = methodType(int(methodAddress.value)) - err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_implementsinterface")), methodAddress) - if err != 0: - raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) - methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.c_uint64, ctypes.POINTER(ctypes.c_uint8), ctypes.POINTER(ctypes.c_bool)) - self.lib.rtti_implementsinterface = methodType(int(methodAddress.value)) - err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_createzoo")), methodAddress) if err != 0: raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.POINTER(ctypes.c_void_p)) self.lib.rtti_createzoo = methodType(int(methodAddress.value)) + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_base_classtypeid")), methodAddress) + if err != 0: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.POINTER(ctypes.c_uint64)) + self.lib.rtti_base_classtypeid = methodType(int(methodAddress.value)) + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_animal_name")), methodAddress) if err != 0: raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) @@ -206,12 +206,12 @@ def _loadFunctionTable(self): self.lib.rtti_getsymbollookupmethod.restype = ctypes.c_int32 self.lib.rtti_getsymbollookupmethod.argtypes = [ctypes.POINTER(ctypes.c_void_p)] - self.lib.rtti_implementsinterface.restype = ctypes.c_int32 - self.lib.rtti_implementsinterface.argtypes = [ctypes.c_void_p, ctypes.c_uint64, ctypes.POINTER(ctypes.c_uint8), ctypes.POINTER(ctypes.c_bool)] - self.lib.rtti_createzoo.restype = ctypes.c_int32 self.lib.rtti_createzoo.argtypes = [ctypes.POINTER(ctypes.c_void_p)] + self.lib.rtti_base_classtypeid.restype = ctypes.c_int32 + self.lib.rtti_base_classtypeid.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_uint64)] + self.lib.rtti_animal_name.restype = ctypes.c_int32 self.lib.rtti_animal_name.argtypes = [ctypes.c_void_p, ctypes.c_uint64, ctypes.POINTER(ctypes.c_uint64), ctypes.c_char_p] @@ -299,49 +299,53 @@ def GetSymbolLookupMethod(self): return pSymbolLookupMethod.value - def ImplementsInterface(self, ObjectObject, ClassHash): - ObjectHandle = None - if ObjectObject: - ObjectHandle = ObjectObject._handle - else: - raise ERTTIException(ErrorCodes.INVALIDPARAM, 'Invalid return/output value') - nClassHashCount = ctypes.c_uint64(len(ClassHash)) - pClassHashBuffer = (ctypes.c_uint8*len(ClassHash))(*ClassHash) - pImplementsInterface = ctypes.c_bool() - self.checkError(None, self.lib.rtti_implementsinterface(ObjectHandle, nClassHashCount, pClassHashBuffer, pImplementsInterface)) - - return pImplementsInterface.value - def CreateZoo(self): InstanceHandle = ctypes.c_void_p() self.checkError(None, self.lib.rtti_createzoo(InstanceHandle)) if InstanceHandle: - InstanceObject = Zoo(InstanceHandle, self) + InstanceObject = self._polymorphicFactory(InstanceHandle) else: raise ERTTIException(ErrorCodes.INVALIDCAST, 'Invalid return/output value') return InstanceObject + def _polymorphicFactory(self, handle): + class PolymorphicFactory(): + def getObjectById(self, classtypeid, handle, wrapper): + methodName = 'getObjectById_' + format(classtypeid.value, '016X') + method = getattr(self, methodName, lambda: 'Invalid class type id') + return method(handle, wrapper) + def getObjectById_1549AD28813DAE05(self, handle, wrapper): # First 64 bits of SHA1 of a string: "RTTI::Base" + return Base(handle, wrapper) + def getObjectById_8B40467DA6D327AF(self, handle, wrapper): # First 64 bits of SHA1 of a string: "RTTI::Animal" + return Animal(handle, wrapper) + def getObjectById_BC9D5FA7750C1020(self, handle, wrapper): # First 64 bits of SHA1 of a string: "RTTI::Mammal" + return Mammal(handle, wrapper) + def getObjectById_6756AA8EA5802EC3(self, handle, wrapper): # First 64 bits of SHA1 of a string: "RTTI::Reptile" + return Reptile(handle, wrapper) + def getObjectById_9751971BD2C2D958(self, handle, wrapper): # First 64 bits of SHA1 of a string: "RTTI::Giraffe" + return Giraffe(handle, wrapper) + def getObjectById_08D007E7B5F7BAF4(self, handle, wrapper): # First 64 bits of SHA1 of a string: "RTTI::Tiger" + return Tiger(handle, wrapper) + def getObjectById_5F6826EF909803B2(self, handle, wrapper): # First 64 bits of SHA1 of a string: "RTTI::Snake" + return Snake(handle, wrapper) + def getObjectById_8E551B208A2E8321(self, handle, wrapper): # First 64 bits of SHA1 of a string: "RTTI::Turtle" + return Turtle(handle, wrapper) + def getObjectById_F1917FE6BBE77831(self, handle, wrapper): # First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" + return AnimalIterator(handle, wrapper) + def getObjectById_2262ABE80A5E7878(self, handle, wrapper): # First 64 bits of SHA1 of a string: "RTTI::Zoo" + return Zoo(handle, wrapper) + + pClassTypeId = ctypes.c_uint64() + self.checkError(None, self.lib.rtti_base_classtypeid(handle, pClassTypeId)) + factory = PolymorphicFactory() + return factory.getObjectById(pClassTypeId, handle, self) + ''' Class Implementation for Base ''' class Base: - @staticmethod - def ClassName(): - return "Base" - - @staticmethod - def ClassHash(): - return bytearray(b'\x09\x5A\x1B\x43\xEF\xFE\xC7\x39\x55\xE3\x1E\x79\x04\x38\xDE\x49') - - @classmethod - def cast(cls, instance): - if instance and instance._wrapper.ImplementsInterface(instance, cls.ClassHash()): - instance._wrapper.AcquireInstance(instance) - return cls(instance._handle, instance._wrapper) - return None - def __init__(self, handle, wrapper): if not handle or not wrapper: raise ERTTIException(ErrorCodes.INVALIDPARAM) @@ -350,19 +354,17 @@ def __init__(self, handle, wrapper): def __del__(self): self._wrapper.ReleaseInstance(self) + def ClassTypeId(self): + pClassTypeId = ctypes.c_uint64() + self._wrapper.checkError(self, self._wrapper.lib.rtti_base_classtypeid(self._handle, pClassTypeId)) + + return pClassTypeId.value + ''' Class Implementation for Animal ''' class Animal(Base): - @staticmethod - def ClassName(): - return "Animal" - - @staticmethod - def ClassHash(): - return bytearray(b'\x16\x1E\x7C\xE7\xBF\xDC\x89\xAB\x4B\x9F\x52\xC1\xD4\xC9\x42\x12') - def __init__(self, handle, wrapper): Base.__init__(self, handle, wrapper) def Name(self): @@ -381,14 +383,6 @@ def Name(self): ''' Class Implementation for Mammal ''' class Mammal(Animal): - @staticmethod - def ClassName(): - return "Mammal" - - @staticmethod - def ClassHash(): - return bytearray(b'\x37\x42\x61\x13\xD1\x29\xE7\x9F\x54\x8F\x4C\x90\x93\x0F\xA6\x97') - def __init__(self, handle, wrapper): Animal.__init__(self, handle, wrapper) @@ -396,14 +390,6 @@ def __init__(self, handle, wrapper): ''' Class Implementation for Reptile ''' class Reptile(Animal): - @staticmethod - def ClassName(): - return "Reptile" - - @staticmethod - def ClassHash(): - return bytearray(b'\xAA\x64\x51\x86\xA4\xB5\xF3\xF2\x79\x52\xC2\xFA\x54\x85\xFA\xB2') - def __init__(self, handle, wrapper): Animal.__init__(self, handle, wrapper) @@ -411,14 +397,6 @@ def __init__(self, handle, wrapper): ''' Class Implementation for Giraffe ''' class Giraffe(Mammal): - @staticmethod - def ClassName(): - return "Giraffe" - - @staticmethod - def ClassHash(): - return bytearray(b'\x42\x7D\xEB\xB8\x1D\x26\x5A\x0E\xDD\x87\x89\xF3\x0B\x11\xBE\xB6') - def __init__(self, handle, wrapper): Mammal.__init__(self, handle, wrapper) @@ -426,14 +404,6 @@ def __init__(self, handle, wrapper): ''' Class Implementation for Tiger ''' class Tiger(Mammal): - @staticmethod - def ClassName(): - return "Tiger" - - @staticmethod - def ClassHash(): - return bytearray(b'\x45\x4C\x98\x43\x11\x06\x86\xBF\x6F\x67\xCE\x51\x15\xB6\x66\x17') - def __init__(self, handle, wrapper): Mammal.__init__(self, handle, wrapper) def Roar(self): @@ -445,14 +415,6 @@ def Roar(self): ''' Class Implementation for Snake ''' class Snake(Reptile): - @staticmethod - def ClassName(): - return "Snake" - - @staticmethod - def ClassHash(): - return bytearray(b'\xDF\xA9\x0F\x1B\x4E\xB3\xAF\xFB\xD3\xB4\x6A\xF3\x4E\xD2\x47\x7C') - def __init__(self, handle, wrapper): Reptile.__init__(self, handle, wrapper) @@ -460,14 +422,6 @@ def __init__(self, handle, wrapper): ''' Class Implementation for Turtle ''' class Turtle(Reptile): - @staticmethod - def ClassName(): - return "Turtle" - - @staticmethod - def ClassHash(): - return bytearray(b'\x06\xDE\xBA\x59\x08\xB0\x07\xEB\x6F\x32\xD8\xD9\x5F\x3F\x61\xB5') - def __init__(self, handle, wrapper): Reptile.__init__(self, handle, wrapper) @@ -475,21 +429,13 @@ def __init__(self, handle, wrapper): ''' Class Implementation for AnimalIterator ''' class AnimalIterator(Base): - @staticmethod - def ClassName(): - return "AnimalIterator" - - @staticmethod - def ClassHash(): - return bytearray(b'\xC2\xB3\x6A\x84\xC6\xC0\x32\x20\x4E\x5C\x92\x3C\x58\x10\x71\xE7') - def __init__(self, handle, wrapper): Base.__init__(self, handle, wrapper) def GetNextAnimal(self): AnimalHandle = ctypes.c_void_p() self._wrapper.checkError(self, self._wrapper.lib.rtti_animaliterator_getnextanimal(self._handle, AnimalHandle)) if AnimalHandle: - AnimalObject = Animal(AnimalHandle, self._wrapper) + AnimalObject = self._wrapper._polymorphicFactory(AnimalHandle) else: AnimalObject = None @@ -500,21 +446,13 @@ def GetNextAnimal(self): ''' Class Implementation for Zoo ''' class Zoo(Base): - @staticmethod - def ClassName(): - return "Zoo" - - @staticmethod - def ClassHash(): - return bytearray(b'\xBF\xA8\x88\xA3\x54\xDB\x97\xC7\xCB\xEF\xB9\xD0\x50\xB9\x4C\xA3') - def __init__(self, handle, wrapper): Base.__init__(self, handle, wrapper) def Iterator(self): IteratorHandle = ctypes.c_void_p() self._wrapper.checkError(self, self._wrapper.lib.rtti_zoo_iterator(self._handle, IteratorHandle)) if IteratorHandle: - IteratorObject = AnimalIterator(IteratorHandle, self._wrapper) + IteratorObject = self._wrapper._polymorphicFactory(IteratorHandle) else: raise ERTTIException(ErrorCodes.INVALIDCAST, 'Invalid return/output value') diff --git a/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp b/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp index e40ee936..7b244d5e 100644 --- a/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp +++ b/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp @@ -41,10 +41,11 @@ int main() using namespace RTTI; while (auto animal = iter->GetNextAnimal()) { - if (auto tiger = rtti_cast(animal)) { - tiger->Roar(); - } std::cout << "Animal name: " << animal->Name() << std::endl; + if (auto tiger = std::dynamic_pointer_cast(animal)) { + std::cout << " ^ is a real tiger!!!" << std::endl; + tiger->Roar(); + } } } catch (std::exception &e) diff --git a/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py b/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py index 984534cf..b735c184 100644 --- a/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py +++ b/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py @@ -32,8 +32,9 @@ def main(): iter = zoo.Iterator() while animal := iter.GetNextAnimal(): - if tiger := RTTI.Tiger.cast(animal): - tiger.Roar() + if isinstance(animal, RTTI.Tiger): + print(" ^ is a real tiger!!!") + animal.Roar() print("Animal name: " + animal.Name()) if __name__ == "__main__": From f9dc1a26204df5eb2c0b1cdfc66ee8bf642b7114 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov Date: Mon, 18 Oct 2021 16:44:33 -0700 Subject: [PATCH 034/143] Remove duplicated definition of ClassTypeId method in base class --- Source/buildimplementationcpp.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/buildimplementationcpp.go b/Source/buildimplementationcpp.go index 33198a22..f8d6d32a 100644 --- a/Source/buildimplementationcpp.go +++ b/Source/buildimplementationcpp.go @@ -439,6 +439,9 @@ func writeCPPClassInterface(component ComponentDefinition, class ComponentDefini for j := 0; j < len(class.Methods); j++ { method := class.Methods[j] + if method.MethodName == component.Global.ClassTypeIdMethod { + continue + } methodstring, _, err := buildCPPInterfaceMethodDeclaration(method, class.ClassName, NameSpace, ClassIdentifier, BaseName, w.IndentString, false, true, true) if err != nil { return err From ad161bb762884037af0b8042987123bfff43f644 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov Date: Mon, 18 Oct 2021 16:44:51 -0700 Subject: [PATCH 035/143] Update C++ example --- .../Bindings/CppDynamic/rtti_abi.hpp | 196 ------------- .../Bindings/CppDynamic/rtti_dynamic.h | 22 +- .../Bindings/CppDynamic/rtti_dynamic.hpp | 266 ++++-------------- .../Cpp/Interfaces/rtti_abi.hpp | 20 +- .../Cpp/Interfaces/rtti_interfaces.hpp | 104 +++++++ .../Cpp/Interfaces/rtti_interfacewrapper.cpp | 117 ++------ 6 files changed, 204 insertions(+), 521 deletions(-) delete mode 100644 Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp deleted file mode 100644 index ae254c13..00000000 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp +++ /dev/null @@ -1,196 +0,0 @@ -/*++ - -Copyright (C) 2020 ADSK - -All rights reserved. - -This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. - -Abstract: This is an autogenerated C++-Header file in order to allow an easy - use of RTTI - -Interface version: 1.0.0 - -*/ - -#ifndef __RTTI_HEADER_CPP -#define __RTTI_HEADER_CPP - -#ifdef __RTTI_EXPORTS -#ifdef _WIN32 -#define RTTI_DECLSPEC __declspec (dllexport) -#else // _WIN32 -#define RTTI_DECLSPEC __attribute__((visibility("default"))) -#endif // _WIN32 -#else // __RTTI_EXPORTS -#define RTTI_DECLSPEC -#endif // __RTTI_EXPORTS - -#include "rtti_types.hpp" - - -#ifdef __cplusplus -extern "C" { -#endif - -/************************************************************************************************************************* - Class definition for Base -**************************************************************************************************************************/ - -/************************************************************************************************************************* - Class definition for Animal -**************************************************************************************************************************/ - -/** -* Get the name of the animal -* -* @param[in] pAnimal - Animal instance. -* @param[in] nResultBufferSize - size of the buffer (including trailing 0) -* @param[out] pResultNeededChars - will be filled with the count of the written bytes, or needed buffer size. -* @param[out] pResultBuffer - buffer of , may be NULL -* @return error code or 0 (success) -*/ -RTTI_DECLSPEC RTTIResult rtti_animal_name(RTTI_Animal pAnimal, const RTTI_uint32 nResultBufferSize, RTTI_uint32* pResultNeededChars, char * pResultBuffer); - -/************************************************************************************************************************* - Class definition for Mammal -**************************************************************************************************************************/ - -/************************************************************************************************************************* - Class definition for Reptile -**************************************************************************************************************************/ - -/************************************************************************************************************************* - Class definition for Giraffe -**************************************************************************************************************************/ - -/************************************************************************************************************************* - Class definition for Tiger -**************************************************************************************************************************/ - -/** -* Roar like a tiger -* -* @param[in] pTiger - Tiger instance. -* @return error code or 0 (success) -*/ -RTTI_DECLSPEC RTTIResult rtti_tiger_roar(RTTI_Tiger pTiger); - -/************************************************************************************************************************* - Class definition for Snake -**************************************************************************************************************************/ - -/************************************************************************************************************************* - Class definition for Turtle -**************************************************************************************************************************/ - -/************************************************************************************************************************* - Class definition for AnimalIterator -**************************************************************************************************************************/ - -/** -* Return next animal -* -* @param[in] pAnimalIterator - AnimalIterator instance. -* @param[out] pAnimal - -* @return error code or 0 (success) -*/ -RTTI_DECLSPEC RTTIResult rtti_animaliterator_getnextanimal(RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal); - -/************************************************************************************************************************* - Class definition for Zoo -**************************************************************************************************************************/ - -/** -* Return an iterator over all zoo animals -* -* @param[in] pZoo - Zoo instance. -* @param[out] pIterator - -* @return error code or 0 (success) -*/ -RTTI_DECLSPEC RTTIResult rtti_zoo_iterator(RTTI_Zoo pZoo, RTTI_AnimalIterator * pIterator); - -/************************************************************************************************************************* - Global functions -**************************************************************************************************************************/ - -/** -* retrieves the binary version of this library. -* -* @param[out] pMajor - returns the major version of this library -* @param[out] pMinor - returns the minor version of this library -* @param[out] pMicro - returns the micro version of this library -* @return error code or 0 (success) -*/ -RTTI_DECLSPEC RTTIResult rtti_getversion(RTTI_uint32 * pMajor, RTTI_uint32 * pMinor, RTTI_uint32 * pMicro); - -/** -* Returns the last error recorded on this object -* -* @param[in] pInstance - Instance Handle -* @param[in] nErrorMessageBufferSize - size of the buffer (including trailing 0) -* @param[out] pErrorMessageNeededChars - will be filled with the count of the written bytes, or needed buffer size. -* @param[out] pErrorMessageBuffer - buffer of Message of the last error, may be NULL -* @param[out] pHasError - Is there a last error to query -* @return error code or 0 (success) -*/ -RTTI_DECLSPEC RTTIResult rtti_getlasterror(RTTI_Base pInstance, const RTTI_uint32 nErrorMessageBufferSize, RTTI_uint32* pErrorMessageNeededChars, char * pErrorMessageBuffer, bool * pHasError); - -/** -* Releases shared ownership of an Instance -* -* @param[in] pInstance - Instance Handle -* @return error code or 0 (success) -*/ -RTTI_DECLSPEC RTTIResult rtti_releaseinstance(RTTI_Base pInstance); - -/** -* Acquires shared ownership of an Instance -* -* @param[in] pInstance - Instance Handle -* @return error code or 0 (success) -*/ -RTTI_DECLSPEC RTTIResult rtti_acquireinstance(RTTI_Base pInstance); - -/** -* Injects an imported component for usage within this component -* -* @param[in] pNameSpace - NameSpace of the injected component -* @param[in] pSymbolAddressMethod - Address of the SymbolAddressMethod of the injected component -* @return error code or 0 (success) -*/ -RTTI_DECLSPEC RTTIResult rtti_injectcomponent(const char * pNameSpace, RTTI_pvoid pSymbolAddressMethod); - -/** -* Returns the address of the SymbolLookupMethod -* -* @param[out] pSymbolLookupMethod - Address of the SymbolAddressMethod -* @return error code or 0 (success) -*/ -RTTI_DECLSPEC RTTIResult rtti_getsymbollookupmethod(RTTI_pvoid * pSymbolLookupMethod); - -/** -* Test whether an object implements a given interface -* -* @param[in] pObject - Instance Handle -* @param[in] nClassHashBufferSize - Number of elements in buffer -* @param[in] pClassHashBuffer - uint8 buffer of Hashed class name of the interface to test -* @param[out] pImplementsInterface - Will be set to true if pInstance implements the interface, false otherwise -* @return error code or 0 (success) -*/ -RTTI_DECLSPEC RTTIResult rtti_implementsinterface(RTTI_Base pObject, RTTI_uint64 nClassHashBufferSize, const RTTI_uint8 * pClassHashBuffer, bool * pImplementsInterface); - -/** -* Create a new zoo with animals -* -* @param[out] pInstance - -* @return error code or 0 (success) -*/ -RTTI_DECLSPEC RTTIResult rtti_createzoo(RTTI_Zoo * pInstance); - -#ifdef __cplusplus -} -#endif - -#endif // __RTTI_HEADER_CPP - diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h index 859684e1..6a7c182b 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h @@ -24,6 +24,15 @@ Interface version: 1.0.0 Class definition for Base **************************************************************************************************************************/ +/** +* Get Class Type Id +* +* @param[in] pBase - Base instance. +* @param[out] pClassTypeId - Class type as a 64 bits integer +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIBase_ClassTypeIdPtr) (RTTI_Base pBase, RTTI_uint64 * pClassTypeId); + /************************************************************************************************************************* Class definition for Animal **************************************************************************************************************************/ @@ -156,17 +165,6 @@ typedef RTTIResult (*PRTTIInjectComponentPtr) (const char * pNameSpace, RTTI_pvo */ typedef RTTIResult (*PRTTIGetSymbolLookupMethodPtr) (RTTI_pvoid * pSymbolLookupMethod); -/** -* Test whether an object implements a given interface -* -* @param[in] pObject - Instance Handle -* @param[in] nClassHashBufferSize - Number of elements in buffer -* @param[in] pClassHashBuffer - uint8 buffer of Hashed class name of the interface to test -* @param[out] pImplementsInterface - Will be set to true if pInstance implements the interface, false otherwise -* @return error code or 0 (success) -*/ -typedef RTTIResult (*PRTTIImplementsInterfacePtr) (RTTI_Base pObject, RTTI_uint64 nClassHashBufferSize, const RTTI_uint8 * pClassHashBuffer, bool * pImplementsInterface); - /** * Create a new zoo with animals * @@ -181,6 +179,7 @@ typedef RTTIResult (*PRTTICreateZooPtr) (RTTI_Zoo * pInstance); typedef struct { void * m_LibraryHandle; + PRTTIBase_ClassTypeIdPtr m_Base_ClassTypeId; PRTTIAnimal_NamePtr m_Animal_Name; PRTTITiger_RoarPtr m_Tiger_Roar; PRTTIAnimalIterator_GetNextAnimalPtr m_AnimalIterator_GetNextAnimal; @@ -191,7 +190,6 @@ typedef struct { PRTTIAcquireInstancePtr m_AcquireInstance; PRTTIInjectComponentPtr m_InjectComponent; PRTTIGetSymbolLookupMethodPtr m_GetSymbolLookupMethod; - PRTTIImplementsInterfacePtr m_ImplementsInterface; PRTTICreateZooPtr m_CreateZoo; } sRTTIDynamicWrapperTable; diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp index fa4c61c4..f03b0a01 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp @@ -93,13 +93,6 @@ typedef PTurtle PRTTITurtle; typedef PAnimalIterator PRTTIAnimalIterator; typedef PZoo PRTTIZoo; -/************************************************************************************************************************* - rtti_cast Definition -**************************************************************************************************************************/ -template -inline std::shared_ptr rtti_cast(PBase obj); - -using RTTI_ClassHash = std::array; /************************************************************************************************************************* classParam Definition @@ -301,7 +294,6 @@ class CWrapper { inline void AcquireInstance(classParam pInstance); inline void InjectComponent(const std::string & sNameSpace, const RTTI_pvoid pSymbolAddressMethod); inline RTTI_pvoid GetSymbolLookupMethod(); - inline bool ImplementsInterface(classParam pObject, const CInputVector & ClassHashBuffer); inline PZoo CreateZoo(); private: @@ -321,6 +313,9 @@ class CWrapper { RTTIResult loadWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable, const char * pLibraryFileName); RTTIResult loadWrapperTableFromSymbolLookupMethod(sRTTIDynamicWrapperTable * pWrapperTable, void* pSymbolLookupMethod); + template + std::shared_ptr polymorphicFactory(RTTIHandle); + friend class CBase; friend class CAnimal; friend class CMammal; @@ -340,8 +335,6 @@ class CWrapper { **************************************************************************************************************************/ class CBase { public: - static inline const std::string &getClassName(); - static inline const RTTI_ClassHash &getClassHash(); protected: /* Wrapper Object that created the class. */ @@ -391,6 +384,7 @@ class CBase { } friend class CWrapper; + inline RTTI_uint64 ClassTypeId(); }; /************************************************************************************************************************* @@ -398,8 +392,6 @@ class CBase { **************************************************************************************************************************/ class CAnimal : public CBase { public: - static inline const std::string &getClassName(); - static inline const RTTI_ClassHash &getClassHash(); /** * CAnimal::CAnimal - Constructor for Animal class. @@ -417,8 +409,6 @@ class CAnimal : public CBase { **************************************************************************************************************************/ class CMammal : public CAnimal { public: - static inline const std::string &getClassName(); - static inline const RTTI_ClassHash &getClassHash(); /** * CMammal::CMammal - Constructor for Mammal class. @@ -435,8 +425,6 @@ class CMammal : public CAnimal { **************************************************************************************************************************/ class CReptile : public CAnimal { public: - static inline const std::string &getClassName(); - static inline const RTTI_ClassHash &getClassHash(); /** * CReptile::CReptile - Constructor for Reptile class. @@ -453,8 +441,6 @@ class CReptile : public CAnimal { **************************************************************************************************************************/ class CGiraffe : public CMammal { public: - static inline const std::string &getClassName(); - static inline const RTTI_ClassHash &getClassHash(); /** * CGiraffe::CGiraffe - Constructor for Giraffe class. @@ -471,8 +457,6 @@ class CGiraffe : public CMammal { **************************************************************************************************************************/ class CTiger : public CMammal { public: - static inline const std::string &getClassName(); - static inline const RTTI_ClassHash &getClassHash(); /** * CTiger::CTiger - Constructor for Tiger class. @@ -490,8 +474,6 @@ class CTiger : public CMammal { **************************************************************************************************************************/ class CSnake : public CReptile { public: - static inline const std::string &getClassName(); - static inline const RTTI_ClassHash &getClassHash(); /** * CSnake::CSnake - Constructor for Snake class. @@ -508,8 +490,6 @@ class CSnake : public CReptile { **************************************************************************************************************************/ class CTurtle : public CReptile { public: - static inline const std::string &getClassName(); - static inline const RTTI_ClassHash &getClassHash(); /** * CTurtle::CTurtle - Constructor for Turtle class. @@ -526,8 +506,6 @@ class CTurtle : public CReptile { **************************************************************************************************************************/ class CAnimalIterator : public CBase { public: - static inline const std::string &getClassName(); - static inline const RTTI_ClassHash &getClassHash(); /** * CAnimalIterator::CAnimalIterator - Constructor for AnimalIterator class. @@ -545,8 +523,6 @@ class CAnimalIterator : public CBase { **************************************************************************************************************************/ class CZoo : public CBase { public: - static inline const std::string &getClassName(); - static inline const RTTI_ClassHash &getClassHash(); /** * CZoo::CZoo - Constructor for Zoo class. @@ -560,161 +536,28 @@ class CZoo : public CBase { }; /************************************************************************************************************************* - RTTI static getClassName implementations + RTTI: Polymorphic Factory implementation **************************************************************************************************************************/ - const std::string &CBase::getClassName() - { - static const std::string s_sClassName = "Base"; - return s_sClassName; - } - - const RTTI_ClassHash &CBase::getClassHash() - { - // MD5(Base): 095A1B43EFFEC73955E31E790438DE49 - static const RTTI_ClassHash s_sClassHash = { 0x09, 0x5A, 0x1B, 0x43, 0xEF, 0xFE, 0xC7, 0x39, 0x55, 0xE3, 0x1E, 0x79, 0x04, 0x38, 0xDE, 0x49, }; - return s_sClassHash; - } - - const std::string &CAnimal::getClassName() - { - static const std::string s_sClassName = "Animal"; - return s_sClassName; - } - - const RTTI_ClassHash &CAnimal::getClassHash() - { - // MD5(Animal): 161E7CE7BFDC89AB4B9F52C1D4C94212 - static const RTTI_ClassHash s_sClassHash = { 0x16, 0x1E, 0x7C, 0xE7, 0xBF, 0xDC, 0x89, 0xAB, 0x4B, 0x9F, 0x52, 0xC1, 0xD4, 0xC9, 0x42, 0x12, }; - return s_sClassHash; - } - - const std::string &CMammal::getClassName() - { - static const std::string s_sClassName = "Mammal"; - return s_sClassName; - } - - const RTTI_ClassHash &CMammal::getClassHash() - { - // MD5(Mammal): 37426113D129E79F548F4C90930FA697 - static const RTTI_ClassHash s_sClassHash = { 0x37, 0x42, 0x61, 0x13, 0xD1, 0x29, 0xE7, 0x9F, 0x54, 0x8F, 0x4C, 0x90, 0x93, 0x0F, 0xA6, 0x97, }; - return s_sClassHash; - } - - const std::string &CReptile::getClassName() - { - static const std::string s_sClassName = "Reptile"; - return s_sClassName; - } - - const RTTI_ClassHash &CReptile::getClassHash() - { - // MD5(Reptile): AA645186A4B5F3F27952C2FA5485FAB2 - static const RTTI_ClassHash s_sClassHash = { 0xAA, 0x64, 0x51, 0x86, 0xA4, 0xB5, 0xF3, 0xF2, 0x79, 0x52, 0xC2, 0xFA, 0x54, 0x85, 0xFA, 0xB2, }; - return s_sClassHash; - } - - const std::string &CGiraffe::getClassName() - { - static const std::string s_sClassName = "Giraffe"; - return s_sClassName; - } - - const RTTI_ClassHash &CGiraffe::getClassHash() - { - // MD5(Giraffe): 427DEBB81D265A0EDD8789F30B11BEB6 - static const RTTI_ClassHash s_sClassHash = { 0x42, 0x7D, 0xEB, 0xB8, 0x1D, 0x26, 0x5A, 0x0E, 0xDD, 0x87, 0x89, 0xF3, 0x0B, 0x11, 0xBE, 0xB6, }; - return s_sClassHash; - } - - const std::string &CTiger::getClassName() - { - static const std::string s_sClassName = "Tiger"; - return s_sClassName; - } - - const RTTI_ClassHash &CTiger::getClassHash() - { - // MD5(Tiger): 454C9843110686BF6F67CE5115B66617 - static const RTTI_ClassHash s_sClassHash = { 0x45, 0x4C, 0x98, 0x43, 0x11, 0x06, 0x86, 0xBF, 0x6F, 0x67, 0xCE, 0x51, 0x15, 0xB6, 0x66, 0x17, }; - return s_sClassHash; - } - - const std::string &CSnake::getClassName() - { - static const std::string s_sClassName = "Snake"; - return s_sClassName; - } - - const RTTI_ClassHash &CSnake::getClassHash() - { - // MD5(Snake): DFA90F1B4EB3AFFBD3B46AF34ED2477C - static const RTTI_ClassHash s_sClassHash = { 0xDF, 0xA9, 0x0F, 0x1B, 0x4E, 0xB3, 0xAF, 0xFB, 0xD3, 0xB4, 0x6A, 0xF3, 0x4E, 0xD2, 0x47, 0x7C, }; - return s_sClassHash; - } - - const std::string &CTurtle::getClassName() - { - static const std::string s_sClassName = "Turtle"; - return s_sClassName; - } - - const RTTI_ClassHash &CTurtle::getClassHash() - { - // MD5(Turtle): 06DEBA5908B007EB6F32D8D95F3F61B5 - static const RTTI_ClassHash s_sClassHash = { 0x06, 0xDE, 0xBA, 0x59, 0x08, 0xB0, 0x07, 0xEB, 0x6F, 0x32, 0xD8, 0xD9, 0x5F, 0x3F, 0x61, 0xB5, }; - return s_sClassHash; - } - - const std::string &CAnimalIterator::getClassName() - { - static const std::string s_sClassName = "AnimalIterator"; - return s_sClassName; - } - - const RTTI_ClassHash &CAnimalIterator::getClassHash() - { - // MD5(AnimalIterator): C2B36A84C6C032204E5C923C581071E7 - static const RTTI_ClassHash s_sClassHash = { 0xC2, 0xB3, 0x6A, 0x84, 0xC6, 0xC0, 0x32, 0x20, 0x4E, 0x5C, 0x92, 0x3C, 0x58, 0x10, 0x71, 0xE7, }; - return s_sClassHash; - } - - const std::string &CZoo::getClassName() - { - static const std::string s_sClassName = "Zoo"; - return s_sClassName; - } - - const RTTI_ClassHash &CZoo::getClassHash() - { - // MD5(Zoo): BFA888A354DB97C7CBEFB9D050B94CA3 - static const RTTI_ClassHash s_sClassHash = { 0xBF, 0xA8, 0x88, 0xA3, 0x54, 0xDB, 0x97, 0xC7, 0xCB, 0xEF, 0xB9, 0xD0, 0x50, 0xB9, 0x4C, 0xA3, }; - return s_sClassHash; - } - - -/************************************************************************************************************************* - RTTI cast implementation -**************************************************************************************************************************/ - - template - std::shared_ptr rtti_cast(PBase pObj) - { - static_assert(std::is_convertible::value, "T must be convertible to RTTI::CBase"); - - if (pObj) { - CWrapper *pWrapper = pObj->wrapper(); - const RTTI_ClassHash & ClassHash = T::getClassHash(); - CInputVector ClassHashBuffer(ClassHash.data(), ClassHash.size()); - if (pWrapper->ImplementsInterface(pObj.get(), ClassHashBuffer)) { - pWrapper->AcquireInstance(pObj); - return std::make_shared(pWrapper, pObj->handle()); - } - } - - return nullptr; - } +template +std::shared_ptr CWrapper::polymorphicFactory(RTTIHandle pHandle) +{ + RTTI_uint64 resultClassTypeId = 0; + CheckError(nullptr, m_WrapperTable.m_Base_ClassTypeId(pHandle, &resultClassTypeId)); + switch(resultClassTypeId) { + case 0x1549AD28813DAE05UL: return std::dynamic_pointer_cast(std::make_shared(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Base" + case 0x8B40467DA6D327AFUL: return std::dynamic_pointer_cast(std::make_shared(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Animal" + case 0xBC9D5FA7750C1020UL: return std::dynamic_pointer_cast(std::make_shared(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Mammal" + case 0x6756AA8EA5802EC3UL: return std::dynamic_pointer_cast(std::make_shared(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Reptile" + case 0x9751971BD2C2D958UL: return std::dynamic_pointer_cast(std::make_shared(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Giraffe" + case 0x08D007E7B5F7BAF4UL: return std::dynamic_pointer_cast(std::make_shared(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Tiger" + case 0x5F6826EF909803B2UL: return std::dynamic_pointer_cast(std::make_shared(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Snake" + case 0x8E551B208A2E8321UL: return std::dynamic_pointer_cast(std::make_shared(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Turtle" + case 0xF1917FE6BBE77831UL: return std::dynamic_pointer_cast(std::make_shared(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" + case 0x2262ABE80A5E7878UL: return std::dynamic_pointer_cast(std::make_shared(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Zoo" + } + return std::make_shared(this, pHandle); +} /** * CWrapper::GetVersion - retrieves the binary version of this library. @@ -793,21 +636,6 @@ class CZoo : public CBase { return resultSymbolLookupMethod; } - /** - * CWrapper::ImplementsInterface - Test whether an object implements a given interface - * @param[in] pObject - Instance Handle - * @param[in] ClassHashBuffer - Hashed class name of the interface to test - * @return Will be set to true if pInstance implements the interface, false otherwise - */ - inline bool CWrapper::ImplementsInterface(classParam pObject, const CInputVector & ClassHashBuffer) - { - RTTIHandle hObject = pObject.GetHandle(); - bool resultImplementsInterface = 0; - CheckError(nullptr,m_WrapperTable.m_ImplementsInterface(hObject, (RTTI_uint64)ClassHashBuffer.size(), ClassHashBuffer.data(), &resultImplementsInterface)); - - return resultImplementsInterface; - } - /** * CWrapper::CreateZoo - Create a new zoo with animals * @return @@ -820,7 +648,7 @@ class CZoo : public CBase { if (!hInstance) { CheckError(nullptr,RTTI_ERROR_INVALIDPARAM); } - return std::make_shared(this, hInstance); + return this->polymorphicFactory(hInstance); } inline void CWrapper::CheckError(CBase * pBaseClass, RTTIResult nResult) @@ -841,6 +669,7 @@ class CZoo : public CBase { return RTTI_ERROR_INVALIDPARAM; pWrapperTable->m_LibraryHandle = nullptr; + pWrapperTable->m_Base_ClassTypeId = nullptr; pWrapperTable->m_Animal_Name = nullptr; pWrapperTable->m_Tiger_Roar = nullptr; pWrapperTable->m_AnimalIterator_GetNextAnimal = nullptr; @@ -851,7 +680,6 @@ class CZoo : public CBase { pWrapperTable->m_AcquireInstance = nullptr; pWrapperTable->m_InjectComponent = nullptr; pWrapperTable->m_GetSymbolLookupMethod = nullptr; - pWrapperTable->m_ImplementsInterface = nullptr; pWrapperTable->m_CreateZoo = nullptr; return RTTI_SUCCESS; @@ -901,6 +729,15 @@ class CZoo : public CBase { dlerror(); #endif // _WIN32 + #ifdef _WIN32 + pWrapperTable->m_Base_ClassTypeId = (PRTTIBase_ClassTypeIdPtr) GetProcAddress(hLibrary, "rtti_base_classtypeid"); + #else // _WIN32 + pWrapperTable->m_Base_ClassTypeId = (PRTTIBase_ClassTypeIdPtr) dlsym(hLibrary, "rtti_base_classtypeid"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_Base_ClassTypeId == nullptr) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 pWrapperTable->m_Animal_Name = (PRTTIAnimal_NamePtr) GetProcAddress(hLibrary, "rtti_animal_name"); #else // _WIN32 @@ -991,15 +828,6 @@ class CZoo : public CBase { if (pWrapperTable->m_GetSymbolLookupMethod == nullptr) return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; - #ifdef _WIN32 - pWrapperTable->m_ImplementsInterface = (PRTTIImplementsInterfacePtr) GetProcAddress(hLibrary, "rtti_implementsinterface"); - #else // _WIN32 - pWrapperTable->m_ImplementsInterface = (PRTTIImplementsInterfacePtr) dlsym(hLibrary, "rtti_implementsinterface"); - dlerror(); - #endif // _WIN32 - if (pWrapperTable->m_ImplementsInterface == nullptr) - return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; - #ifdef _WIN32 pWrapperTable->m_CreateZoo = (PRTTICreateZooPtr) GetProcAddress(hLibrary, "rtti_createzoo"); #else // _WIN32 @@ -1025,6 +853,10 @@ class CZoo : public CBase { SymbolLookupType pLookup = (SymbolLookupType)pSymbolLookupMethod; RTTIResult eLookupError = RTTI_SUCCESS; + eLookupError = (*pLookup)("rtti_base_classtypeid", (void**)&(pWrapperTable->m_Base_ClassTypeId)); + if ( (eLookupError != 0) || (pWrapperTable->m_Base_ClassTypeId == nullptr) ) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + eLookupError = (*pLookup)("rtti_animal_name", (void**)&(pWrapperTable->m_Animal_Name)); if ( (eLookupError != 0) || (pWrapperTable->m_Animal_Name == nullptr) ) return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; @@ -1065,10 +897,6 @@ class CZoo : public CBase { if ( (eLookupError != 0) || (pWrapperTable->m_GetSymbolLookupMethod == nullptr) ) return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; - eLookupError = (*pLookup)("rtti_implementsinterface", (void**)&(pWrapperTable->m_ImplementsInterface)); - if ( (eLookupError != 0) || (pWrapperTable->m_ImplementsInterface == nullptr) ) - return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; - eLookupError = (*pLookup)("rtti_createzoo", (void**)&(pWrapperTable->m_CreateZoo)); if ( (eLookupError != 0) || (pWrapperTable->m_CreateZoo == nullptr) ) return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; @@ -1082,6 +910,18 @@ class CZoo : public CBase { * Method definitions for class CBase */ + /** + * CBase::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 CBase::ClassTypeId() + { + RTTI_uint64 resultClassTypeId = 0; + CheckError(m_pWrapper->m_WrapperTable.m_Base_ClassTypeId(m_pHandle, &resultClassTypeId)); + + return resultClassTypeId; + } + /** * Method definitions for class CAnimal */ @@ -1147,7 +987,7 @@ class CZoo : public CBase { CheckError(m_pWrapper->m_WrapperTable.m_AnimalIterator_GetNextAnimal(m_pHandle, &hAnimal)); if (hAnimal) { - return std::make_shared(m_pWrapper, hAnimal); + return m_pWrapper->polymorphicFactory(hAnimal); } else { return nullptr; } @@ -1169,7 +1009,7 @@ class CZoo : public CBase { if (!hIterator) { CheckError(RTTI_ERROR_INVALIDPARAM); } - return std::make_shared(m_pWrapper, hIterator); + return m_pWrapper->polymorphicFactory(hIterator); } } // namespace RTTI diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp index ae254c13..12929685 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp @@ -37,6 +37,15 @@ extern "C" { Class definition for Base **************************************************************************************************************************/ +/** +* Get Class Type Id +* +* @param[in] pBase - Base instance. +* @param[out] pClassTypeId - Class type as a 64 bits integer +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_base_classtypeid(RTTI_Base pBase, RTTI_uint64 * pClassTypeId); + /************************************************************************************************************************* Class definition for Animal **************************************************************************************************************************/ @@ -169,17 +178,6 @@ RTTI_DECLSPEC RTTIResult rtti_injectcomponent(const char * pNameSpace, RTTI_pvoi */ RTTI_DECLSPEC RTTIResult rtti_getsymbollookupmethod(RTTI_pvoid * pSymbolLookupMethod); -/** -* Test whether an object implements a given interface -* -* @param[in] pObject - Instance Handle -* @param[in] nClassHashBufferSize - Number of elements in buffer -* @param[in] pClassHashBuffer - uint8 buffer of Hashed class name of the interface to test -* @param[out] pImplementsInterface - Will be set to true if pInstance implements the interface, false otherwise -* @return error code or 0 (success) -*/ -RTTI_DECLSPEC RTTIResult rtti_implementsinterface(RTTI_Base pObject, RTTI_uint64 nClassHashBufferSize, const RTTI_uint8 * pClassHashBuffer, bool * pImplementsInterface); - /** * Create a new zoo with animals * diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp index 97b074aa..b957e1e5 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp @@ -186,6 +186,11 @@ class IBase { return m_ParameterCache.get(); } + /** + * IBase::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + virtual RTTI_uint64 ClassTypeId() = 0; }; @@ -227,6 +232,17 @@ typedef IBaseSharedPtr PIBase; class IAnimal : public virtual IBase { public: + /** + * IAnimal::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 ClassTypeId() override + { + // First 64 bits of SHA1 of a string: "RTTI::Animal" + static const RTTI_uint64 s_AnimalTypeId = 0x8B40467DA6D327AFUL; + return s_AnimalTypeId; + } + /** * IAnimal::Name - Get the name of the animal * @return @@ -244,6 +260,17 @@ typedef IBaseSharedPtr PIAnimal; class IMammal : public virtual IAnimal { public: + /** + * IMammal::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 ClassTypeId() override + { + // First 64 bits of SHA1 of a string: "RTTI::Mammal" + static const RTTI_uint64 s_MammalTypeId = 0xBC9D5FA7750C1020UL; + return s_MammalTypeId; + } + }; typedef IBaseSharedPtr PIMammal; @@ -255,6 +282,17 @@ typedef IBaseSharedPtr PIMammal; class IReptile : public virtual IAnimal { public: + /** + * IReptile::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 ClassTypeId() override + { + // First 64 bits of SHA1 of a string: "RTTI::Reptile" + static const RTTI_uint64 s_ReptileTypeId = 0x6756AA8EA5802EC3UL; + return s_ReptileTypeId; + } + }; typedef IBaseSharedPtr PIReptile; @@ -266,6 +304,17 @@ typedef IBaseSharedPtr PIReptile; class IGiraffe : public virtual IMammal { public: + /** + * IGiraffe::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 ClassTypeId() override + { + // First 64 bits of SHA1 of a string: "RTTI::Giraffe" + static const RTTI_uint64 s_GiraffeTypeId = 0x9751971BD2C2D958UL; + return s_GiraffeTypeId; + } + }; typedef IBaseSharedPtr PIGiraffe; @@ -277,6 +326,17 @@ typedef IBaseSharedPtr PIGiraffe; class ITiger : public virtual IMammal { public: + /** + * ITiger::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 ClassTypeId() override + { + // First 64 bits of SHA1 of a string: "RTTI::Tiger" + static const RTTI_uint64 s_TigerTypeId = 0x8D007E7B5F7BAF4UL; + return s_TigerTypeId; + } + /** * ITiger::Roar - Roar like a tiger */ @@ -293,6 +353,17 @@ typedef IBaseSharedPtr PITiger; class ISnake : public virtual IReptile { public: + /** + * ISnake::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 ClassTypeId() override + { + // First 64 bits of SHA1 of a string: "RTTI::Snake" + static const RTTI_uint64 s_SnakeTypeId = 0x5F6826EF909803B2UL; + return s_SnakeTypeId; + } + }; typedef IBaseSharedPtr PISnake; @@ -304,6 +375,17 @@ typedef IBaseSharedPtr PISnake; class ITurtle : public virtual IReptile { public: + /** + * ITurtle::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 ClassTypeId() override + { + // First 64 bits of SHA1 of a string: "RTTI::Turtle" + static const RTTI_uint64 s_TurtleTypeId = 0x8E551B208A2E8321UL; + return s_TurtleTypeId; + } + }; typedef IBaseSharedPtr PITurtle; @@ -315,6 +397,17 @@ typedef IBaseSharedPtr PITurtle; class IAnimalIterator : public virtual IBase { public: + /** + * IAnimalIterator::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 ClassTypeId() override + { + // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" + static const RTTI_uint64 s_AnimalIteratorTypeId = 0xF1917FE6BBE77831UL; + return s_AnimalIteratorTypeId; + } + /** * IAnimalIterator::GetNextAnimal - Return next animal * @return @@ -332,6 +425,17 @@ typedef IBaseSharedPtr PIAnimalIterator; class IZoo : public virtual IBase { public: + /** + * IZoo::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 ClassTypeId() override + { + // First 64 bits of SHA1 of a string: "RTTI::Zoo" + static const RTTI_uint64 s_ZooTypeId = 0x2262ABE80A5E7878UL; + return s_ZooTypeId; + } + /** * IZoo::Iterator - Return an iterator over all zoo animals * @return diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp index 341e46ee..d38a7539 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp @@ -56,6 +56,32 @@ RTTIResult handleUnhandledException(IBase * pIBaseClass) /************************************************************************************************************************* Class implementation for Base **************************************************************************************************************************/ +RTTIResult rtti_base_classtypeid(RTTI_Base pBase, RTTI_uint64 * pClassTypeId) +{ + IBase* pIBaseClass = (IBase *)pBase; + + try { + if (pClassTypeId == nullptr) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDPARAM); + IBase* pIBase = dynamic_cast(pIBaseClass); + if (!pIBase) + throw ERTTIInterfaceException(RTTI_ERROR_INVALIDCAST); + + *pClassTypeId = pIBase->ClassTypeId(); + + return RTTI_SUCCESS; + } + catch (ERTTIInterfaceException & Exception) { + return handleRTTIException(pIBaseClass, Exception); + } + catch (std::exception & StdException) { + return handleStdException(pIBaseClass, StdException); + } + catch (...) { + return handleUnhandledException(pIBaseClass); + } +} + /************************************************************************************************************************* Class implementation for Animal @@ -235,6 +261,8 @@ RTTIResult RTTI::Impl::RTTI_GetProcAddress (const char * pProcName, void ** ppPr *ppProcAddress = nullptr; std::string sProcName (pProcName); + if (sProcName == "rtti_base_classtypeid") + *ppProcAddress = (void*) &rtti_base_classtypeid; if (sProcName == "rtti_animal_name") *ppProcAddress = (void*) &rtti_animal_name; if (sProcName == "rtti_tiger_roar") @@ -255,8 +283,6 @@ RTTIResult RTTI::Impl::RTTI_GetProcAddress (const char * pProcName, void ** ppPr *ppProcAddress = (void*) &rtti_injectcomponent; if (sProcName == "rtti_getsymbollookupmethod") *ppProcAddress = (void*) &rtti_getsymbollookupmethod; - if (sProcName == "rtti_implementsinterface") - *ppProcAddress = (void*) &rtti_implementsinterface; if (sProcName == "rtti_createzoo") *ppProcAddress = (void*) &rtti_createzoo; @@ -432,93 +458,6 @@ RTTIResult rtti_getsymbollookupmethod(RTTI_pvoid * pSymbolLookupMethod) } } - -/************************************************************************************************************************* - Test whether an object implements a given interface -**************************************************************************************************************************/ - -RTTIResult rtti_implementsinterface(RTTI_Base pObject, RTTI_uint64 nClassHashBufferSize, const RTTI_uint8 * pClassHashBuffer, bool * pImplementsInterface) -{ - if (nClassHashBufferSize != 16) // Hash length must be as expected - return RTTI_ERROR_INVALIDPARAM; - - IBase* pIBaseClassInstance = (IBase *)pObject; - - switch(pClassHashBuffer[0]) { - case 0x06: - static const RTTI_uint8 s_TurtleHash[] = { 0x06, 0xDE, 0xBA, 0x59, 0x08, 0xB0, 0x07, 0xEB, 0x6F, 0x32, 0xD8, 0xD9, 0x5F, 0x3F, 0x61, 0xB5, }; - if (memcmp(pClassHashBuffer, s_TurtleHash, 16) == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - break; - case 0x09: - static const RTTI_uint8 s_BaseHash[] = { 0x09, 0x5A, 0x1B, 0x43, 0xEF, 0xFE, 0xC7, 0x39, 0x55, 0xE3, 0x1E, 0x79, 0x04, 0x38, 0xDE, 0x49, }; - if (memcmp(pClassHashBuffer, s_BaseHash, 16) == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - break; - case 0x16: - static const RTTI_uint8 s_AnimalHash[] = { 0x16, 0x1E, 0x7C, 0xE7, 0xBF, 0xDC, 0x89, 0xAB, 0x4B, 0x9F, 0x52, 0xC1, 0xD4, 0xC9, 0x42, 0x12, }; - if (memcmp(pClassHashBuffer, s_AnimalHash, 16) == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - break; - case 0x37: - static const RTTI_uint8 s_MammalHash[] = { 0x37, 0x42, 0x61, 0x13, 0xD1, 0x29, 0xE7, 0x9F, 0x54, 0x8F, 0x4C, 0x90, 0x93, 0x0F, 0xA6, 0x97, }; - if (memcmp(pClassHashBuffer, s_MammalHash, 16) == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - break; - case 0x42: - static const RTTI_uint8 s_GiraffeHash[] = { 0x42, 0x7D, 0xEB, 0xB8, 0x1D, 0x26, 0x5A, 0x0E, 0xDD, 0x87, 0x89, 0xF3, 0x0B, 0x11, 0xBE, 0xB6, }; - if (memcmp(pClassHashBuffer, s_GiraffeHash, 16) == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - break; - case 0x45: - static const RTTI_uint8 s_TigerHash[] = { 0x45, 0x4C, 0x98, 0x43, 0x11, 0x06, 0x86, 0xBF, 0x6F, 0x67, 0xCE, 0x51, 0x15, 0xB6, 0x66, 0x17, }; - if (memcmp(pClassHashBuffer, s_TigerHash, 16) == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - break; - case 0xAA: - static const RTTI_uint8 s_ReptileHash[] = { 0xAA, 0x64, 0x51, 0x86, 0xA4, 0xB5, 0xF3, 0xF2, 0x79, 0x52, 0xC2, 0xFA, 0x54, 0x85, 0xFA, 0xB2, }; - if (memcmp(pClassHashBuffer, s_ReptileHash, 16) == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - break; - case 0xBF: - static const RTTI_uint8 s_ZooHash[] = { 0xBF, 0xA8, 0x88, 0xA3, 0x54, 0xDB, 0x97, 0xC7, 0xCB, 0xEF, 0xB9, 0xD0, 0x50, 0xB9, 0x4C, 0xA3, }; - if (memcmp(pClassHashBuffer, s_ZooHash, 16) == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - break; - case 0xC2: - static const RTTI_uint8 s_AnimalIteratorHash[] = { 0xC2, 0xB3, 0x6A, 0x84, 0xC6, 0xC0, 0x32, 0x20, 0x4E, 0x5C, 0x92, 0x3C, 0x58, 0x10, 0x71, 0xE7, }; - if (memcmp(pClassHashBuffer, s_AnimalIteratorHash, 16) == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - break; - case 0xDF: - static const RTTI_uint8 s_SnakeHash[] = { 0xDF, 0xA9, 0x0F, 0x1B, 0x4E, 0xB3, 0xAF, 0xFB, 0xD3, 0xB4, 0x6A, 0xF3, 0x4E, 0xD2, 0x47, 0x7C, }; - if (memcmp(pClassHashBuffer, s_SnakeHash, 16) == 0) { - *pImplementsInterface = dynamic_cast(pIBaseClassInstance) != nullptr; - return RTTI_SUCCESS; - } - break; - } - return RTTI_ERROR_INVALIDPARAM; -} - RTTIResult rtti_createzoo(RTTI_Zoo * pInstance) { IBase* pIBaseClass = nullptr; From 33252bdedeab6c5068c13a9d90913eb473a03dd2 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov Date: Mon, 18 Oct 2021 16:54:17 -0700 Subject: [PATCH 036/143] Add Pascal implementation and exmaple --- .../Bindings/Pascal/Unit_RTTI.pas | 913 ++++++++++++++++++ .../Examples/Pascal/RTTI_Example.lpi | 112 +++ .../Examples/Pascal/RTTI_Example.lpr | 109 +++ .../Pascal/Interfaces/rtti.lpr | 49 + .../Pascal/Interfaces/rtti_exception.pas | 104 ++ .../Pascal/Interfaces/rtti_exports.pas | 585 +++++++++++ .../Pascal/Interfaces/rtti_interfaces.pas | 141 +++ .../Pascal/Interfaces/rtti_types.pas | 66 ++ .../Implementations/Pascal/Stub/rtti_impl.pas | 91 ++ .../Pascal/Stub/rtti_impl_animal.pas | 59 ++ .../Pascal/Stub/rtti_impl_animaliterator.pas | 61 ++ .../Pascal/Stub/rtti_impl_base.pas | 90 ++ .../Pascal/Stub/rtti_impl_giraffe.pas | 41 + .../Pascal/Stub/rtti_impl_mammal.pas | 41 + .../Pascal/Stub/rtti_impl_reptile.pas | 41 + .../Pascal/Stub/rtti_impl_snake.pas | 41 + .../Pascal/Stub/rtti_impl_tiger.pas | 47 + .../Pascal/Stub/rtti_impl_turtle.pas | 41 + .../Pascal/Stub/rtti_impl_zoo.pas | 56 ++ .../Implementations/Pascal/rtti.def | 13 + .../Implementations/Pascal/rtti.lpi | 113 +++ 21 files changed, 2814 insertions(+) create mode 100644 Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas create mode 100644 Examples/RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpi create mode 100644 Examples/RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpr create mode 100644 Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti.lpr create mode 100644 Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exception.pas create mode 100644 Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exports.pas create mode 100644 Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_interfaces.pas create mode 100644 Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_types.pas create mode 100644 Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl.pas create mode 100644 Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animal.pas create mode 100644 Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animaliterator.pas create mode 100644 Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_base.pas create mode 100644 Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_giraffe.pas create mode 100644 Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_mammal.pas create mode 100644 Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_reptile.pas create mode 100644 Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_snake.pas create mode 100644 Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_tiger.pas create mode 100644 Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_turtle.pas create mode 100644 Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_zoo.pas create mode 100644 Examples/RTTI/RTTI_component/Implementations/Pascal/rtti.def create mode 100644 Examples/RTTI/RTTI_component/Implementations/Pascal/rtti.lpi diff --git a/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas b/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas new file mode 100644 index 00000000..1333842e --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas @@ -0,0 +1,913 @@ +{$IFDEF FPC}{$MODE DELPHI}{$ENDIF} +(*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Pascal Header file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*) + +unit Unit_RTTI; + +interface + +uses + {$IFDEF WINDOWS} + Windows, + {$ELSE} + dynlibs, + {$ENDIF} + Types, + Classes, + SysUtils; + +(************************************************************************************************************************* + Version definition for RTTI +**************************************************************************************************************************) + +const + RTTI_VERSION_MAJOR = 1; + RTTI_VERSION_MINOR = 0; + RTTI_VERSION_MICRO = 0; + RTTI_VERSION_PRERELEASEINFO = ''; + RTTI_VERSION_BUILDINFO = ''; + + +(************************************************************************************************************************* + General type definitions +**************************************************************************************************************************) + +type + TRTTIResult = Cardinal; + TRTTIHandle = Pointer; + + PRTTIResult = ^TRTTIResult; + PRTTIHandle = ^TRTTIHandle; + +(************************************************************************************************************************* + Error Constants for RTTI +**************************************************************************************************************************) + +const + RTTI_SUCCESS = 0; + RTTI_ERROR_NOTIMPLEMENTED = 1; + RTTI_ERROR_INVALIDPARAM = 2; + RTTI_ERROR_INVALIDCAST = 3; + RTTI_ERROR_BUFFERTOOSMALL = 4; + RTTI_ERROR_GENERICEXCEPTION = 5; + RTTI_ERROR_COULDNOTLOADLIBRARY = 6; + RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT = 7; + RTTI_ERROR_INCOMPATIBLEBINARYVERSION = 8; + + +(************************************************************************************************************************* + Declaration of handle classes +**************************************************************************************************************************) + +type + TRTTIWrapper = class; + TRTTIBase = class; + TRTTIAnimal = class; + TRTTIMammal = class; + TRTTIReptile = class; + TRTTIGiraffe = class; + TRTTITiger = class; + TRTTISnake = class; + TRTTITurtle = class; + TRTTIAnimalIterator = class; + TRTTIZoo = class; + + +(************************************************************************************************************************* + Function type definitions for Base +**************************************************************************************************************************) + + (** + * Get Class Type Id + * + * @param[in] pBase - Base instance. + * @param[out] pClassTypeId - Class type as a 64 bits integer + * @return error code or 0 (success) + *) + TRTTIBase_ClassTypeIdFunc = function(pBase: TRTTIHandle; out pClassTypeId: QWord): TRTTIResult; cdecl; + + +(************************************************************************************************************************* + Function type definitions for Animal +**************************************************************************************************************************) + + (** + * Get the name of the animal + * + * @param[in] pAnimal - Animal instance. + * @param[in] nResultBufferSize - size of the buffer (including trailing 0) + * @param[out] pResultNeededChars - will be filled with the count of the written bytes, or needed buffer size. + * @param[out] pResultBuffer - buffer of , may be NULL + * @return error code or 0 (success) + *) + TRTTIAnimal_NameFunc = function(pAnimal: TRTTIHandle; const nResultBufferSize: Cardinal; out pResultNeededChars: Cardinal; pResultBuffer: PAnsiChar): TRTTIResult; cdecl; + + +(************************************************************************************************************************* + Function type definitions for Mammal +**************************************************************************************************************************) + + +(************************************************************************************************************************* + Function type definitions for Reptile +**************************************************************************************************************************) + + +(************************************************************************************************************************* + Function type definitions for Giraffe +**************************************************************************************************************************) + + +(************************************************************************************************************************* + Function type definitions for Tiger +**************************************************************************************************************************) + + (** + * Roar like a tiger + * + * @param[in] pTiger - Tiger instance. + * @return error code or 0 (success) + *) + TRTTITiger_RoarFunc = function(pTiger: TRTTIHandle): TRTTIResult; cdecl; + + +(************************************************************************************************************************* + Function type definitions for Snake +**************************************************************************************************************************) + + +(************************************************************************************************************************* + Function type definitions for Turtle +**************************************************************************************************************************) + + +(************************************************************************************************************************* + Function type definitions for AnimalIterator +**************************************************************************************************************************) + + (** + * Return next animal + * + * @param[in] pAnimalIterator - AnimalIterator instance. + * @param[out] pAnimal - + * @return error code or 0 (success) + *) + TRTTIAnimalIterator_GetNextAnimalFunc = function(pAnimalIterator: TRTTIHandle; out pAnimal: TRTTIHandle): TRTTIResult; cdecl; + + +(************************************************************************************************************************* + Function type definitions for Zoo +**************************************************************************************************************************) + + (** + * Return an iterator over all zoo animals + * + * @param[in] pZoo - Zoo instance. + * @param[out] pIterator - + * @return error code or 0 (success) + *) + TRTTIZoo_IteratorFunc = function(pZoo: TRTTIHandle; out pIterator: TRTTIHandle): TRTTIResult; cdecl; + +(************************************************************************************************************************* + Global function definitions +**************************************************************************************************************************) + + (** + * retrieves the binary version of this library. + * + * @param[out] pMajor - returns the major version of this library + * @param[out] pMinor - returns the minor version of this library + * @param[out] pMicro - returns the micro version of this library + * @return error code or 0 (success) + *) + TRTTIGetVersionFunc = function(out pMajor: Cardinal; out pMinor: Cardinal; out pMicro: Cardinal): TRTTIResult; cdecl; + + (** + * Returns the last error recorded on this object + * + * @param[in] pInstance - Instance Handle + * @param[in] nErrorMessageBufferSize - size of the buffer (including trailing 0) + * @param[out] pErrorMessageNeededChars - will be filled with the count of the written bytes, or needed buffer size. + * @param[out] pErrorMessageBuffer - buffer of Message of the last error, may be NULL + * @param[out] pHasError - Is there a last error to query + * @return error code or 0 (success) + *) + TRTTIGetLastErrorFunc = function(const pInstance: TRTTIHandle; const nErrorMessageBufferSize: Cardinal; out pErrorMessageNeededChars: Cardinal; pErrorMessageBuffer: PAnsiChar; out pHasError: Byte): TRTTIResult; cdecl; + + (** + * Releases shared ownership of an Instance + * + * @param[in] pInstance - Instance Handle + * @return error code or 0 (success) + *) + TRTTIReleaseInstanceFunc = function(const pInstance: TRTTIHandle): TRTTIResult; cdecl; + + (** + * Acquires shared ownership of an Instance + * + * @param[in] pInstance - Instance Handle + * @return error code or 0 (success) + *) + TRTTIAcquireInstanceFunc = function(const pInstance: TRTTIHandle): TRTTIResult; cdecl; + + (** + * Injects an imported component for usage within this component + * + * @param[in] pNameSpace - NameSpace of the injected component + * @param[in] pSymbolAddressMethod - Address of the SymbolAddressMethod of the injected component + * @return error code or 0 (success) + *) + TRTTIInjectComponentFunc = function(const pNameSpace: PAnsiChar; const pSymbolAddressMethod: Pointer): TRTTIResult; cdecl; + + (** + * Returns the address of the SymbolLookupMethod + * + * @param[out] pSymbolLookupMethod - Address of the SymbolAddressMethod + * @return error code or 0 (success) + *) + TRTTIGetSymbolLookupMethodFunc = function(out pSymbolLookupMethod: Pointer): TRTTIResult; cdecl; + + (** + * Create a new zoo with animals + * + * @param[out] pInstance - + * @return error code or 0 (success) + *) + TRTTICreateZooFunc = function(out pInstance: TRTTIHandle): TRTTIResult; cdecl; + + +(************************************************************************************************************************* + Helper function pointer definitions +**************************************************************************************************************************) +TRTTISymbolLookupMethod = function(const pSymbolName: PAnsiChar; out pValue: Pointer): TRTTIResult; cdecl; + +(************************************************************************************************************************* + Exception definition +**************************************************************************************************************************) + + ERTTIException = class(Exception) + private + FErrorCode: TRTTIResult; + FCustomMessage: String; + public + property ErrorCode: TRTTIResult read FErrorCode; + property CustomMessage: String read FCustomMessage; + constructor Create(AErrorCode: TRTTIResult; AMessage: String); + constructor CreateCustomMessage(AErrorCode: TRTTIResult; AMessage: String); + end; + + +(************************************************************************************************************************* + Class definition for Base +**************************************************************************************************************************) + + TRTTIBase = class(TObject) + private + FWrapper: TRTTIWrapper; + FHandle: TRTTIHandle; + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + property TheHandle: TRTTIHandle read FHandle; + function ClassTypeId(): QWord; + end; + + +(************************************************************************************************************************* + Class definition for Animal +**************************************************************************************************************************) + + TRTTIAnimal = class(TRTTIBase) + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + function Name(): String; + end; + + +(************************************************************************************************************************* + Class definition for Mammal +**************************************************************************************************************************) + + TRTTIMammal = class(TRTTIAnimal) + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + end; + + +(************************************************************************************************************************* + Class definition for Reptile +**************************************************************************************************************************) + + TRTTIReptile = class(TRTTIAnimal) + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + end; + + +(************************************************************************************************************************* + Class definition for Giraffe +**************************************************************************************************************************) + + TRTTIGiraffe = class(TRTTIMammal) + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + end; + + +(************************************************************************************************************************* + Class definition for Tiger +**************************************************************************************************************************) + + TRTTITiger = class(TRTTIMammal) + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + procedure Roar(); + end; + + +(************************************************************************************************************************* + Class definition for Snake +**************************************************************************************************************************) + + TRTTISnake = class(TRTTIReptile) + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + end; + + +(************************************************************************************************************************* + Class definition for Turtle +**************************************************************************************************************************) + + TRTTITurtle = class(TRTTIReptile) + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + end; + + +(************************************************************************************************************************* + Class definition for AnimalIterator +**************************************************************************************************************************) + + TRTTIAnimalIterator = class(TRTTIBase) + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + function GetNextAnimal(): TRTTIAnimal; + end; + + +(************************************************************************************************************************* + Class definition for Zoo +**************************************************************************************************************************) + + TRTTIZoo = class(TRTTIBase) + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + function Iterator(): TRTTIAnimalIterator; + end; + +(************************************************************************************************************************* + Wrapper definition +**************************************************************************************************************************) + + TRTTIWrapper = class(TObject) + private + FModule: HMODULE; + FRTTIBase_ClassTypeIdFunc: TRTTIBase_ClassTypeIdFunc; + FRTTIAnimal_NameFunc: TRTTIAnimal_NameFunc; + FRTTITiger_RoarFunc: TRTTITiger_RoarFunc; + FRTTIAnimalIterator_GetNextAnimalFunc: TRTTIAnimalIterator_GetNextAnimalFunc; + FRTTIZoo_IteratorFunc: TRTTIZoo_IteratorFunc; + FRTTIGetVersionFunc: TRTTIGetVersionFunc; + FRTTIGetLastErrorFunc: TRTTIGetLastErrorFunc; + FRTTIReleaseInstanceFunc: TRTTIReleaseInstanceFunc; + FRTTIAcquireInstanceFunc: TRTTIAcquireInstanceFunc; + FRTTIInjectComponentFunc: TRTTIInjectComponentFunc; + FRTTIGetSymbolLookupMethodFunc: TRTTIGetSymbolLookupMethodFunc; + FRTTICreateZooFunc: TRTTICreateZooFunc; + + {$IFDEF MSWINDOWS} + function LoadFunction(AFunctionName: AnsiString; FailIfNotExistent: Boolean = True): FARPROC; + {$ELSE} + function LoadFunction(AFunctionName: AnsiString; FailIfNotExistent: Boolean = True): Pointer; + {$ENDIF MSWINDOWS} + + procedure checkBinaryVersion(); + + protected + property RTTIBase_ClassTypeIdFunc: TRTTIBase_ClassTypeIdFunc read FRTTIBase_ClassTypeIdFunc; + property RTTIAnimal_NameFunc: TRTTIAnimal_NameFunc read FRTTIAnimal_NameFunc; + property RTTITiger_RoarFunc: TRTTITiger_RoarFunc read FRTTITiger_RoarFunc; + property RTTIAnimalIterator_GetNextAnimalFunc: TRTTIAnimalIterator_GetNextAnimalFunc read FRTTIAnimalIterator_GetNextAnimalFunc; + property RTTIZoo_IteratorFunc: TRTTIZoo_IteratorFunc read FRTTIZoo_IteratorFunc; + property RTTIGetVersionFunc: TRTTIGetVersionFunc read FRTTIGetVersionFunc; + property RTTIGetLastErrorFunc: TRTTIGetLastErrorFunc read FRTTIGetLastErrorFunc; + property RTTIReleaseInstanceFunc: TRTTIReleaseInstanceFunc read FRTTIReleaseInstanceFunc; + property RTTIAcquireInstanceFunc: TRTTIAcquireInstanceFunc read FRTTIAcquireInstanceFunc; + property RTTIInjectComponentFunc: TRTTIInjectComponentFunc read FRTTIInjectComponentFunc; + property RTTIGetSymbolLookupMethodFunc: TRTTIGetSymbolLookupMethodFunc read FRTTIGetSymbolLookupMethodFunc; + property RTTICreateZooFunc: TRTTICreateZooFunc read FRTTICreateZooFunc; + procedure CheckError(AInstance: TRTTIBase; AErrorCode: TRTTIResult); + public + constructor Create(ADLLName: String); + constructor CreateFromSymbolLookupMethod(ALookupMethod: TRTTISymbolLookupMethod); + destructor Destroy; override; + procedure GetVersion(out AMajor: Cardinal; out AMinor: Cardinal; out AMicro: Cardinal); + function GetLastError(const AInstance: TRTTIBase; out AErrorMessage: String): Boolean; + procedure ReleaseInstance(const AInstance: TRTTIBase); + procedure AcquireInstance(const AInstance: TRTTIBase); + procedure InjectComponent(const ANameSpace: String; const ASymbolAddressMethod: Pointer); + function GetSymbolLookupMethod(): Pointer; + function CreateZoo(): TRTTIZoo; + end; + + TPolymorphicFactory<_T:class; _B> = record + class function Make(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): _T; static; + end; + +implementation + + +(************************************************************************************************************************* + PolymorficFactory implementation +**************************************************************************************************************************) + + class function TPolymorphicFactory<_T, _B>.Make(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): _T; + var + ClassTypeId: QWord; + Obj: TRTTIBase; + begin + Result := nil; + Wrapper.CheckError(nil, Wrapper.RTTIBase_ClassTypeIdFunc(handle, ClassTypeId)); + case (ClassTypeId) of + $1549AD28813DAE05: begin Obj := TRTTIBase.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Base" + $8B40467DA6D327AF: begin Obj := TRTTIAnimal.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Animal" + $BC9D5FA7750C1020: begin Obj := TRTTIMammal.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Mammal" + $6756AA8EA5802EC3: begin Obj := TRTTIReptile.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Reptile" + $9751971BD2C2D958: begin Obj := TRTTIGiraffe.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Giraffe" + $08D007E7B5F7BAF4: begin Obj := TRTTITiger.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Tiger" + $5F6826EF909803B2: begin Obj := TRTTISnake.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Snake" + $8E551B208A2E8321: begin Obj := TRTTITurtle.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Turtle" + $F1917FE6BBE77831: begin Obj := TRTTIAnimalIterator.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" + $2262ABE80A5E7878: begin Obj := TRTTIZoo.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Zoo" + end; + if Result = nil then Result := _B.Create(Wrapper, Handle); + end; + +(************************************************************************************************************************* + Exception implementation +**************************************************************************************************************************) + + constructor ERTTIException.Create(AErrorCode: TRTTIResult; AMessage: String); + var + ADescription: String; + begin + FErrorCode := AErrorCode; + case FErrorCode of + RTTI_ERROR_NOTIMPLEMENTED: ADescription := 'functionality not implemented'; + RTTI_ERROR_INVALIDPARAM: ADescription := 'an invalid parameter was passed'; + RTTI_ERROR_INVALIDCAST: ADescription := 'a type cast failed'; + RTTI_ERROR_BUFFERTOOSMALL: ADescription := 'a provided buffer is too small'; + RTTI_ERROR_GENERICEXCEPTION: ADescription := 'a generic exception occurred'; + RTTI_ERROR_COULDNOTLOADLIBRARY: ADescription := 'the library could not be loaded'; + RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT: ADescription := 'a required exported symbol could not be found in the library'; + RTTI_ERROR_INCOMPATIBLEBINARYVERSION: ADescription := 'the version of the binary interface does not match the bindings interface'; + else + ADescription := 'unknown'; + end; + + inherited Create(Format('RTTI Error - %s (#%d, %s)', [ ADescription, AErrorCode, AMessage ])); + end; + + constructor ERTTIException.CreateCustomMessage(AErrorCode: TRTTIResult; AMessage: String); + begin + FCustomMessage := AMessage; + FErrorCode := AErrorCode; + inherited Create(Format('%s (%d)', [FCustomMessage, AErrorCode])); + end; + +(************************************************************************************************************************* + Class implementation for Base +**************************************************************************************************************************) + + constructor TRTTIBase.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + if not Assigned(AWrapper) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM, ''); + if not Assigned(AHandle) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM, ''); + + inherited Create(); + FWrapper := AWrapper; + FHandle := AHandle; + end; + + destructor TRTTIBase.Destroy; + begin + FWrapper.ReleaseInstance(self); + inherited; + end; + + function TRTTIBase.ClassTypeId(): QWord; + begin + FWrapper.CheckError(Self, FWrapper.RTTIBase_ClassTypeIdFunc(FHandle, Result)); + end; + +(************************************************************************************************************************* + Class implementation for Animal +**************************************************************************************************************************) + + constructor TRTTIAnimal.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + inherited Create(AWrapper, AHandle); + end; + + destructor TRTTIAnimal.Destroy; + begin + inherited; + end; + + function TRTTIAnimal.Name(): String; + var + bytesNeededResult: Cardinal; + bytesWrittenResult: Cardinal; + bufferResult: array of Char; + begin + bytesNeededResult:= 0; + bytesWrittenResult:= 0; + FWrapper.CheckError(Self, FWrapper.RTTIAnimal_NameFunc(FHandle, 0, bytesNeededResult, nil)); + SetLength(bufferResult, bytesNeededResult); + FWrapper.CheckError(Self, FWrapper.RTTIAnimal_NameFunc(FHandle, bytesNeededResult, bytesWrittenResult, @bufferResult[0])); + Result := StrPas(@bufferResult[0]); + end; + +(************************************************************************************************************************* + Class implementation for Mammal +**************************************************************************************************************************) + + constructor TRTTIMammal.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + inherited Create(AWrapper, AHandle); + end; + + destructor TRTTIMammal.Destroy; + begin + inherited; + end; + +(************************************************************************************************************************* + Class implementation for Reptile +**************************************************************************************************************************) + + constructor TRTTIReptile.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + inherited Create(AWrapper, AHandle); + end; + + destructor TRTTIReptile.Destroy; + begin + inherited; + end; + +(************************************************************************************************************************* + Class implementation for Giraffe +**************************************************************************************************************************) + + constructor TRTTIGiraffe.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + inherited Create(AWrapper, AHandle); + end; + + destructor TRTTIGiraffe.Destroy; + begin + inherited; + end; + +(************************************************************************************************************************* + Class implementation for Tiger +**************************************************************************************************************************) + + constructor TRTTITiger.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + inherited Create(AWrapper, AHandle); + end; + + destructor TRTTITiger.Destroy; + begin + inherited; + end; + + procedure TRTTITiger.Roar(); + begin + FWrapper.CheckError(Self, FWrapper.RTTITiger_RoarFunc(FHandle)); + end; + +(************************************************************************************************************************* + Class implementation for Snake +**************************************************************************************************************************) + + constructor TRTTISnake.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + inherited Create(AWrapper, AHandle); + end; + + destructor TRTTISnake.Destroy; + begin + inherited; + end; + +(************************************************************************************************************************* + Class implementation for Turtle +**************************************************************************************************************************) + + constructor TRTTITurtle.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + inherited Create(AWrapper, AHandle); + end; + + destructor TRTTITurtle.Destroy; + begin + inherited; + end; + +(************************************************************************************************************************* + Class implementation for AnimalIterator +**************************************************************************************************************************) + + constructor TRTTIAnimalIterator.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + inherited Create(AWrapper, AHandle); + end; + + destructor TRTTIAnimalIterator.Destroy; + begin + inherited; + end; + + function TRTTIAnimalIterator.GetNextAnimal(): TRTTIAnimal; + var + HAnimal: TRTTIHandle; + begin + Result := nil; + HAnimal := nil; + FWrapper.CheckError(Self, FWrapper.RTTIAnimalIterator_GetNextAnimalFunc(FHandle, HAnimal)); + if Assigned(HAnimal) then + Result := TPolymorphicFactory.Make(FWrapper, HAnimal); + end; + +(************************************************************************************************************************* + Class implementation for Zoo +**************************************************************************************************************************) + + constructor TRTTIZoo.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + inherited Create(AWrapper, AHandle); + end; + + destructor TRTTIZoo.Destroy; + begin + inherited; + end; + + function TRTTIZoo.Iterator(): TRTTIAnimalIterator; + var + HIterator: TRTTIHandle; + begin + Result := nil; + HIterator := nil; + FWrapper.CheckError(Self, FWrapper.RTTIZoo_IteratorFunc(FHandle, HIterator)); + if Assigned(HIterator) then + Result := TPolymorphicFactory.Make(FWrapper, HIterator); + end; + +(************************************************************************************************************************* + Wrapper class implementation +**************************************************************************************************************************) + + constructor TRTTIWrapper.Create(ADLLName: String); + {$IFDEF MSWINDOWS} + var + AWideString: WideString; + {$ENDIF MSWINDOWS} + begin + inherited Create; + + + {$IFDEF MSWINDOWS} + AWideString := UTF8Decode(ADLLName + #0); + FModule := LoadLibraryW(PWideChar(AWideString)); + {$ELSE} + FModule := dynlibs.LoadLibrary(ADLLName); + {$ENDIF MSWINDOWS} + if FModule = 0 then + raise ERTTIException.Create(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + + FRTTIBase_ClassTypeIdFunc := LoadFunction('rtti_base_classtypeid'); + FRTTIAnimal_NameFunc := LoadFunction('rtti_animal_name'); + FRTTITiger_RoarFunc := LoadFunction('rtti_tiger_roar'); + FRTTIAnimalIterator_GetNextAnimalFunc := LoadFunction('rtti_animaliterator_getnextanimal'); + FRTTIZoo_IteratorFunc := LoadFunction('rtti_zoo_iterator'); + FRTTIGetVersionFunc := LoadFunction('rtti_getversion'); + FRTTIGetLastErrorFunc := LoadFunction('rtti_getlasterror'); + FRTTIReleaseInstanceFunc := LoadFunction('rtti_releaseinstance'); + FRTTIAcquireInstanceFunc := LoadFunction('rtti_acquireinstance'); + FRTTIInjectComponentFunc := LoadFunction('rtti_injectcomponent'); + FRTTIGetSymbolLookupMethodFunc := LoadFunction('rtti_getsymbollookupmethod'); + FRTTICreateZooFunc := LoadFunction('rtti_createzoo'); + + checkBinaryVersion(); + end; + + constructor TRTTIWrapper.CreateFromSymbolLookupMethod(ALookupMethod: TRTTISymbolLookupMethod); + var + AResult : TRTTIResult; + begin + inherited Create; + + + AResult := ALookupMethod(PAnsiChar('rtti_base_classtypeid'), @FRTTIBase_ClassTypeIdFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_animal_name'), @FRTTIAnimal_NameFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_tiger_roar'), @FRTTITiger_RoarFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_animaliterator_getnextanimal'), @FRTTIAnimalIterator_GetNextAnimalFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_zoo_iterator'), @FRTTIZoo_IteratorFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_getversion'), @FRTTIGetVersionFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_getlasterror'), @FRTTIGetLastErrorFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_releaseinstance'), @FRTTIReleaseInstanceFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_acquireinstance'), @FRTTIAcquireInstanceFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_injectcomponent'), @FRTTIInjectComponentFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_getsymbollookupmethod'), @FRTTIGetSymbolLookupMethodFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_createzoo'), @FRTTICreateZooFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + + checkBinaryVersion(); + end; + + destructor TRTTIWrapper.Destroy; + begin + {$IFDEF MSWINDOWS} + if FModule <> 0 then + FreeLibrary(FModule); + {$ELSE} + if FModule <> 0 then + UnloadLibrary(FModule); + {$ENDIF MSWINDOWS} + inherited; + end; + + procedure TRTTIWrapper.CheckError(AInstance: TRTTIBase; AErrorCode: TRTTIResult); + var + AErrorMessage: String; + begin + if AInstance <> nil then begin + if AInstance.FWrapper <> Self then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_INVALIDCAST, 'invalid wrapper call'); + end; + if AErrorCode <> RTTI_SUCCESS then begin + AErrorMessage := ''; + if Assigned(AInstance) then + GetLastError(AInstance, AErrorMessage); + raise ERTTIException.Create(AErrorCode, AErrorMessage); + end; + end; + + {$IFDEF MSWINDOWS} + function TRTTIWrapper.LoadFunction(AFunctionName: AnsiString; FailIfNotExistent: Boolean): FARPROC; + begin + Result := GetProcAddress(FModule, PAnsiChar(AFunctionName)); + if FailIfNotExistent and not Assigned(Result) then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT, 'could not find function ' + AFunctionName); + end; + {$ELSE} + function TRTTIWrapper.LoadFunction(AFunctionName: AnsiString; FailIfNotExistent: Boolean): Pointer; + begin + Result := dynlibs.GetProcAddress(FModule, AFunctionName); + if FailIfNotExistent and not Assigned(Result) then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT, 'could not find function ' + AFunctionName); + end; + {$ENDIF MSWINDOWS} + + procedure TRTTIWrapper.checkBinaryVersion(); + var + AMajor, AMinor, AMicro: Cardinal; + begin + GetVersion(AMajor, AMinor, AMicro); + if (AMajor <> RTTI_VERSION_MAJOR) then + raise ERTTIException.Create(RTTI_ERROR_INCOMPATIBLEBINARYVERSION, ''); + end; + + procedure TRTTIWrapper.GetVersion(out AMajor: Cardinal; out AMinor: Cardinal; out AMicro: Cardinal); + begin + CheckError(nil, RTTIGetVersionFunc(AMajor, AMinor, AMicro)); + end; + + function TRTTIWrapper.GetLastError(const AInstance: TRTTIBase; out AErrorMessage: String): Boolean; + var + AInstanceHandle: TRTTIHandle; + bytesNeededErrorMessage: Cardinal; + bytesWrittenErrorMessage: Cardinal; + bufferErrorMessage: array of Char; + ResultHasError: Byte; + begin + if Assigned(AInstance) then + AInstanceHandle := AInstance.TheHandle + else + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_INVALIDPARAM, 'AInstance is a nil value.'); + bytesNeededErrorMessage:= 0; + bytesWrittenErrorMessage:= 0; + ResultHasError := 0; + CheckError(nil, RTTIGetLastErrorFunc(AInstanceHandle, 0, bytesNeededErrorMessage, nil, ResultHasError)); + SetLength(bufferErrorMessage, bytesNeededErrorMessage); + CheckError(nil, RTTIGetLastErrorFunc(AInstanceHandle, bytesNeededErrorMessage, bytesWrittenErrorMessage, @bufferErrorMessage[0], ResultHasError)); + AErrorMessage := StrPas(@bufferErrorMessage[0]); + Result := (ResultHasError <> 0); + end; + + procedure TRTTIWrapper.ReleaseInstance(const AInstance: TRTTIBase); + var + AInstanceHandle: TRTTIHandle; + begin + if Assigned(AInstance) then + AInstanceHandle := AInstance.TheHandle + else + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_INVALIDPARAM, 'AInstance is a nil value.'); + CheckError(nil, RTTIReleaseInstanceFunc(AInstanceHandle)); + end; + + procedure TRTTIWrapper.AcquireInstance(const AInstance: TRTTIBase); + var + AInstanceHandle: TRTTIHandle; + begin + if Assigned(AInstance) then + AInstanceHandle := AInstance.TheHandle + else + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_INVALIDPARAM, 'AInstance is a nil value.'); + CheckError(nil, RTTIAcquireInstanceFunc(AInstanceHandle)); + end; + + procedure TRTTIWrapper.InjectComponent(const ANameSpace: String; const ASymbolAddressMethod: Pointer); + begin + CheckError(nil, RTTIInjectComponentFunc(PAnsiChar(ANameSpace), ASymbolAddressMethod)); + end; + + function TRTTIWrapper.GetSymbolLookupMethod(): Pointer; + begin + CheckError(nil, RTTIGetSymbolLookupMethodFunc(Result)); + end; + + function TRTTIWrapper.CreateZoo(): TRTTIZoo; + var + HInstance: TRTTIHandle; + begin + Result := nil; + HInstance := nil; + CheckError(nil, RTTICreateZooFunc(HInstance)); + if Assigned(HInstance) then + Result := TPolymorphicFactory.Make(Self, HInstance); + end; + + +end. diff --git a/Examples/RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpi b/Examples/RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpi new file mode 100644 index 00000000..c626a4e4 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpi @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + <UseAppBundle Value="False"/> + <ResourceType Value="res"/> + </General> + <BuildModes Count="2"> + <Item1 Name="Release" Default="True"/> + <Item2 Name="Debug"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\Release\RTTI_Example"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <OtherUnitFiles Value="..\..\Bindings\Pascal"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <IncludeAssertionCode Value="True"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <RelocatableUnit Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <UseExternalDbgSyms Value="True"/> + </Debugging> + <Options> + <ExecutableType Value="Library"/> + </Options> + </Linking> + </CompilerOptions> + </Item2> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + <Modes Count="1"> + <Mode0 Name="default"/> + </Modes> + </RunParams> + <Units Count="2"> + <Unit0> + <Filename Value="RTTI_Example.lpr"/> + <IsPartOfProject Value="True"/> + <UnitName Value="RTTIPascalTest"/> + </Unit0> + <Unit1> + <Filename Value="Unit_RTTI.pas"/> + <IsPartOfProject Value="True"/> + </Unit1> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\Release\RTTI_Example"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <OtherUnitFiles Value="..\..\Bindings\Pascal"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <IncludeAssertionCode Value="True"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <RelocatableUnit Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <DebugInfoType Value="dsDwarf2Set"/> + <StripSymbols Value="True"/> + <UseExternalDbgSyms Value="True"/> + </Debugging> + </Linking> + </CompilerOptions> + <Debugging> + <Exceptions Count="3"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/Examples/RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpr b/Examples/RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpr new file mode 100644 index 00000000..d7907356 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpr @@ -0,0 +1,109 @@ +(*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Pascal application that demonstrates the + usage of the Pascal bindings of RTTI + +Interface version: 1.0.0 + +*) + +program RTTIPascalTest; +{$mode objfpc}{$H+} +uses + {$IFDEF UNIX}{$IFDEF UseCThreads} + cthreads, + {$ENDIF}{$ENDIF} + Classes, SysUtils, CustApp, + Unit_RTTI + { you can add units after this }; + +type + +TRTTI_Example = class(TCustomApplication) +protected + procedure DoRun; override; + procedure TestRTTI(); +public + constructor Create(TheOwner: TComponent); override; + destructor Destroy; override; +end; + + +procedure TRTTI_Example.TestRTTI(); +var + ARTTIWrapper: TRTTIWrapper; + Zoo: TRTTIZoo; + Iterator: TRTTIAnimalIterator; + Animal: TRTTIAnimal; + Tiger: TRTTITiger; + AMajor, AMinor, AMicro: Cardinal; + AVersionString: string; + ALibPath: string; +begin + writeln('loading DLL'); + ALibPath := '/Users/anpiloa/git/AutomaticComponentToolkit/Examples/RTTI/RTTI_component/Implementations/Pascal/bin/x86_64-darwin/Release'; // TODO add the location of the shared library binary here + ARTTIWrapper := TRTTIWrapper.Create(ALibPath + '/' + 'libprojectrtti.dylib'); // TODO add the extension of the shared library file here + + //ALibPath := '/Users/anpiloa/git/AutomaticComponentToolkit/Examples/RTTI/build-lib/'; // TODO add the location of the shared library binary here + //ARTTIWrapper := TRTTIWrapper.Create(ALibPath + '/' + 'rtti.dylib'); // TODO add the extension of the shared library file here + + try + writeln('loading DLL Done'); + ARTTIWrapper.GetVersion(AMajor, AMinor, AMicro); + AVersionString := Format('RTTI.version = %d.%d.%d', [AMajor, AMinor, AMicro]); + writeln(AVersionString); + Zoo := ARTTIWrapper.CreateZoo(); + Iterator := Zoo.Iterator(); + Animal := Iterator.GetNextAnimal(); + while Animal <> nil do + begin + writeln('Animal name: ', Animal.Name()); + if Animal is TRTTITiger then + begin + writeln(' ^ is a real tiger!!!'); + Tiger := Animal as TRTTITiger; + Tiger.Roar(); + end; + Animal := Iterator.GetNextAnimal(); + end; + finally + FreeAndNil(ARTTIWrapper); + end; +end; + +procedure TRTTI_Example.DoRun; +begin + try + TestRTTI(); + except + On E: Exception do + writeln('Fatal error: ', E.Message); + end; + Terminate +end; + +constructor TRTTI_Example.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + StopOnException:=True; +end; + +destructor TRTTI_Example.Destroy; +begin + inherited Destroy; +end; + + +var + Application: TRTTI_Example; +begin + Application:=TRTTI_Example.Create(nil); + Application.Run; + Application.Free; +end. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti.lpr b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti.lpr new file mode 100644 index 00000000..e4df19c3 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti.lpr @@ -0,0 +1,49 @@ +(*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Pascal project file in order to allow easy +development of RTTI. + +Interface version: 1.0.0 + +*) + +{$MODE DELPHI} +library rtti; + +uses +{$IFDEF UNIX} + cthreads, +{$ENDIF UNIX} + syncobjs, + rtti_types, + rtti_exports, + Classes, + sysutils; + +exports + rtti_base_classtypeid, + rtti_animal_name, + rtti_tiger_roar, + rtti_animaliterator_getnextanimal, + rtti_zoo_iterator, + rtti_getversion, + rtti_getlasterror, + rtti_releaseinstance, + rtti_acquireinstance, + rtti_injectcomponent, + rtti_getsymbollookupmethod, + rtti_createzoo; + +{$IFDEF RTTI_INCLUDE_RES_FILE} +{$R *.res} +{$ENDIF RTTI_INCLUDE_RES_FILE} + +begin + +end. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exception.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exception.pas new file mode 100644 index 00000000..fc3465ff --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exception.pas @@ -0,0 +1,104 @@ +(*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Pascal exception class definition file in order to allow easy +development of RTTI. The functions in this file need to be implemented. It needs to be generated only once. + +Interface version: 1.0.0 + +*) + +{$MODE DELPHI} +unit rtti_exception; + +interface + +uses + rtti_types, + rtti_interfaces, + Classes, + sysutils; + +type + ERTTIException = class(Exception) + private + FErrorCode: TRTTIResult; + FCustomMessage: String; + public + property ErrorCode: TRTTIResult read FErrorCode; + property CustomMessage: String read FCustomMessage; + constructor Create(AErrorCode: TRTTIResult); + constructor CreateCustomMessage(AErrorCode: TRTTIResult; AMessage: String); + end; + + +(************************************************************************************************************************* + Definition of exception handling functionality for RTTI +**************************************************************************************************************************) + +function HandleRTTIException(ARTTIObject: TObject; E: ERTTIException): TRTTIResult; +function HandleStdException(ARTTIObject: TObject; E: Exception): TRTTIResult; +function HandleUnhandledException(ARTTIObject: TObject): TRTTIResult; + + +implementation + + constructor ERTTIException.Create(AErrorCode: TRTTIResult); + var + ADescription: String; + begin + FErrorCode := AErrorCode; + case FErrorCode of + RTTI_ERROR_NOTIMPLEMENTED: ADescription := 'functionality not implemented'; + RTTI_ERROR_INVALIDPARAM: ADescription := 'an invalid parameter was passed'; + RTTI_ERROR_INVALIDCAST: ADescription := 'a type cast failed'; + RTTI_ERROR_BUFFERTOOSMALL: ADescription := 'a provided buffer is too small'; + RTTI_ERROR_GENERICEXCEPTION: ADescription := 'a generic exception occurred'; + RTTI_ERROR_COULDNOTLOADLIBRARY: ADescription := 'the library could not be loaded'; + RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT: ADescription := 'a required exported symbol could not be found in the library'; + RTTI_ERROR_INCOMPATIBLEBINARYVERSION: ADescription := 'the version of the binary interface does not match the bindings interface'; + else + ADescription := 'unknown'; + end; + + inherited Create(Format('RTTI Error - %s (#%d)', [ ADescription, AErrorCode ])); + end; + + constructor ERTTIException.CreateCustomMessage(AErrorCode: TRTTIResult; AMessage: String); + begin + FCustomMessage := AMessage; + FErrorCode := AErrorCode; + inherited Create(Format('%s(%d)', [FCustomMessage, AErrorCode])); + end; + +(************************************************************************************************************************* + Implementation of exception handling functionality for RTTI +**************************************************************************************************************************) + +function HandleRTTIException(ARTTIObject: TObject; E: ERTTIException): TRTTIResult; +begin + result := E.ErrorCode; + if Supports(ARTTIObject, IRTTIBase) then begin + (ARTTIObject as IRTTIBase).RegisterErrorMessage(E.CustomMessage) + end; +end; +function HandleStdException(ARTTIObject: TObject; E: Exception): TRTTIResult; +begin + Result := RTTI_ERROR_GENERICEXCEPTION; + if Supports(ARTTIObject, IRTTIBase) then begin + (ARTTIObject as IRTTIBase).RegisterErrorMessage(E.Message) + end; +end; +function HandleUnhandledException(ARTTIObject: TObject): TRTTIResult; +begin + Result := RTTI_ERROR_GENERICEXCEPTION; + if Supports(ARTTIObject, IRTTIBase) then begin + (ARTTIObject as IRTTIBase).RegisterErrorMessage('Unhandled Exception') + end; +end; +end. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exports.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exports.pas new file mode 100644 index 00000000..4709c400 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exports.pas @@ -0,0 +1,585 @@ +(*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Pascal export implementation file in order to allow easy +development of RTTI. The functions in this file need to be implemented. It needs to be generated only once. + +Interface version: 1.0.0 + +*) + +{$MODE DELPHI} +unit rtti_exports; + +interface + +uses + rtti_impl, + rtti_types, + rtti_interfaces, + rtti_exception, + Classes, + sysutils; + +(************************************************************************************************************************* + Class export definition of Base +**************************************************************************************************************************) + +(** +* Get Class Type Id +* +* @param[in] pBase - Base instance. +* @param[out] pClassTypeId - Class type as a 64 bits integer +* @return error code or 0 (success) +*) +function rtti_base_classtypeid(pBase: TRTTIHandle; pClassTypeId: PQWord): TRTTIResult; cdecl; + +(************************************************************************************************************************* + Class export definition of Animal +**************************************************************************************************************************) + +(** +* Get the name of the animal +* +* @param[in] pAnimal - Animal instance. +* @param[in] nResultBufferSize - size of the buffer (including trailing 0) +* @param[out] pResultNeededChars - will be filled with the count of the written bytes, or needed buffer size. +* @param[out] pResultBuffer - buffer of , may be NULL +* @return error code or 0 (success) +*) +function rtti_animal_name(pAnimal: TRTTIHandle; nResultBufferSize: Cardinal; pResultNeededChars: PCardinal; pResultBuffer: PAnsiChar): TRTTIResult; cdecl; + +(************************************************************************************************************************* + Class export definition of Mammal +**************************************************************************************************************************) + +(************************************************************************************************************************* + Class export definition of Reptile +**************************************************************************************************************************) + +(************************************************************************************************************************* + Class export definition of Giraffe +**************************************************************************************************************************) + +(************************************************************************************************************************* + Class export definition of Tiger +**************************************************************************************************************************) + +(** +* Roar like a tiger +* +* @param[in] pTiger - Tiger instance. +* @return error code or 0 (success) +*) +function rtti_tiger_roar(pTiger: TRTTIHandle): TRTTIResult; cdecl; + +(************************************************************************************************************************* + Class export definition of Snake +**************************************************************************************************************************) + +(************************************************************************************************************************* + Class export definition of Turtle +**************************************************************************************************************************) + +(************************************************************************************************************************* + Class export definition of AnimalIterator +**************************************************************************************************************************) + +(** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @return error code or 0 (success) +*) +function rtti_animaliterator_getnextanimal(pAnimalIterator: TRTTIHandle; pAnimal: PRTTIHandle): TRTTIResult; cdecl; + +(************************************************************************************************************************* + Class export definition of Zoo +**************************************************************************************************************************) + +(** +* Return an iterator over all zoo animals +* +* @param[in] pZoo - Zoo instance. +* @param[out] pIterator - +* @return error code or 0 (success) +*) +function rtti_zoo_iterator(pZoo: TRTTIHandle; pIterator: PRTTIHandle): TRTTIResult; cdecl; + +(************************************************************************************************************************* + Global function export definition +**************************************************************************************************************************) + +(** +* retrieves the binary version of this library. +* +* @param[out] pMajor - returns the major version of this library +* @param[out] pMinor - returns the minor version of this library +* @param[out] pMicro - returns the micro version of this library +* @return error code or 0 (success) +*) +function rtti_getversion(pMajor: PCardinal; pMinor: PCardinal; pMicro: PCardinal): TRTTIResult; cdecl; + +(** +* Returns the last error recorded on this object +* +* @param[in] pInstance - Instance Handle +* @param[in] nErrorMessageBufferSize - size of the buffer (including trailing 0) +* @param[out] pErrorMessageNeededChars - will be filled with the count of the written bytes, or needed buffer size. +* @param[out] pErrorMessageBuffer - buffer of Message of the last error, may be NULL +* @param[out] pHasError - Is there a last error to query +* @return error code or 0 (success) +*) +function rtti_getlasterror(pInstance: TRTTIHandle; nErrorMessageBufferSize: Cardinal; pErrorMessageNeededChars: PCardinal; pErrorMessageBuffer: PAnsiChar; pHasError: PByte): TRTTIResult; cdecl; + +(** +* Releases shared ownership of an Instance +* +* @param[in] pInstance - Instance Handle +* @return error code or 0 (success) +*) +function rtti_releaseinstance(pInstance: TRTTIHandle): TRTTIResult; cdecl; + +(** +* Acquires shared ownership of an Instance +* +* @param[in] pInstance - Instance Handle +* @return error code or 0 (success) +*) +function rtti_acquireinstance(pInstance: TRTTIHandle): TRTTIResult; cdecl; + +(** +* Injects an imported component for usage within this component +* +* @param[in] pNameSpace - NameSpace of the injected component +* @param[in] pSymbolAddressMethod - Address of the SymbolAddressMethod of the injected component +* @return error code or 0 (success) +*) +function rtti_injectcomponent(pNameSpace: PAnsiChar; pSymbolAddressMethod: Pointer): TRTTIResult; cdecl; + +(** +* Returns the address of the SymbolLookupMethod +* +* @param[out] pSymbolLookupMethod - Address of the SymbolAddressMethod +* @return error code or 0 (success) +*) +function rtti_getsymbollookupmethod(pSymbolLookupMethod: PPointer): TRTTIResult; cdecl; + +(** +* Create a new zoo with animals +* +* @param[out] pInstance - +* @return error code or 0 (success) +*) +function rtti_createzoo(pInstance: PRTTIHandle): TRTTIResult; cdecl; + + +(************************************************************************************************************************* + Function table lookup implementation +**************************************************************************************************************************) + +function _rtti_getprocaddress_internal(pProcName: PAnsiChar; out ppProcAddress: Pointer): TRTTIResult cdecl; + +implementation + +function rtti_base_classtypeid(pBase: TRTTIHandle; pClassTypeId: PQWord): TRTTIResult; cdecl; +var + ResultClassTypeId: QWord; + ObjectBase: TObject; + IntfBase: IRTTIBase; +begin + try + if not Assigned(pClassTypeId) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + if not Assigned(pBase) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + + ObjectBase := TObject(pBase); + if Supports(ObjectBase, IRTTIBase) then begin + IntfBase := ObjectBase as IRTTIBase; + ResultClassTypeId := IntfBase.ClassTypeId(); + + pClassTypeId^ := ResultClassTypeId; + end else + raise ERTTIException.Create(RTTI_ERROR_INVALIDCAST); + + Result := RTTI_SUCCESS; + except + On E: ERTTIException do begin + Result := HandleRTTIException(ObjectBase , E); + end; + On E: Exception do begin + Result := HandleStdException(ObjectBase , E); + end + else begin + Result := HandleUnhandledException(ObjectBase); + end; + end; +end; + +function rtti_animal_name(pAnimal: TRTTIHandle; nResultBufferSize: Cardinal; pResultNeededChars: PCardinal; pResultBuffer: PAnsiChar): TRTTIResult; cdecl; +var + ResultResult: String; + LenResult: Cardinal; + ObjectAnimal: TObject; + IntfAnimal: IRTTIAnimal; +begin + try + if ((not Assigned(pResultBuffer)) and (not Assigned(pResultNeededChars))) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + if not Assigned(pAnimal) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + + ObjectAnimal := TObject(pAnimal); + if Supports(ObjectAnimal, IRTTIAnimal) then begin + IntfAnimal := ObjectAnimal as IRTTIAnimal; + ResultResult := IntfAnimal.Name(); + + LenResult := Length(ResultResult); + if Assigned(pResultNeededChars) then + pResultNeededChars^ := LenResult + 1; + if Assigned(pResultBuffer) then begin + if (LenResult >= nResultBufferSize) then + raise ERTTIException.Create(RTTI_ERROR_BUFFERTOOSMALL); + Move(PAnsiChar(ResultResult)^, pResultBuffer^, LenResult); + pResultBuffer[LenResult] := Char(0); + end; + end else + raise ERTTIException.Create(RTTI_ERROR_INVALIDCAST); + + Result := RTTI_SUCCESS; + except + On E: ERTTIException do begin + Result := HandleRTTIException(ObjectAnimal , E); + end; + On E: Exception do begin + Result := HandleStdException(ObjectAnimal , E); + end + else begin + Result := HandleUnhandledException(ObjectAnimal); + end; + end; +end; + +function rtti_tiger_roar(pTiger: TRTTIHandle): TRTTIResult; cdecl; +var + ObjectTiger: TObject; + IntfTiger: IRTTITiger; +begin + try + if not Assigned(pTiger) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + + ObjectTiger := TObject(pTiger); + if Supports(ObjectTiger, IRTTITiger) then begin + IntfTiger := ObjectTiger as IRTTITiger; + IntfTiger.Roar(); + + end else + raise ERTTIException.Create(RTTI_ERROR_INVALIDCAST); + + Result := RTTI_SUCCESS; + except + On E: ERTTIException do begin + Result := HandleRTTIException(ObjectTiger , E); + end; + On E: Exception do begin + Result := HandleStdException(ObjectTiger , E); + end + else begin + Result := HandleUnhandledException(ObjectTiger); + end; + end; +end; + +function rtti_animaliterator_getnextanimal(pAnimalIterator: TRTTIHandle; pAnimal: PRTTIHandle): TRTTIResult; cdecl; +var + ResultAnimal: TObject; + ObjectAnimalIterator: TObject; + IntfAnimalIterator: IRTTIAnimalIterator; +begin + try + if not Assigned(pAnimal) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + if not Assigned(pAnimalIterator) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + + ObjectAnimalIterator := TObject(pAnimalIterator); + if Supports(ObjectAnimalIterator, IRTTIAnimalIterator) then begin + IntfAnimalIterator := ObjectAnimalIterator as IRTTIAnimalIterator; + ResultAnimal := IntfAnimalIterator.GetNextAnimal(); + + pAnimal^ := ResultAnimal; + end else + raise ERTTIException.Create(RTTI_ERROR_INVALIDCAST); + + Result := RTTI_SUCCESS; + except + On E: ERTTIException do begin + Result := HandleRTTIException(ObjectAnimalIterator , E); + end; + On E: Exception do begin + Result := HandleStdException(ObjectAnimalIterator , E); + end + else begin + Result := HandleUnhandledException(ObjectAnimalIterator); + end; + end; +end; + +function rtti_zoo_iterator(pZoo: TRTTIHandle; pIterator: PRTTIHandle): TRTTIResult; cdecl; +var + ResultIterator: TObject; + ObjectZoo: TObject; + IntfZoo: IRTTIZoo; +begin + try + if not Assigned(pIterator) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + if not Assigned(pZoo) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + + ObjectZoo := TObject(pZoo); + if Supports(ObjectZoo, IRTTIZoo) then begin + IntfZoo := ObjectZoo as IRTTIZoo; + ResultIterator := IntfZoo.Iterator(); + + pIterator^ := ResultIterator; + end else + raise ERTTIException.Create(RTTI_ERROR_INVALIDCAST); + + Result := RTTI_SUCCESS; + except + On E: ERTTIException do begin + Result := HandleRTTIException(ObjectZoo , E); + end; + On E: Exception do begin + Result := HandleStdException(ObjectZoo , E); + end + else begin + Result := HandleUnhandledException(ObjectZoo); + end; + end; +end; + +function rtti_getversion(pMajor: PCardinal; pMinor: PCardinal; pMicro: PCardinal): TRTTIResult; cdecl; +begin + try + if (not Assigned(pMajor)) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + + if (not Assigned(pMinor)) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + + if (not Assigned(pMicro)) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + + + TRTTIWrapper.GetVersion(pMajor^, pMinor^, pMicro^); + + Result := RTTI_SUCCESS; + except + On E: ERTTIException do begin + Result := E.ErrorCode; + end + else begin + Result := RTTI_ERROR_GENERICEXCEPTION; + end + end; +end; + +function rtti_getlasterror(pInstance: TRTTIHandle; nErrorMessageBufferSize: Cardinal; pErrorMessageNeededChars: PCardinal; pErrorMessageBuffer: PAnsiChar; pHasError: PByte): TRTTIResult; cdecl; +var + ObjectInstance: TObject; + ResultErrorMessage: String; + LenErrorMessage: Cardinal; + ResultHasError: Boolean; +begin + try + ObjectInstance := TObject(pInstance); + if (not Supports(ObjectInstance, IRTTIBase)) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDCAST); + + if ((not Assigned(pErrorMessageBuffer)) and (not Assigned(pErrorMessageNeededChars))) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + if not Assigned(pHasError) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + + ResultHasError := TRTTIWrapper.GetLastError(ObjectInstance, ResultErrorMessage); + + LenErrorMessage := Length(ResultErrorMessage); + if Assigned(pErrorMessageNeededChars) then + pErrorMessageNeededChars^ := LenErrorMessage + 1; + if Assigned(pErrorMessageBuffer) then begin + if (LenErrorMessage >= nErrorMessageBufferSize) then + raise ERTTIException.Create(RTTI_ERROR_BUFFERTOOSMALL); + Move(PAnsiChar(ResultErrorMessage)^, pErrorMessageBuffer^, LenErrorMessage); + pErrorMessageBuffer[LenErrorMessage] := Char(0); + end; + pHasError^ := Ord(ResultHasError); + Result := RTTI_SUCCESS; + except + On E: ERTTIException do begin + Result := E.ErrorCode; + end + else begin + Result := RTTI_ERROR_GENERICEXCEPTION; + end + end; +end; + +function rtti_releaseinstance(pInstance: TRTTIHandle): TRTTIResult; cdecl; +var + ObjectInstance: TObject; +begin + try + ObjectInstance := TObject(pInstance); + if (not Supports(ObjectInstance, IRTTIBase)) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDCAST); + + + TRTTIWrapper.ReleaseInstance(ObjectInstance); + + Result := RTTI_SUCCESS; + except + On E: ERTTIException do begin + Result := E.ErrorCode; + end + else begin + Result := RTTI_ERROR_GENERICEXCEPTION; + end + end; +end; + +function rtti_acquireinstance(pInstance: TRTTIHandle): TRTTIResult; cdecl; +var + ObjectInstance: TObject; +begin + try + ObjectInstance := TObject(pInstance); + if (not Supports(ObjectInstance, IRTTIBase)) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDCAST); + + + TRTTIWrapper.AcquireInstance(ObjectInstance); + + Result := RTTI_SUCCESS; + except + On E: ERTTIException do begin + Result := E.ErrorCode; + end + else begin + Result := RTTI_ERROR_GENERICEXCEPTION; + end + end; +end; + +function rtti_injectcomponent(pNameSpace: PAnsiChar; pSymbolAddressMethod: Pointer): TRTTIResult; cdecl; +var + ANameSpaceFound: boolean; +begin + try + if (not Assigned(pNameSpace)) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + + if not ANameSpaceFound then + raise ERTTIException.Create(RTTI_ERROR_COULDNOTLOADLIBRARY); + Result := RTTI_SUCCESS; + except + On E: ERTTIException do begin + Result := E.ErrorCode; + end + else begin + Result := RTTI_ERROR_GENERICEXCEPTION; + end + end; +end; + +function rtti_getsymbollookupmethod(pSymbolLookupMethod: PPointer): TRTTIResult; cdecl; +begin + try + if not Assigned(pSymbolLookupMethod) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + + pSymbolLookupMethod^ := @_rtti_getprocaddress_internal; + Result := RTTI_SUCCESS; + except + On E: ERTTIException do begin + Result := E.ErrorCode; + end + else begin + Result := RTTI_ERROR_GENERICEXCEPTION; + end + end; +end; + +function rtti_createzoo(pInstance: PRTTIHandle): TRTTIResult; cdecl; +var + ResultInstance: TObject; +begin + try + if not Assigned(pInstance) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + + ResultInstance := TRTTIWrapper.CreateZoo(); + + pInstance^ := ResultInstance; + Result := RTTI_SUCCESS; + except + On E: ERTTIException do begin + Result := E.ErrorCode; + end + else begin + Result := RTTI_ERROR_GENERICEXCEPTION; + end + end; +end; + + + +(************************************************************************************************************************* + Function table lookup implementation +**************************************************************************************************************************) + +function _rtti_getprocaddress_internal(pProcName: PAnsiChar; out ppProcAddress: Pointer): TRTTIResult cdecl; + +begin + result := RTTI_SUCCESS; + ppProcAddress := nil; + + if (pProcName = 'rtti_base_classtypeid') then + ppProcAddress := @rtti_base_classtypeid + else if (pProcName = 'rtti_animal_name') then + ppProcAddress := @rtti_animal_name + else if (pProcName = 'rtti_tiger_roar') then + ppProcAddress := @rtti_tiger_roar + else if (pProcName = 'rtti_animaliterator_getnextanimal') then + ppProcAddress := @rtti_animaliterator_getnextanimal + else if (pProcName = 'rtti_zoo_iterator') then + ppProcAddress := @rtti_zoo_iterator + else if (pProcName = 'rtti_getversion') then + ppProcAddress := @rtti_getversion + else if (pProcName = 'rtti_getlasterror') then + ppProcAddress := @rtti_getlasterror + else if (pProcName = 'rtti_releaseinstance') then + ppProcAddress := @rtti_releaseinstance + else if (pProcName = 'rtti_acquireinstance') then + ppProcAddress := @rtti_acquireinstance + else if (pProcName = 'rtti_injectcomponent') then + ppProcAddress := @rtti_injectcomponent + else if (pProcName = 'rtti_getsymbollookupmethod') then + ppProcAddress := @rtti_getsymbollookupmethod + else if (pProcName = 'rtti_createzoo') then + ppProcAddress := @rtti_createzoo + else + result := RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; +end; + +end. + diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_interfaces.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_interfaces.pas new file mode 100644 index 00000000..baf32788 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_interfaces.pas @@ -0,0 +1,141 @@ +(*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Pascal interface definition file in order to allow easy +development of RTTI. The functions in this file need to be implemented. It needs to be generated only once. + +Interface version: 1.0.0 + +*) + +{$MODE DELPHI} +{$INTERFACES CORBA} +unit rtti_interfaces; + +interface + +uses + rtti_types, + Classes, + sysutils; + + +type + +(************************************************************************************************************************* + Interface definition for Base +**************************************************************************************************************************) + +IRTTIBase = interface + ['{52FDFC07-2182-454F-963F-5F0F9A621D72}'] + + function GetLastErrorMessage(out AErrorMessage: String): Boolean; + procedure ClearErrorMessages(); + procedure RegisterErrorMessage(const AErrorMessage: String); + procedure IncRefCount(); + function DecRefCount(): Boolean; + function ClassTypeId(): QWord; +end; + + +(************************************************************************************************************************* + Interface definition for Animal +**************************************************************************************************************************) + +IRTTIAnimal = interface(IRTTIBase) + ['{9566C74D-1003-4C4D-BBBB-0407D1E2C649}'] + + function Name(): String; +end; + + +(************************************************************************************************************************* + Interface definition for Mammal +**************************************************************************************************************************) + +IRTTIMammal = interface(IRTTIAnimal) + ['{81855AD8-681D-4D86-91E9-1E00167939CB}'] + +end; + + +(************************************************************************************************************************* + Interface definition for Reptile +**************************************************************************************************************************) + +IRTTIReptile = interface(IRTTIAnimal) + ['{6694D2C4-22AC-4208-A007-2939487F6999}'] + +end; + + +(************************************************************************************************************************* + Interface definition for Giraffe +**************************************************************************************************************************) + +IRTTIGiraffe = interface(IRTTIMammal) + ['{EB9D18A4-4784-445D-87F3-C67CF22746E9}'] + +end; + + +(************************************************************************************************************************* + Interface definition for Tiger +**************************************************************************************************************************) + +IRTTITiger = interface(IRTTIMammal) + ['{95AF5A25-3679-41BA-A2FF-6CD471C483F1}'] + + procedure Roar(); +end; + + +(************************************************************************************************************************* + Interface definition for Snake +**************************************************************************************************************************) + +IRTTISnake = interface(IRTTIReptile) + ['{5FB90BAD-B37C-4821-B6D9-5526A41A9504}'] + +end; + + +(************************************************************************************************************************* + Interface definition for Turtle +**************************************************************************************************************************) + +IRTTITurtle = interface(IRTTIReptile) + ['{680B4E7C-8B76-4A1B-9D49-D4955C848621}'] + +end; + + +(************************************************************************************************************************* + Interface definition for AnimalIterator +**************************************************************************************************************************) + +IRTTIAnimalIterator = interface(IRTTIBase) + ['{6325253F-EC73-4DD7-A9E2-8BF921119C16}'] + + function GetNextAnimal(): TObject; +end; + + +(************************************************************************************************************************* + Interface definition for Zoo +**************************************************************************************************************************) + +IRTTIZoo = interface(IRTTIBase) + ['{0F070244-8615-4BDA-8831-3F6A8EB668D2}'] + + function Iterator(): TObject; +end; + +implementation + +end. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_types.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_types.pas new file mode 100644 index 00000000..c901da0c --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_types.pas @@ -0,0 +1,66 @@ +(*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Pascal type definition file in order to allow easy +development of RTTI. The functions in this file need to be implemented. It needs to be generated only once. + +Interface version: 1.0.0 + +*) + +{$MODE DELPHI} +unit rtti_types; + +interface + +uses + Classes, + sysutils; + +(************************************************************************************************************************* + Version definition for RTTI +**************************************************************************************************************************) + +const + RTTI_VERSION_MAJOR = 1; + RTTI_VERSION_MINOR = 0; + RTTI_VERSION_MICRO = 0; + RTTI_VERSION_PRERELEASEINFO = ''; + RTTI_VERSION_BUILDINFO = ''; + + +(************************************************************************************************************************* + General type definitions +**************************************************************************************************************************) + +type + TRTTIResult = Cardinal; + TRTTIHandle = Pointer; + + PRTTIResult = ^TRTTIResult; + PRTTIHandle = ^TRTTIHandle; + +(************************************************************************************************************************* + Error Constants for RTTI +**************************************************************************************************************************) + +const + RTTI_SUCCESS = 0; + RTTI_ERROR_NOTIMPLEMENTED = 1; + RTTI_ERROR_INVALIDPARAM = 2; + RTTI_ERROR_INVALIDCAST = 3; + RTTI_ERROR_BUFFERTOOSMALL = 4; + RTTI_ERROR_GENERICEXCEPTION = 5; + RTTI_ERROR_COULDNOTLOADLIBRARY = 6; + RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT = 7; + RTTI_ERROR_INCOMPATIBLEBINARYVERSION = 8; + + +implementation + +end. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl.pas new file mode 100644 index 00000000..e3e3c44c --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl.pas @@ -0,0 +1,91 @@ +(*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Pascal implementation file in order to allow easy +development of RTTI. It needs to be generated only once. + +Interface version: 1.0.0 + +*) + +{$MODE DELPHI} +Unit rtti_impl; + +interface + +uses + rtti_types, + rtti_exception, + rtti_interfaces, + rtti_impl_zoo, + rtti_impl_base, + rtti_impl_animal, + rtti_impl_giraffe, + rtti_impl_mammal, + rtti_impl_reptile, + rtti_impl_snake, + rtti_impl_tiger, + rtti_impl_turtle, + Classes, + sysutils; + +type + TRTTIWrapper = class(TObject) + public + class procedure GetVersion(out AMajor: Cardinal; out AMinor: Cardinal; out AMicro: Cardinal); + class function GetLastError(AInstance: TObject; out AErrorMessage: String): Boolean; + class procedure ReleaseInstance(AInstance: TObject); + class procedure AcquireInstance(AInstance: TObject); + class function CreateZoo(): TObject; + end; + + +implementation + +class procedure TRTTIWrapper.GetVersion(out AMajor: Cardinal; out AMinor: Cardinal; out AMicro: Cardinal); +begin + AMajor := RTTI_VERSION_MAJOR; + AMinor := RTTI_VERSION_MINOR; + AMicro := RTTI_VERSION_MICRO; +end; + +class function TRTTIWrapper.GetLastError(AInstance: TObject; out AErrorMessage: String): Boolean; +begin + if AInstance <> nil then + begin + Result := (AInstance as TRTTIBase).GetLastErrorMessage(AErrorMessage); + end; +end; + +class procedure TRTTIWrapper.ReleaseInstance(AInstance: TObject); +begin + (AInstance as IRTTIBase).DecRefCount(); +end; + +class procedure TRTTIWrapper.AcquireInstance(AInstance: TObject); +begin + (AInstance as IRTTIBase).IncRefCount(); +end; + +class function TRTTIWrapper.CreateZoo(): TObject; +begin + Result := TRTTIZoo.Create(); + (Result as TRTTIZoo).Animals.Add(TRTTIGiraffe.Create('Gerald Giraffe')); + (Result as TRTTIZoo).Animals.Add(TRTTITiger.Create('Timmy Tiger')); + (Result as TRTTIZoo).Animals.Add(TRTTITiger.Create('Tony Tiger')); + (Result as TRTTIZoo).Animals.Add(TRTTISnake.Create('Sebastian Snake')); + (Result as TRTTIZoo).Animals.Add(TRTTITurtle.Create('Tobias Turtle')); + (Result as TRTTIZoo).Animals.Add(TRTTITurtle.Create('Theo Turtle')); + (Result as TRTTIZoo).Animals.Add(TRTTITurtle.Create('Tomás Turtle')); + (Result as TRTTIZoo).Animals.Add(TRTTISnake.Create('Slytherin Snake')); + (Result as TRTTIZoo).Animals.Add(TRTTITiger.Create('Travis Tiger')); + (Result as TRTTIZoo).Animals.Add(TRTTIGiraffe.Create('Gary Giraffe')); +end; + + +end. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animal.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animal.pas new file mode 100644 index 00000000..8db65ce8 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animal.pas @@ -0,0 +1,59 @@ +(*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of TRTTIAnimal + +*) + +{$MODE DELPHI} +unit rtti_impl_animal; + +interface + +uses + rtti_types, + rtti_interfaces, + rtti_exception, + rtti_impl_base, + Classes, + sysutils; + +type + TRTTIAnimal = class(TRTTIBase, IRTTIAnimal) + private + + protected + m_sName: String; + public + function ClassTypeId(): QWord; Override; + function Name(): String; + constructor Create(Name: String); + destructor Done; + end; + +implementation + +function TRTTIAnimal.ClassTypeId(): QWord; +begin + Result := $8B40467DA6D327AF; // First 64 bits of SHA1 of a string: "RTTI::Animal" +end; + +function TRTTIAnimal.Name(): String; +begin + Result := m_sName; +end; + +constructor TRTTIAnimal.Create(Name: String); +begin + self.m_sName := Name; +end; + +destructor TRTTIAnimal.Done; +begin + writeln('"Delete ', Name); +end; + +end. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animaliterator.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animaliterator.pas new file mode 100644 index 00000000..8c89c98c --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animaliterator.pas @@ -0,0 +1,61 @@ +(*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of TRTTIAnimalIterator + +*) + +{$MODE DELPHI} +unit rtti_impl_animaliterator; + +interface + +uses + rtti_types, + rtti_interfaces, + rtti_exception, + rtti_impl_base, + rtti_impl_animal, + Classes, + sysutils; + +type + TRTTIAnimalIterator = class(TRTTIBase, IRTTIAnimalIterator) + private + protected + Animals: TList; + Index: integer; + public + function ClassTypeId(): QWord; Override; + + constructor Create(Animals: TList); + function GetNextAnimal(): TObject; + protected + end; + +implementation + +function TRTTIAnimalIterator.ClassTypeId(): QWord; +begin + Result := $F1917FE6BBE77831; // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" +end; + +constructor TRTTIAnimalIterator.Create(Animals: TList); +begin + self.Animals := Animals; + Index := 0; +end; + +function TRTTIAnimalIterator.GetNextAnimal(): TObject; +begin + if Index < Animals.Count then + Result := Animals[Index] + else + Result := nil; + Index := Index + 1; +end; + +end. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_base.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_base.pas new file mode 100644 index 00000000..945931c5 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_base.pas @@ -0,0 +1,90 @@ +(*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of TRTTIBase + +*) + +{$MODE DELPHI} +unit rtti_impl_base; + +interface + +uses + rtti_types, + rtti_interfaces, + rtti_exception, + Classes, + sysutils; + +type + TRTTIBase = class(TObject, IRTTIBase) + private + FMessages: TStringList; + FReferenceCount: integer; + + protected + + public + constructor Create(); + destructor Destroy(); override; + function GetLastErrorMessage(out AErrorMessage: String): Boolean; + procedure ClearErrorMessages(); + procedure RegisterErrorMessage(const AErrorMessage: String); + procedure IncRefCount(); + function DecRefCount(): Boolean; + function ClassTypeId(): QWord; Virtual; Abstract; + end; + +implementation + +constructor TRTTIBase.Create(); +begin + inherited Create(); + FMessages := TStringList.Create(); + FReferenceCount := 1; +end; + +destructor TRTTIBase.Destroy(); +begin + FreeAndNil(FMessages); + inherited Destroy(); +end; + +function TRTTIBase.GetLastErrorMessage(out AErrorMessage: String): Boolean; +begin + result := (FMessages.Count>0); + if (result) then + AErrorMessage := FMessages[FMessages.Count-1]; +end; + +procedure TRTTIBase.ClearErrorMessages(); +begin + FMessages.Clear(); +end; + +procedure TRTTIBase.RegisterErrorMessage(const AErrorMessage: String); +begin + FMessages.Add(AErrorMessage); +end; + +procedure TRTTIBase.IncRefCount(); +begin + inc(FReferenceCount); +end; + +function TRTTIBase.DecRefCount(): Boolean; +begin + dec(FReferenceCount); + if (FReferenceCount = 0) then begin + self.Destroy(); + result := true; + end + else + result := false; +end; + +end. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_giraffe.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_giraffe.pas new file mode 100644 index 00000000..b9ce348a --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_giraffe.pas @@ -0,0 +1,41 @@ +(*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of TRTTIGiraffe + +*) + +{$MODE DELPHI} +unit rtti_impl_giraffe; + +interface + +uses + rtti_types, + rtti_interfaces, + rtti_exception, + rtti_impl_mammal, + Classes, + sysutils; + +type + TRTTIGiraffe = class(TRTTIMammal, IRTTIGiraffe) + private + + protected + + public + function ClassTypeId(): QWord; Override; + end; + +implementation + +function TRTTIGiraffe.ClassTypeId(): QWord; +begin + Result := $9751971BD2C2D958; // First 64 bits of SHA1 of a string: "RTTI::Giraffe" +end; + +end. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_mammal.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_mammal.pas new file mode 100644 index 00000000..58578b7b --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_mammal.pas @@ -0,0 +1,41 @@ +(*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of TRTTIMammal + +*) + +{$MODE DELPHI} +unit rtti_impl_mammal; + +interface + +uses + rtti_types, + rtti_interfaces, + rtti_exception, + rtti_impl_animal, + Classes, + sysutils; + +type + TRTTIMammal = class(TRTTIAnimal, IRTTIMammal) + private + + protected + + public + function ClassTypeId(): QWord; Override; + end; + +implementation + +function TRTTIMammal.ClassTypeId(): QWord; +begin + Result := $BC9D5FA7750C1020; // First 64 bits of SHA1 of a string: "RTTI::Mammal" +end; + +end. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_reptile.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_reptile.pas new file mode 100644 index 00000000..0ba02d7b --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_reptile.pas @@ -0,0 +1,41 @@ +(*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of TRTTIReptile + +*) + +{$MODE DELPHI} +unit rtti_impl_reptile; + +interface + +uses + rtti_types, + rtti_interfaces, + rtti_exception, + rtti_impl_animal, + Classes, + sysutils; + +type + TRTTIReptile = class(TRTTIAnimal, IRTTIReptile) + private + + protected + + public + function ClassTypeId(): QWord; Override; + end; + +implementation + +function TRTTIReptile.ClassTypeId(): QWord; +begin + Result := $6756AA8EA5802EC3; // First 64 bits of SHA1 of a string: "RTTI::Reptile" +end; + +end. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_snake.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_snake.pas new file mode 100644 index 00000000..783ae5c2 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_snake.pas @@ -0,0 +1,41 @@ +(*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of TRTTISnake + +*) + +{$MODE DELPHI} +unit rtti_impl_snake; + +interface + +uses + rtti_types, + rtti_interfaces, + rtti_exception, + rtti_impl_reptile, + Classes, + sysutils; + +type + TRTTISnake = class(TRTTIReptile, IRTTISnake) + private + + protected + + public + function ClassTypeId(): QWord; Override; + end; + +implementation + +function TRTTISnake.ClassTypeId(): QWord; +begin + Result := $5F6826EF909803B2; // First 64 bits of SHA1 of a string: "RTTI::Snake" +end; + +end. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_tiger.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_tiger.pas new file mode 100644 index 00000000..91888ae2 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_tiger.pas @@ -0,0 +1,47 @@ +(*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of TRTTITiger + +*) + +{$MODE DELPHI} +unit rtti_impl_tiger; + +interface + +uses + rtti_types, + rtti_interfaces, + rtti_exception, + rtti_impl_mammal, + Classes, + sysutils; + +type + TRTTITiger = class(TRTTIMammal, IRTTITiger) + private + + protected + + public + function ClassTypeId(): QWord; Override; + procedure Roar(); + end; + +implementation + +function TRTTITiger.ClassTypeId(): QWord; +begin + Result := $08D007E7B5F7BAF4; // First 64 bits of SHA1 of a string: "RTTI::Tiger" +end; + +procedure TRTTITiger.Roar(); +begin + writeln('ROAAAAARRRRR!!'); +end; + +end. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_turtle.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_turtle.pas new file mode 100644 index 00000000..6464f76b --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_turtle.pas @@ -0,0 +1,41 @@ +(*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of TRTTITurtle + +*) + +{$MODE DELPHI} +unit rtti_impl_turtle; + +interface + +uses + rtti_types, + rtti_interfaces, + rtti_exception, + rtti_impl_reptile, + Classes, + sysutils; + +type + TRTTITurtle = class(TRTTIReptile, IRTTITurtle) + private + + protected + + public + function ClassTypeId(): QWord; Override; + end; + +implementation + +function TRTTITurtle.ClassTypeId(): QWord; +begin + Result := $8E551B208A2E8321; // First 64 bits of SHA1 of a string: "RTTI::Turtle" +end; + +end. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_zoo.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_zoo.pas new file mode 100644 index 00000000..995667f1 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_zoo.pas @@ -0,0 +1,56 @@ +(*++ + +Copyright (C) 2020 ADSK + +All rights reserved. + +Abstract: This is the class declaration of TRTTIZoo + +*) + +{$MODE DELPHI} +unit rtti_impl_zoo; + +interface + +uses + rtti_types, + rtti_interfaces, + rtti_exception, + rtti_impl_base, + rtti_impl_animal, + rtti_impl_animaliterator, + Classes, + sysutils; + +type + TRTTIZoo = class(TRTTIBase, IRTTIZoo) + private + + protected + + public + Animals: TList; + constructor Create(); + function ClassTypeId(): QWord; Override; + function Iterator(): TObject; + end; + +implementation + +function TRTTIZoo.ClassTypeId(): QWord; +begin + Result := $2262ABE80A5E7878; // First 64 bits of SHA1 of a string: "RTTI::Zoo" +end; + +constructor TRTTIZoo.Create(); +begin + Animals := TList.Create(); +end; + +function TRTTIZoo.Iterator(): TObject; +begin + Result := TRTTIAnimalIterator.Create(Animals); +end; + +end. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/rtti.def b/Examples/RTTI/RTTI_component/Implementations/Pascal/rtti.def new file mode 100644 index 00000000..36fbb276 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/rtti.def @@ -0,0 +1,13 @@ +EXPORTS +rtti_getversion +rtti_getlasterror +rtti_releaseinstance +rtti_acquireinstance +rtti_injectcomponent +rtti_getsymbollookupmethod +rtti_createzoo +rtti_base_classtypeid +rtti_animal_name +rtti_tiger_roar +rtti_animaliterator_getnextanimal +rtti_zoo_iterator diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/rtti.lpi b/Examples/RTTI/RTTI_component/Implementations/Pascal/rtti.lpi new file mode 100644 index 00000000..7b6c09b9 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/rtti.lpi @@ -0,0 +1,113 @@ +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectOptions> + <Version Value="10"/> + <PathDelim Value="\"/> + <General> + <Flags> + <MainUnitHasCreateFormStatements Value="False" /> + <MainUnitHasTitleStatement Value="False" /> + <MainUnitHasScaledStatement Value="False" /> + </Flags> + <SessionStorage Value="InProjectDir" /> + <MainUnit Value="0"/> + <Title Value="RTTI" /> + <UseAppBundle Value="False" /> + <ResourceType Value="res" /> + </General> + <BuildModes Count="2"> + <Item1 Name="Release" Default="True"/> + <Item2 Name="Debug"> + <CompilerOptions> + <Version Value="11" /> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\Release\projectrtti"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <OtherUnitFiles Value="Stub;Interfaces"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <IncludeAssertionCode Value="True"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <RelocatableUnit Value="True" /> + </CodeGeneration> + <Linking> + <Debugging> + <UseExternalDbgSyms Value="True"/> + </Debugging> + <Options> + <ExecutableType Value="Library"/> + </Options> + </Linking> + </CompilerOptions> + </Item2> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + </PublishOptions> + <RunParams> + <local> + <FormatVersion Value="1"/> + </local> + </RunParams> + <Units Count="2"> + <Unit0> + <Filename Value="Interfaces\rtti.lpr"/> + <IsPartOfProject Value="True"/> + </Unit0> + <Unit1> + <Filename Value="Stub\rtti.pas"/> + <IsPartOfProject Value="True"/> + </Unit1> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\Release\rtti"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <OtherUnitFiles Value="Stub;Interfaces"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <IncludeAssertionCode Value="True"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <RelocatableUnit Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <StripSymbols Value="True"/> + <UseExternalDbgSyms Value="True"/> + </Debugging> + <Options> + <ExecutableType Value="Library"/> + </Options> + </Linking> + </CompilerOptions> + <Debugging> + <Exceptions Count="3"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + </Exceptions> + </Debugging> +</CONFIG> + From 8b874bded6caafc713dac0f6a0c61675f2213b23 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 18 Oct 2021 19:48:50 -0700 Subject: [PATCH 037/143] Tune Pascal project --- .../RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpr | 7 ++----- .../RTTI/RTTI_component/Implementations/Pascal/rtti.lpi | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpr b/Examples/RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpr index d7907356..c282b039 100644 --- a/Examples/RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpr +++ b/Examples/RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpr @@ -47,11 +47,8 @@ procedure TRTTI_Example.TestRTTI(); ALibPath: string; begin writeln('loading DLL'); - ALibPath := '/Users/anpiloa/git/AutomaticComponentToolkit/Examples/RTTI/RTTI_component/Implementations/Pascal/bin/x86_64-darwin/Release'; // TODO add the location of the shared library binary here - ARTTIWrapper := TRTTIWrapper.Create(ALibPath + '/' + 'libprojectrtti.dylib'); // TODO add the extension of the shared library file here - - //ALibPath := '/Users/anpiloa/git/AutomaticComponentToolkit/Examples/RTTI/build-lib/'; // TODO add the location of the shared library binary here - //ARTTIWrapper := TRTTIWrapper.Create(ALibPath + '/' + 'rtti.dylib'); // TODO add the extension of the shared library file here + ALibPath := '.'; // TODO add the location of the shared library binary here + ARTTIWrapper := TRTTIWrapper.Create(ALibPath + '/' + 'rtti.'); // TODO add the extension of the shared library file here try writeln('loading DLL Done'); diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/rtti.lpi b/Examples/RTTI/RTTI_component/Implementations/Pascal/rtti.lpi index 7b6c09b9..c11ac65c 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Pascal/rtti.lpi +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/rtti.lpi @@ -22,7 +22,7 @@ <Version Value="11" /> <PathDelim Value="\"/> <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\Release\projectrtti"/> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\Release\rtti"/> </Target> <SearchPaths> <IncludeFiles Value="$(ProjOutDir)"/> From fde00e80f91719332dee9d122f9a63aada5456be Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <anpilog@gmail.com> Date: Mon, 18 Oct 2021 19:52:19 -0700 Subject: [PATCH 038/143] Fix year --- Examples/RTTI/RTTI.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/RTTI/RTTI.xml b/Examples/RTTI/RTTI.xml index 2d5bb210..f60eb969 100644 --- a/Examples/RTTI/RTTI.xml +++ b/Examples/RTTI/RTTI.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<component xmlns="http://schemas.autodesk.com/netfabb/automaticcomponenttoolkit/2018" libraryname="RTTI" namespace="RTTI" copyright="ADSK" year="2020" basename="rtti" version="1.0.0"> +<component xmlns="http://schemas.autodesk.com/netfabb/automaticcomponenttoolkit/2018" libraryname="RTTI" namespace="RTTI" copyright="ADSK" year="2021" basename="rtti" version="1.0.0"> <!-- class="Namespace:*" becomes aware of this.--> From af2f664b93f97f318542fd88aa8d998a0ada8e0b Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <anpilog@gmail.com> Date: Mon, 18 Oct 2021 19:56:55 -0700 Subject: [PATCH 039/143] Update year --- Examples/RTTI/RTTI_component/license.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/RTTI/RTTI_component/license.txt b/Examples/RTTI/RTTI_component/license.txt index 3eefc675..fa8920cb 100644 --- a/Examples/RTTI/RTTI_component/license.txt +++ b/Examples/RTTI/RTTI_component/license.txt @@ -1,4 +1,4 @@ -Copyright (C) 2020 ADSK +Copyright (C) 2021 ADSK All rights reserved. From 6a5a8c0463a1de319a5fc6bd4923db66d0760144 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Wed, 20 Oct 2021 15:08:31 -0700 Subject: [PATCH 040/143] Cast hex numbers to QWord and fix a warning --- Source/buildbindingpascal.go | 2 +- Source/buildimplementationpascal.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/buildbindingpascal.go b/Source/buildbindingpascal.go index 68b3ab63..15a42b86 100644 --- a/Source/buildbindingpascal.go +++ b/Source/buildbindingpascal.go @@ -438,7 +438,7 @@ func buildDynamicPascalImplementation(component ComponentDefinition, w LanguageW w.Writeln(" case (ClassTypeId) of") for i := 0; i < len(component.Classes); i++ { classTypeId, chashHashString := component.Classes[i].classTypeId(NameSpace) - w.Writeln(" $%016X: begin Obj := T%s%s.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: \"%s\"", classTypeId, strings.ToUpper(NameSpace), component.Classes[i].ClassName, chashHashString) + w.Writeln(" QWord($%016X): begin Obj := T%s%s.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: \"%s\"", classTypeId, strings.ToUpper(NameSpace), component.Classes[i].ClassName, chashHashString) } w.Writeln(" end;") w.Writeln(" if Result = nil then Result := _B.Create(Wrapper, Handle);") diff --git a/Source/buildimplementationpascal.go b/Source/buildimplementationpascal.go index d1bd5b08..71c91620 100644 --- a/Source/buildimplementationpascal.go +++ b/Source/buildimplementationpascal.go @@ -1466,7 +1466,7 @@ func buildPascalStub(component ComponentDefinition, NameSpace string, ClassIdent classTypeId, chashHashString := class.classTypeId(NameSpace) var methodImplementation []string - methodImplementation = append(methodImplementation, fmt.Sprintf("Result := $%016X; // First 64 bits of SHA1 of a string: \"%s\"", classTypeId, chashHashString)) + methodImplementation = append(methodImplementation, fmt.Sprintf("Result := QWord($%016X); // First 64 bits of SHA1 of a string: \"%s\"", classTypeId, chashHashString)) err := writePascalClassMethodDummyStub(component.classTypeIdMethod(), w, NameSpace, class.ClassName, outClassName, false, methodImplementation) if err != nil { From aef8400256e19b4b03d3241ceba4f302d8a7bcc8 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Fri, 22 Oct 2021 12:55:04 -0700 Subject: [PATCH 041/143] Update date --- Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h | 2 +- .../RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp | 2 +- Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_types.hpp | 2 +- Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas | 2 +- Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py | 2 +- .../RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp | 2 +- .../Implementations/Cpp/Interfaces/rtti_interfaceexception.cpp | 2 +- .../Implementations/Cpp/Interfaces/rtti_interfaceexception.hpp | 2 +- .../Implementations/Cpp/Interfaces/rtti_interfaces.hpp | 2 +- .../Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp | 2 +- .../Implementations/Cpp/Interfaces/rtti_types.hpp | 2 +- .../Implementations/Pascal/Interfaces/rtti_exception.pas | 2 +- .../Implementations/Pascal/Interfaces/rtti_exports.pas | 2 +- .../Implementations/Pascal/Interfaces/rtti_interfaces.pas | 2 +- .../Implementations/Pascal/Interfaces/rtti_types.pas | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h index 6a7c182b..0f672975 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h @@ -1,6 +1,6 @@ /*++ -Copyright (C) 2020 ADSK +Copyright (C) 2021 ADSK All rights reserved. diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp index f03b0a01..0ca76c39 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp @@ -1,6 +1,6 @@ /*++ -Copyright (C) 2020 ADSK +Copyright (C) 2021 ADSK All rights reserved. diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_types.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_types.hpp index ef137b36..cc0455f9 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_types.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_types.hpp @@ -1,6 +1,6 @@ /*++ -Copyright (C) 2020 ADSK +Copyright (C) 2021 ADSK All rights reserved. diff --git a/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas b/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas index 1333842e..f9f4d663 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas +++ b/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas @@ -1,7 +1,7 @@ {$IFDEF FPC}{$MODE DELPHI}{$ENDIF} (*++ -Copyright (C) 2020 ADSK +Copyright (C) 2021 ADSK All rights reserved. diff --git a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py index fca2a1e8..1d0d6215 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py +++ b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py @@ -1,6 +1,6 @@ '''++ -Copyright (C) 2020 ADSK +Copyright (C) 2021 ADSK All rights reserved. diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp index 12929685..cffde6e3 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp @@ -1,6 +1,6 @@ /*++ -Copyright (C) 2020 ADSK +Copyright (C) 2021 ADSK All rights reserved. diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaceexception.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaceexception.cpp index 4db45b80..32cff8a8 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaceexception.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaceexception.cpp @@ -1,6 +1,6 @@ /*++ -Copyright (C) 2020 ADSK +Copyright (C) 2021 ADSK All rights reserved. diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaceexception.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaceexception.hpp index a6f4795c..0b153bb9 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaceexception.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaceexception.hpp @@ -1,6 +1,6 @@ /*++ -Copyright (C) 2020 ADSK +Copyright (C) 2021 ADSK All rights reserved. diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp index b957e1e5..bf317fee 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp @@ -1,6 +1,6 @@ /*++ -Copyright (C) 2020 ADSK +Copyright (C) 2021 ADSK All rights reserved. diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp index d38a7539..9d7dbbad 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp @@ -1,6 +1,6 @@ /*++ -Copyright (C) 2020 ADSK +Copyright (C) 2021 ADSK All rights reserved. diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_types.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_types.hpp index ef137b36..cc0455f9 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_types.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_types.hpp @@ -1,6 +1,6 @@ /*++ -Copyright (C) 2020 ADSK +Copyright (C) 2021 ADSK All rights reserved. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exception.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exception.pas index fc3465ff..97825104 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exception.pas +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exception.pas @@ -1,6 +1,6 @@ (*++ -Copyright (C) 2020 ADSK +Copyright (C) 2021 ADSK All rights reserved. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exports.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exports.pas index 4709c400..01fe86c5 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exports.pas +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exports.pas @@ -1,6 +1,6 @@ (*++ -Copyright (C) 2020 ADSK +Copyright (C) 2021 ADSK All rights reserved. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_interfaces.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_interfaces.pas index baf32788..cefb8f88 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_interfaces.pas +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_interfaces.pas @@ -1,6 +1,6 @@ (*++ -Copyright (C) 2020 ADSK +Copyright (C) 2021 ADSK All rights reserved. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_types.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_types.pas index c901da0c..9a40dc21 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_types.pas +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_types.pas @@ -1,6 +1,6 @@ (*++ -Copyright (C) 2020 ADSK +Copyright (C) 2021 ADSK All rights reserved. From 2ae1e8cd59499691af1db48f837656fd3fbe4154 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Fri, 22 Oct 2021 13:02:02 -0700 Subject: [PATCH 042/143] Add CDynamic --- Examples/RTTI/RTTI.xml | 4 +- .../Bindings/CDynamic/rtti_dynamic.c | 206 ++++++++++++++++++ .../Bindings/CDynamic/rtti_dynamic.cc | 206 ++++++++++++++++++ .../Bindings/CDynamic/rtti_dynamic.h | 204 +++++++++++++++++ .../Bindings/CDynamic/rtti_types.h | 140 ++++++++++++ .../Bindings/CppDynamic/rtti_abi.hpp | 190 ++++++++++++++++ .../Examples/CDynamic/CMakeLists.txt | 34 +++ .../Examples/CDynamic/RTTI_example.c | 105 +++++++++ 8 files changed, 1086 insertions(+), 3 deletions(-) create mode 100644 Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.c create mode 100644 Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.cc create mode 100644 Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.h create mode 100644 Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_types.h create mode 100644 Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp create mode 100644 Examples/RTTI/RTTI_component/Examples/CDynamic/CMakeLists.txt create mode 100644 Examples/RTTI/RTTI_component/Examples/CDynamic/RTTI_example.c diff --git a/Examples/RTTI/RTTI.xml b/Examples/RTTI/RTTI.xml index f60eb969..f5e77960 100644 --- a/Examples/RTTI/RTTI.xml +++ b/Examples/RTTI/RTTI.xml @@ -8,9 +8,7 @@ </license> <bindings> - <binding language="CppDynamic" indentation="tabs"/> - <binding language="Python" indentation="tabs"/> - <binding language="Pascal" indentation="tabs"/> + <binding language="CDynamic" indentation="tabs" /> </bindings> <implementations> <implementation language="Cpp" indentation="tabs"/> diff --git a/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.c b/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.c new file mode 100644 index 00000000..6cbe5c24 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.c @@ -0,0 +1,206 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated plain C Header file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +#include "rtti_types.h" +#include "rtti_dynamic.h" +#ifdef _WIN32 +#include <windows.h> +#else // _WIN32 +#include <dlfcn.h> +#include <stdlib.h> +#endif // _WIN32 + +RTTIResult InitRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable) +{ + if (pWrapperTable == NULL) + return RTTI_ERROR_INVALIDPARAM; + + pWrapperTable->m_LibraryHandle = NULL; + pWrapperTable->m_Base_ClassTypeId = NULL; + pWrapperTable->m_Animal_Name = NULL; + pWrapperTable->m_Tiger_Roar = NULL; + pWrapperTable->m_AnimalIterator_GetNextAnimal = NULL; + pWrapperTable->m_Zoo_Iterator = NULL; + pWrapperTable->m_GetVersion = NULL; + pWrapperTable->m_GetLastError = NULL; + pWrapperTable->m_ReleaseInstance = NULL; + pWrapperTable->m_AcquireInstance = NULL; + pWrapperTable->m_InjectComponent = NULL; + pWrapperTable->m_GetSymbolLookupMethod = NULL; + pWrapperTable->m_CreateZoo = NULL; + + return RTTI_SUCCESS; +} + +RTTIResult ReleaseRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable) +{ + if (pWrapperTable == NULL) + return RTTI_ERROR_INVALIDPARAM; + + if (pWrapperTable->m_LibraryHandle != NULL) { + #ifdef _WIN32 + HMODULE hModule = (HMODULE) pWrapperTable->m_LibraryHandle; + FreeLibrary(hModule); + #else // _WIN32 + dlclose(pWrapperTable->m_LibraryHandle); + #endif // _WIN32 + return InitRTTIWrapperTable(pWrapperTable); + } + + return RTTI_SUCCESS; +} + +RTTIResult LoadRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable, const char * pLibraryFileName) +{ + if (pWrapperTable == NULL) + return RTTI_ERROR_INVALIDPARAM; + if (pLibraryFileName == NULL) + return RTTI_ERROR_INVALIDPARAM; + + #ifdef _WIN32 + // Convert filename to UTF16-string + int nLength = static_cast<int>(strnlen_s(pLibraryFileName, MAX_PATH)); + int nBufferSize = nLength * 2 + 2; + wchar_t* wsLibraryFileName = (wchar_t*)malloc(nBufferSize*sizeof(wchar_t)); + memset(wsLibraryFileName, 0, nBufferSize*sizeof(wchar_t)); + int nResult = MultiByteToWideChar(CP_UTF8, 0, pLibraryFileName, nLength, wsLibraryFileName, nBufferSize); + if (nResult == 0) { + free(wsLibraryFileName); + return RTTI_ERROR_COULDNOTLOADLIBRARY; + } + + HMODULE hLibrary = LoadLibraryW(wsLibraryFileName); + free(wsLibraryFileName); + if (hLibrary == 0) + return RTTI_ERROR_COULDNOTLOADLIBRARY; + #else // _WIN32 + void* hLibrary = dlopen(pLibraryFileName, RTLD_LAZY); + if (hLibrary == 0) + return RTTI_ERROR_COULDNOTLOADLIBRARY; + dlerror(); + #endif // _WIN32 + + #ifdef _WIN32 + pWrapperTable->m_Base_ClassTypeId = (PRTTIBase_ClassTypeIdPtr) GetProcAddress(hLibrary, "rtti_base_classtypeid"); + #else // _WIN32 + pWrapperTable->m_Base_ClassTypeId = (PRTTIBase_ClassTypeIdPtr) dlsym(hLibrary, "rtti_base_classtypeid"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_Base_ClassTypeId == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_Animal_Name = (PRTTIAnimal_NamePtr) GetProcAddress(hLibrary, "rtti_animal_name"); + #else // _WIN32 + pWrapperTable->m_Animal_Name = (PRTTIAnimal_NamePtr) dlsym(hLibrary, "rtti_animal_name"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_Animal_Name == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_Tiger_Roar = (PRTTITiger_RoarPtr) GetProcAddress(hLibrary, "rtti_tiger_roar"); + #else // _WIN32 + pWrapperTable->m_Tiger_Roar = (PRTTITiger_RoarPtr) dlsym(hLibrary, "rtti_tiger_roar"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_Tiger_Roar == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_AnimalIterator_GetNextAnimal = (PRTTIAnimalIterator_GetNextAnimalPtr) GetProcAddress(hLibrary, "rtti_animaliterator_getnextanimal"); + #else // _WIN32 + pWrapperTable->m_AnimalIterator_GetNextAnimal = (PRTTIAnimalIterator_GetNextAnimalPtr) dlsym(hLibrary, "rtti_animaliterator_getnextanimal"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_AnimalIterator_GetNextAnimal == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_Zoo_Iterator = (PRTTIZoo_IteratorPtr) GetProcAddress(hLibrary, "rtti_zoo_iterator"); + #else // _WIN32 + pWrapperTable->m_Zoo_Iterator = (PRTTIZoo_IteratorPtr) dlsym(hLibrary, "rtti_zoo_iterator"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_Zoo_Iterator == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_GetVersion = (PRTTIGetVersionPtr) GetProcAddress(hLibrary, "rtti_getversion"); + #else // _WIN32 + pWrapperTable->m_GetVersion = (PRTTIGetVersionPtr) dlsym(hLibrary, "rtti_getversion"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_GetVersion == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_GetLastError = (PRTTIGetLastErrorPtr) GetProcAddress(hLibrary, "rtti_getlasterror"); + #else // _WIN32 + pWrapperTable->m_GetLastError = (PRTTIGetLastErrorPtr) dlsym(hLibrary, "rtti_getlasterror"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_GetLastError == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_ReleaseInstance = (PRTTIReleaseInstancePtr) GetProcAddress(hLibrary, "rtti_releaseinstance"); + #else // _WIN32 + pWrapperTable->m_ReleaseInstance = (PRTTIReleaseInstancePtr) dlsym(hLibrary, "rtti_releaseinstance"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_ReleaseInstance == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_AcquireInstance = (PRTTIAcquireInstancePtr) GetProcAddress(hLibrary, "rtti_acquireinstance"); + #else // _WIN32 + pWrapperTable->m_AcquireInstance = (PRTTIAcquireInstancePtr) dlsym(hLibrary, "rtti_acquireinstance"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_AcquireInstance == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_InjectComponent = (PRTTIInjectComponentPtr) GetProcAddress(hLibrary, "rtti_injectcomponent"); + #else // _WIN32 + pWrapperTable->m_InjectComponent = (PRTTIInjectComponentPtr) dlsym(hLibrary, "rtti_injectcomponent"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_InjectComponent == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_GetSymbolLookupMethod = (PRTTIGetSymbolLookupMethodPtr) GetProcAddress(hLibrary, "rtti_getsymbollookupmethod"); + #else // _WIN32 + pWrapperTable->m_GetSymbolLookupMethod = (PRTTIGetSymbolLookupMethodPtr) dlsym(hLibrary, "rtti_getsymbollookupmethod"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_GetSymbolLookupMethod == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_CreateZoo = (PRTTICreateZooPtr) GetProcAddress(hLibrary, "rtti_createzoo"); + #else // _WIN32 + pWrapperTable->m_CreateZoo = (PRTTICreateZooPtr) dlsym(hLibrary, "rtti_createzoo"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_CreateZoo == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + pWrapperTable->m_LibraryHandle = hLibrary; + return RTTI_SUCCESS; +} + diff --git a/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.cc b/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.cc new file mode 100644 index 00000000..6cbe5c24 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.cc @@ -0,0 +1,206 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated plain C Header file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +#include "rtti_types.h" +#include "rtti_dynamic.h" +#ifdef _WIN32 +#include <windows.h> +#else // _WIN32 +#include <dlfcn.h> +#include <stdlib.h> +#endif // _WIN32 + +RTTIResult InitRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable) +{ + if (pWrapperTable == NULL) + return RTTI_ERROR_INVALIDPARAM; + + pWrapperTable->m_LibraryHandle = NULL; + pWrapperTable->m_Base_ClassTypeId = NULL; + pWrapperTable->m_Animal_Name = NULL; + pWrapperTable->m_Tiger_Roar = NULL; + pWrapperTable->m_AnimalIterator_GetNextAnimal = NULL; + pWrapperTable->m_Zoo_Iterator = NULL; + pWrapperTable->m_GetVersion = NULL; + pWrapperTable->m_GetLastError = NULL; + pWrapperTable->m_ReleaseInstance = NULL; + pWrapperTable->m_AcquireInstance = NULL; + pWrapperTable->m_InjectComponent = NULL; + pWrapperTable->m_GetSymbolLookupMethod = NULL; + pWrapperTable->m_CreateZoo = NULL; + + return RTTI_SUCCESS; +} + +RTTIResult ReleaseRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable) +{ + if (pWrapperTable == NULL) + return RTTI_ERROR_INVALIDPARAM; + + if (pWrapperTable->m_LibraryHandle != NULL) { + #ifdef _WIN32 + HMODULE hModule = (HMODULE) pWrapperTable->m_LibraryHandle; + FreeLibrary(hModule); + #else // _WIN32 + dlclose(pWrapperTable->m_LibraryHandle); + #endif // _WIN32 + return InitRTTIWrapperTable(pWrapperTable); + } + + return RTTI_SUCCESS; +} + +RTTIResult LoadRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable, const char * pLibraryFileName) +{ + if (pWrapperTable == NULL) + return RTTI_ERROR_INVALIDPARAM; + if (pLibraryFileName == NULL) + return RTTI_ERROR_INVALIDPARAM; + + #ifdef _WIN32 + // Convert filename to UTF16-string + int nLength = static_cast<int>(strnlen_s(pLibraryFileName, MAX_PATH)); + int nBufferSize = nLength * 2 + 2; + wchar_t* wsLibraryFileName = (wchar_t*)malloc(nBufferSize*sizeof(wchar_t)); + memset(wsLibraryFileName, 0, nBufferSize*sizeof(wchar_t)); + int nResult = MultiByteToWideChar(CP_UTF8, 0, pLibraryFileName, nLength, wsLibraryFileName, nBufferSize); + if (nResult == 0) { + free(wsLibraryFileName); + return RTTI_ERROR_COULDNOTLOADLIBRARY; + } + + HMODULE hLibrary = LoadLibraryW(wsLibraryFileName); + free(wsLibraryFileName); + if (hLibrary == 0) + return RTTI_ERROR_COULDNOTLOADLIBRARY; + #else // _WIN32 + void* hLibrary = dlopen(pLibraryFileName, RTLD_LAZY); + if (hLibrary == 0) + return RTTI_ERROR_COULDNOTLOADLIBRARY; + dlerror(); + #endif // _WIN32 + + #ifdef _WIN32 + pWrapperTable->m_Base_ClassTypeId = (PRTTIBase_ClassTypeIdPtr) GetProcAddress(hLibrary, "rtti_base_classtypeid"); + #else // _WIN32 + pWrapperTable->m_Base_ClassTypeId = (PRTTIBase_ClassTypeIdPtr) dlsym(hLibrary, "rtti_base_classtypeid"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_Base_ClassTypeId == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_Animal_Name = (PRTTIAnimal_NamePtr) GetProcAddress(hLibrary, "rtti_animal_name"); + #else // _WIN32 + pWrapperTable->m_Animal_Name = (PRTTIAnimal_NamePtr) dlsym(hLibrary, "rtti_animal_name"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_Animal_Name == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_Tiger_Roar = (PRTTITiger_RoarPtr) GetProcAddress(hLibrary, "rtti_tiger_roar"); + #else // _WIN32 + pWrapperTable->m_Tiger_Roar = (PRTTITiger_RoarPtr) dlsym(hLibrary, "rtti_tiger_roar"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_Tiger_Roar == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_AnimalIterator_GetNextAnimal = (PRTTIAnimalIterator_GetNextAnimalPtr) GetProcAddress(hLibrary, "rtti_animaliterator_getnextanimal"); + #else // _WIN32 + pWrapperTable->m_AnimalIterator_GetNextAnimal = (PRTTIAnimalIterator_GetNextAnimalPtr) dlsym(hLibrary, "rtti_animaliterator_getnextanimal"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_AnimalIterator_GetNextAnimal == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_Zoo_Iterator = (PRTTIZoo_IteratorPtr) GetProcAddress(hLibrary, "rtti_zoo_iterator"); + #else // _WIN32 + pWrapperTable->m_Zoo_Iterator = (PRTTIZoo_IteratorPtr) dlsym(hLibrary, "rtti_zoo_iterator"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_Zoo_Iterator == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_GetVersion = (PRTTIGetVersionPtr) GetProcAddress(hLibrary, "rtti_getversion"); + #else // _WIN32 + pWrapperTable->m_GetVersion = (PRTTIGetVersionPtr) dlsym(hLibrary, "rtti_getversion"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_GetVersion == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_GetLastError = (PRTTIGetLastErrorPtr) GetProcAddress(hLibrary, "rtti_getlasterror"); + #else // _WIN32 + pWrapperTable->m_GetLastError = (PRTTIGetLastErrorPtr) dlsym(hLibrary, "rtti_getlasterror"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_GetLastError == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_ReleaseInstance = (PRTTIReleaseInstancePtr) GetProcAddress(hLibrary, "rtti_releaseinstance"); + #else // _WIN32 + pWrapperTable->m_ReleaseInstance = (PRTTIReleaseInstancePtr) dlsym(hLibrary, "rtti_releaseinstance"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_ReleaseInstance == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_AcquireInstance = (PRTTIAcquireInstancePtr) GetProcAddress(hLibrary, "rtti_acquireinstance"); + #else // _WIN32 + pWrapperTable->m_AcquireInstance = (PRTTIAcquireInstancePtr) dlsym(hLibrary, "rtti_acquireinstance"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_AcquireInstance == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_InjectComponent = (PRTTIInjectComponentPtr) GetProcAddress(hLibrary, "rtti_injectcomponent"); + #else // _WIN32 + pWrapperTable->m_InjectComponent = (PRTTIInjectComponentPtr) dlsym(hLibrary, "rtti_injectcomponent"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_InjectComponent == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_GetSymbolLookupMethod = (PRTTIGetSymbolLookupMethodPtr) GetProcAddress(hLibrary, "rtti_getsymbollookupmethod"); + #else // _WIN32 + pWrapperTable->m_GetSymbolLookupMethod = (PRTTIGetSymbolLookupMethodPtr) dlsym(hLibrary, "rtti_getsymbollookupmethod"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_GetSymbolLookupMethod == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_CreateZoo = (PRTTICreateZooPtr) GetProcAddress(hLibrary, "rtti_createzoo"); + #else // _WIN32 + pWrapperTable->m_CreateZoo = (PRTTICreateZooPtr) dlsym(hLibrary, "rtti_createzoo"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_CreateZoo == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + pWrapperTable->m_LibraryHandle = hLibrary; + return RTTI_SUCCESS; +} + diff --git a/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.h b/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.h new file mode 100644 index 00000000..871f180d --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.h @@ -0,0 +1,204 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated plain C Header file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +#ifndef __RTTI_DYNAMICHEADER +#define __RTTI_DYNAMICHEADER + +#include "rtti_types.h" + + + +/************************************************************************************************************************* + Class definition for Base +**************************************************************************************************************************/ + +/** +* Get Class Type Id +* +* @param[in] pBase - Base instance. +* @param[out] pClassTypeId - Class type as a 64 bits integer +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIBase_ClassTypeIdPtr) (RTTI_Base pBase, RTTI_uint64 * pClassTypeId); + +/************************************************************************************************************************* + Class definition for Animal +**************************************************************************************************************************/ + +/** +* Get the name of the animal +* +* @param[in] pAnimal - Animal instance. +* @param[in] nResultBufferSize - size of the buffer (including trailing 0) +* @param[out] pResultNeededChars - will be filled with the count of the written bytes, or needed buffer size. +* @param[out] pResultBuffer - buffer of , may be NULL +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIAnimal_NamePtr) (RTTI_Animal pAnimal, const RTTI_uint32 nResultBufferSize, RTTI_uint32* pResultNeededChars, char * pResultBuffer); + +/************************************************************************************************************************* + Class definition for Mammal +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Reptile +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Giraffe +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Tiger +**************************************************************************************************************************/ + +/** +* Roar like a tiger +* +* @param[in] pTiger - Tiger instance. +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTITiger_RoarPtr) (RTTI_Tiger pTiger); + +/************************************************************************************************************************* + Class definition for Snake +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Turtle +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for AnimalIterator +**************************************************************************************************************************/ + +/** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIAnimalIterator_GetNextAnimalPtr) (RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal); + +/************************************************************************************************************************* + Class definition for Zoo +**************************************************************************************************************************/ + +/** +* Return an iterator over all zoo animals +* +* @param[in] pZoo - Zoo instance. +* @param[out] pIterator - +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIZoo_IteratorPtr) (RTTI_Zoo pZoo, RTTI_AnimalIterator * pIterator); + +/************************************************************************************************************************* + Global functions +**************************************************************************************************************************/ + +/** +* retrieves the binary version of this library. +* +* @param[out] pMajor - returns the major version of this library +* @param[out] pMinor - returns the minor version of this library +* @param[out] pMicro - returns the micro version of this library +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIGetVersionPtr) (RTTI_uint32 * pMajor, RTTI_uint32 * pMinor, RTTI_uint32 * pMicro); + +/** +* Returns the last error recorded on this object +* +* @param[in] pInstance - Instance Handle +* @param[in] nErrorMessageBufferSize - size of the buffer (including trailing 0) +* @param[out] pErrorMessageNeededChars - will be filled with the count of the written bytes, or needed buffer size. +* @param[out] pErrorMessageBuffer - buffer of Message of the last error, may be NULL +* @param[out] pHasError - Is there a last error to query +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIGetLastErrorPtr) (RTTI_Base pInstance, const RTTI_uint32 nErrorMessageBufferSize, RTTI_uint32* pErrorMessageNeededChars, char * pErrorMessageBuffer, bool * pHasError); + +/** +* Releases shared ownership of an Instance +* +* @param[in] pInstance - Instance Handle +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIReleaseInstancePtr) (RTTI_Base pInstance); + +/** +* Acquires shared ownership of an Instance +* +* @param[in] pInstance - Instance Handle +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIAcquireInstancePtr) (RTTI_Base pInstance); + +/** +* Injects an imported component for usage within this component +* +* @param[in] pNameSpace - NameSpace of the injected component +* @param[in] pSymbolAddressMethod - Address of the SymbolAddressMethod of the injected component +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIInjectComponentPtr) (const char * pNameSpace, RTTI_pvoid pSymbolAddressMethod); + +/** +* Returns the address of the SymbolLookupMethod +* +* @param[out] pSymbolLookupMethod - Address of the SymbolAddressMethod +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIGetSymbolLookupMethodPtr) (RTTI_pvoid * pSymbolLookupMethod); + +/** +* Create a new zoo with animals +* +* @param[out] pInstance - +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTICreateZooPtr) (RTTI_Zoo * pInstance); + +/************************************************************************************************************************* + Function Table Structure +**************************************************************************************************************************/ + +typedef struct { + void * m_LibraryHandle; + PRTTIBase_ClassTypeIdPtr m_Base_ClassTypeId; + PRTTIAnimal_NamePtr m_Animal_Name; + PRTTITiger_RoarPtr m_Tiger_Roar; + PRTTIAnimalIterator_GetNextAnimalPtr m_AnimalIterator_GetNextAnimal; + PRTTIZoo_IteratorPtr m_Zoo_Iterator; + PRTTIGetVersionPtr m_GetVersion; + PRTTIGetLastErrorPtr m_GetLastError; + PRTTIReleaseInstancePtr m_ReleaseInstance; + PRTTIAcquireInstancePtr m_AcquireInstance; + PRTTIInjectComponentPtr m_InjectComponent; + PRTTIGetSymbolLookupMethodPtr m_GetSymbolLookupMethod; + PRTTICreateZooPtr m_CreateZoo; +} sRTTIDynamicWrapperTable; + +/************************************************************************************************************************* + Load DLL dynamically +**************************************************************************************************************************/ +RTTIResult InitRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable); +RTTIResult ReleaseRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable); +RTTIResult LoadRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable, const char * pLibraryFileName); + +#endif // __RTTI_DYNAMICHEADER + diff --git a/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_types.h b/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_types.h new file mode 100644 index 00000000..1e3a2608 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_types.h @@ -0,0 +1,140 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated plain C Header file with basic types in +order to allow an easy use of RTTI + +Interface version: 1.0.0 + +*/ + +#ifndef __RTTI_TYPES_HEADER +#define __RTTI_TYPES_HEADER + +#include <stdbool.h> + +/************************************************************************************************************************* + Scalar types definition +**************************************************************************************************************************/ + +#ifdef RTTI_USELEGACYINTEGERTYPES + +typedef unsigned char RTTI_uint8; +typedef unsigned short RTTI_uint16 ; +typedef unsigned int RTTI_uint32; +typedef unsigned long long RTTI_uint64; +typedef char RTTI_int8; +typedef short RTTI_int16; +typedef int RTTI_int32; +typedef long long RTTI_int64; + +#else // RTTI_USELEGACYINTEGERTYPES + +#include <stdint.h> + +typedef uint8_t RTTI_uint8; +typedef uint16_t RTTI_uint16; +typedef uint32_t RTTI_uint32; +typedef uint64_t RTTI_uint64; +typedef int8_t RTTI_int8; +typedef int16_t RTTI_int16; +typedef int32_t RTTI_int32; +typedef int64_t RTTI_int64 ; + +#endif // RTTI_USELEGACYINTEGERTYPES + +typedef float RTTI_single; +typedef double RTTI_double; + +/************************************************************************************************************************* + General type definitions +**************************************************************************************************************************/ + +typedef RTTI_int32 RTTIResult; +#pragma pack (1) +typedef struct { + void * Handle; + RTTI_uint64 ClassTypeId; +} RTTIHandle; +#pragma pack () +#define RTTIHandleNull { nullptr, 0 } +typedef void * RTTI_pvoid; + +/************************************************************************************************************************* + Version for RTTI +**************************************************************************************************************************/ + +#define RTTI_VERSION_MAJOR 1 +#define RTTI_VERSION_MINOR 0 +#define RTTI_VERSION_MICRO 0 +#define RTTI_VERSION_PRERELEASEINFO "" +#define RTTI_VERSION_BUILDINFO "" + +/************************************************************************************************************************* + Error constants for RTTI +**************************************************************************************************************************/ + +#define RTTI_SUCCESS 0 +#define RTTI_ERROR_NOTIMPLEMENTED 1 /** functionality not implemented */ +#define RTTI_ERROR_INVALIDPARAM 2 /** an invalid parameter was passed */ +#define RTTI_ERROR_INVALIDCAST 3 /** a type cast failed */ +#define RTTI_ERROR_BUFFERTOOSMALL 4 /** a provided buffer is too small */ +#define RTTI_ERROR_GENERICEXCEPTION 5 /** a generic exception occurred */ +#define RTTI_ERROR_COULDNOTLOADLIBRARY 6 /** the library could not be loaded */ +#define RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT 7 /** a required exported symbol could not be found in the library */ +#define RTTI_ERROR_INCOMPATIBLEBINARYVERSION 8 /** the version of the binary interface does not match the bindings interface */ + +/************************************************************************************************************************* + Error strings for RTTI +**************************************************************************************************************************/ + +inline const char * RTTI_GETERRORSTRING (RTTIResult nErrorCode) { + switch (nErrorCode) { + case RTTI_SUCCESS: return "no error"; + case RTTI_ERROR_NOTIMPLEMENTED: return "functionality not implemented"; + case RTTI_ERROR_INVALIDPARAM: return "an invalid parameter was passed"; + case RTTI_ERROR_INVALIDCAST: return "a type cast failed"; + case RTTI_ERROR_BUFFERTOOSMALL: return "a provided buffer is too small"; + case RTTI_ERROR_GENERICEXCEPTION: return "a generic exception occurred"; + case RTTI_ERROR_COULDNOTLOADLIBRARY: return "the library could not be loaded"; + case RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT: return "a required exported symbol could not be found in the library"; + case RTTI_ERROR_INCOMPATIBLEBINARYVERSION: return "the version of the binary interface does not match the bindings interface"; + default: return "unknown error"; + } +} + +/************************************************************************************************************************* + Declaration of handle classes +**************************************************************************************************************************/ + +typedef RTTIHandle RTTI_Base; +typedef RTTIHandle RTTI_Animal; +typedef RTTIHandle RTTI_Mammal; +typedef RTTIHandle RTTI_Reptile; +typedef RTTIHandle RTTI_Giraffe; +typedef RTTIHandle RTTI_Tiger; +typedef RTTIHandle RTTI_Snake; +typedef RTTIHandle RTTI_Turtle; +typedef RTTIHandle RTTI_AnimalIterator; +typedef RTTIHandle RTTI_Zoo; + +/************************************************************************************************************************* + Declaration of structs +**************************************************************************************************************************/ + +#pragma pack (1) + +typedef struct { + RTTI_int32 m_X; + RTTI_int32 m_Y; +} sRTTITestStruct; + +#pragma pack () + + +#endif // __RTTI_TYPES_HEADER diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp new file mode 100644 index 00000000..37912169 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_abi.hpp @@ -0,0 +1,190 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. + +Abstract: This is an autogenerated C++-Header file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +#ifndef __RTTI_HEADER_CPP +#define __RTTI_HEADER_CPP + +#ifdef __RTTI_EXPORTS +#ifdef _WIN32 +#define RTTI_DECLSPEC __declspec (dllexport) +#else // _WIN32 +#define RTTI_DECLSPEC __attribute__((visibility("default"))) +#endif // _WIN32 +#else // __RTTI_EXPORTS +#define RTTI_DECLSPEC +#endif // __RTTI_EXPORTS + +#include "rtti_types.hpp" + + +extern "C" { + +/************************************************************************************************************************* + Class definition for Base +**************************************************************************************************************************/ + +/** +* Get Class Type Id +* +* @param[in] pBase - Base instance. +* @param[out] pClassTypeId - Class type as a 64 bits integer +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_base_classtypeid(RTTI_Base pBase, RTTI_uint64 * pClassTypeId); + +/************************************************************************************************************************* + Class definition for Animal +**************************************************************************************************************************/ + +/** +* Get the name of the animal +* +* @param[in] pAnimal - Animal instance. +* @param[in] nResultBufferSize - size of the buffer (including trailing 0) +* @param[out] pResultNeededChars - will be filled with the count of the written bytes, or needed buffer size. +* @param[out] pResultBuffer - buffer of , may be NULL +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_animal_name(RTTI_Animal pAnimal, const RTTI_uint32 nResultBufferSize, RTTI_uint32* pResultNeededChars, char * pResultBuffer); + +/************************************************************************************************************************* + Class definition for Mammal +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Reptile +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Giraffe +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Tiger +**************************************************************************************************************************/ + +/** +* Roar like a tiger +* +* @param[in] pTiger - Tiger instance. +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_tiger_roar(RTTI_Tiger pTiger); + +/************************************************************************************************************************* + Class definition for Snake +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Turtle +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for AnimalIterator +**************************************************************************************************************************/ + +/** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_animaliterator_getnextanimal(RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal); + +/************************************************************************************************************************* + Class definition for Zoo +**************************************************************************************************************************/ + +/** +* Return an iterator over all zoo animals +* +* @param[in] pZoo - Zoo instance. +* @param[out] pIterator - +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_zoo_iterator(RTTI_Zoo pZoo, RTTI_AnimalIterator * pIterator); + +/************************************************************************************************************************* + Global functions +**************************************************************************************************************************/ + +/** +* retrieves the binary version of this library. +* +* @param[out] pMajor - returns the major version of this library +* @param[out] pMinor - returns the minor version of this library +* @param[out] pMicro - returns the micro version of this library +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_getversion(RTTI_uint32 * pMajor, RTTI_uint32 * pMinor, RTTI_uint32 * pMicro); + +/** +* Returns the last error recorded on this object +* +* @param[in] pInstance - Instance Handle +* @param[in] nErrorMessageBufferSize - size of the buffer (including trailing 0) +* @param[out] pErrorMessageNeededChars - will be filled with the count of the written bytes, or needed buffer size. +* @param[out] pErrorMessageBuffer - buffer of Message of the last error, may be NULL +* @param[out] pHasError - Is there a last error to query +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_getlasterror(RTTI_Base pInstance, const RTTI_uint32 nErrorMessageBufferSize, RTTI_uint32* pErrorMessageNeededChars, char * pErrorMessageBuffer, bool * pHasError); + +/** +* Releases shared ownership of an Instance +* +* @param[in] pInstance - Instance Handle +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_releaseinstance(RTTI_Base pInstance); + +/** +* Acquires shared ownership of an Instance +* +* @param[in] pInstance - Instance Handle +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_acquireinstance(RTTI_Base pInstance); + +/** +* Injects an imported component for usage within this component +* +* @param[in] pNameSpace - NameSpace of the injected component +* @param[in] pSymbolAddressMethod - Address of the SymbolAddressMethod of the injected component +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_injectcomponent(const char * pNameSpace, RTTI_pvoid pSymbolAddressMethod); + +/** +* Returns the address of the SymbolLookupMethod +* +* @param[out] pSymbolLookupMethod - Address of the SymbolAddressMethod +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_getsymbollookupmethod(RTTI_pvoid * pSymbolLookupMethod); + +/** +* Create a new zoo with animals +* +* @param[out] pInstance - +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_createzoo(RTTI_Zoo * pInstance); + +} + +#endif // __RTTI_HEADER_CPP + diff --git a/Examples/RTTI/RTTI_component/Examples/CDynamic/CMakeLists.txt b/Examples/RTTI/RTTI_component/Examples/CDynamic/CMakeLists.txt new file mode 100644 index 00000000..f5bdd5c1 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/CDynamic/CMakeLists.txt @@ -0,0 +1,34 @@ +#[[++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated CMake Project that demonstrates the + usage of the C bindings of RTTI + +Interface version: 1.0.0 + + +]] + +cmake_minimum_required(VERSION 3.5) + +set(CMAKE_CURRENT_BINDING_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../Bindings/CDynamic) + +project(RTTIExample_CDynamic C) +if (EXISTS ${CMAKE_CURRENT_BINDING_DIR}/rtti_dynamic.cc) + file(RENAME "${CMAKE_CURRENT_BINDING_DIR}/rtti_dynamic.cc" "${CMAKE_CURRENT_BINDING_DIR}/rtti_dynamic.c") +endif() +add_executable(RTTIExample_CDynamic + "${CMAKE_CURRENT_SOURCE_DIR}/RTTI_example.c" + "${CMAKE_CURRENT_BINDING_DIR}/rtti_dynamic.c" +) + +set_property(TARGET RTTIExample_CDynamic PROPERTY C_STANDARD 99) +if (UNIX) + target_link_libraries(RTTIExample_CDynamic ${CMAKE_DL_LIBS}) +endif (UNIX) +target_include_directories(RTTIExample_CDynamic PRIVATE "${CMAKE_CURRENT_BINDING_DIR}") diff --git a/Examples/RTTI/RTTI_component/Examples/CDynamic/RTTI_example.c b/Examples/RTTI/RTTI_component/Examples/CDynamic/RTTI_example.c new file mode 100644 index 00000000..219eaab2 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/CDynamic/RTTI_example.c @@ -0,0 +1,105 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated C application that demonstrates the + usage of the C bindings of RTTI + +Interface version: 1.0.0 + +*/ + +#include <stdio.h> +#include <stdlib.h> +#include "rtti_dynamic.h" + +#define printf_s printf + +void releaseWrapper(sRTTIDynamicWrapperTable* pWrapperTable) { + RTTIResult eResult = ReleaseRTTIWrapperTable(pWrapperTable); + if (RTTI_SUCCESS != eResult) { + printf_s("Failed to release wrapper table\n"); + } +} + +int main() +{ + // TODO: put a path to RTTI binary file here: + const char* libpath = "./rtti.dylib"; + sRTTIDynamicWrapperTable sWrapperTable; + RTTIResult eResult = RTTI_SUCCESS; + + eResult = InitRTTIWrapperTable(&sWrapperTable); + if (RTTI_SUCCESS != eResult) { + printf_s("Failed to initialize wrapper table\n"); + return eResult; + } + + eResult = LoadRTTIWrapperTable(&sWrapperTable, libpath); + if (RTTI_SUCCESS != eResult) { + printf_s("Failed to load rtti-binary\n"); + return eResult; + } + RTTI_uint32 nMajor, nMinor, nMicro; + eResult = sWrapperTable.m_GetVersion(&nMajor, &nMinor, &nMicro); + if (RTTI_SUCCESS != eResult) { + printf_s("Failed to get version\n"); + releaseWrapper(&sWrapperTable); + return eResult; + } + printf_s("RTTI.Version = %d.%d.%d", nMajor, nMinor, nMicro); + + printf_s("\n"); + + RTTI_Zoo Zoo; + eResult = sWrapperTable.m_CreateZoo(&Zoo); + if (RTTI_SUCCESS != eResult) { + printf_s("Failed to get Zoo\n"); + releaseWrapper(&sWrapperTable); + return eResult; + } + + RTTI_AnimalIterator Iterator; + eResult = sWrapperTable.m_Zoo_Iterator(Zoo, &Iterator); + if (RTTI_SUCCESS != eResult) { + printf_s("Failed to get Iterator\n"); + releaseWrapper(&sWrapperTable); + return eResult; + } + + while (1) { + RTTI_Animal Animal; + eResult = sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal); + if (RTTI_SUCCESS != eResult) { + printf_s("Failed to get Iterator\n"); + releaseWrapper(&sWrapperTable); + return eResult; + } + + if (!Animal.Handle) + break; + + RTTI_uint32 CharsRead = 0; + char Name[255]; + if (RTTI_SUCCESS != sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) + || RTTI_SUCCESS != sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])) { + printf_s("Failed to call Animal name\n"); + releaseWrapper(&sWrapperTable); + return eResult; + } + printf_s("Animal name: %s\n", Name); + } + + eResult = ReleaseRTTIWrapperTable(&sWrapperTable); + if (RTTI_SUCCESS != eResult) { + printf_s("Failed to release wrapper table\n"); + return eResult; + } + + return 0; +} + From ac46ae7cde6a850d3cf732ae500c4961b902bfe0 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Fri, 22 Oct 2021 13:03:46 -0700 Subject: [PATCH 043/143] Add Cpp example --- .../RTTI_component/Bindings/Cpp/rtti_abi.hpp | 194 +++++ .../Bindings/Cpp/rtti_implicit.hpp | 750 ++++++++++++++++++ .../Bindings/Cpp/rtti_types.hpp | 145 ++++ .../Examples/Cpp/CMakeLists.txt | 25 + .../Examples/Cpp/RTTI_example.cpp | 49 ++ 5 files changed, 1163 insertions(+) create mode 100644 Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_abi.hpp create mode 100644 Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_implicit.hpp create mode 100644 Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_types.hpp create mode 100644 Examples/RTTI/RTTI_component/Examples/Cpp/CMakeLists.txt create mode 100644 Examples/RTTI/RTTI_component/Examples/Cpp/RTTI_example.cpp diff --git a/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_abi.hpp b/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_abi.hpp new file mode 100644 index 00000000..cffde6e3 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_abi.hpp @@ -0,0 +1,194 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated C++-Header file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +#ifndef __RTTI_HEADER_CPP +#define __RTTI_HEADER_CPP + +#ifdef __RTTI_EXPORTS +#ifdef _WIN32 +#define RTTI_DECLSPEC __declspec (dllexport) +#else // _WIN32 +#define RTTI_DECLSPEC __attribute__((visibility("default"))) +#endif // _WIN32 +#else // __RTTI_EXPORTS +#define RTTI_DECLSPEC +#endif // __RTTI_EXPORTS + +#include "rtti_types.hpp" + + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************************************* + Class definition for Base +**************************************************************************************************************************/ + +/** +* Get Class Type Id +* +* @param[in] pBase - Base instance. +* @param[out] pClassTypeId - Class type as a 64 bits integer +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_base_classtypeid(RTTI_Base pBase, RTTI_uint64 * pClassTypeId); + +/************************************************************************************************************************* + Class definition for Animal +**************************************************************************************************************************/ + +/** +* Get the name of the animal +* +* @param[in] pAnimal - Animal instance. +* @param[in] nResultBufferSize - size of the buffer (including trailing 0) +* @param[out] pResultNeededChars - will be filled with the count of the written bytes, or needed buffer size. +* @param[out] pResultBuffer - buffer of , may be NULL +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_animal_name(RTTI_Animal pAnimal, const RTTI_uint32 nResultBufferSize, RTTI_uint32* pResultNeededChars, char * pResultBuffer); + +/************************************************************************************************************************* + Class definition for Mammal +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Reptile +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Giraffe +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Tiger +**************************************************************************************************************************/ + +/** +* Roar like a tiger +* +* @param[in] pTiger - Tiger instance. +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_tiger_roar(RTTI_Tiger pTiger); + +/************************************************************************************************************************* + Class definition for Snake +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Turtle +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for AnimalIterator +**************************************************************************************************************************/ + +/** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_animaliterator_getnextanimal(RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal); + +/************************************************************************************************************************* + Class definition for Zoo +**************************************************************************************************************************/ + +/** +* Return an iterator over all zoo animals +* +* @param[in] pZoo - Zoo instance. +* @param[out] pIterator - +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_zoo_iterator(RTTI_Zoo pZoo, RTTI_AnimalIterator * pIterator); + +/************************************************************************************************************************* + Global functions +**************************************************************************************************************************/ + +/** +* retrieves the binary version of this library. +* +* @param[out] pMajor - returns the major version of this library +* @param[out] pMinor - returns the minor version of this library +* @param[out] pMicro - returns the micro version of this library +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_getversion(RTTI_uint32 * pMajor, RTTI_uint32 * pMinor, RTTI_uint32 * pMicro); + +/** +* Returns the last error recorded on this object +* +* @param[in] pInstance - Instance Handle +* @param[in] nErrorMessageBufferSize - size of the buffer (including trailing 0) +* @param[out] pErrorMessageNeededChars - will be filled with the count of the written bytes, or needed buffer size. +* @param[out] pErrorMessageBuffer - buffer of Message of the last error, may be NULL +* @param[out] pHasError - Is there a last error to query +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_getlasterror(RTTI_Base pInstance, const RTTI_uint32 nErrorMessageBufferSize, RTTI_uint32* pErrorMessageNeededChars, char * pErrorMessageBuffer, bool * pHasError); + +/** +* Releases shared ownership of an Instance +* +* @param[in] pInstance - Instance Handle +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_releaseinstance(RTTI_Base pInstance); + +/** +* Acquires shared ownership of an Instance +* +* @param[in] pInstance - Instance Handle +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_acquireinstance(RTTI_Base pInstance); + +/** +* Injects an imported component for usage within this component +* +* @param[in] pNameSpace - NameSpace of the injected component +* @param[in] pSymbolAddressMethod - Address of the SymbolAddressMethod of the injected component +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_injectcomponent(const char * pNameSpace, RTTI_pvoid pSymbolAddressMethod); + +/** +* Returns the address of the SymbolLookupMethod +* +* @param[out] pSymbolLookupMethod - Address of the SymbolAddressMethod +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_getsymbollookupmethod(RTTI_pvoid * pSymbolLookupMethod); + +/** +* Create a new zoo with animals +* +* @param[out] pInstance - +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_createzoo(RTTI_Zoo * pInstance); + +#ifdef __cplusplus +} +#endif + +#endif // __RTTI_HEADER_CPP + diff --git a/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_implicit.hpp b/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_implicit.hpp new file mode 100644 index 00000000..e9dea63a --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_implicit.hpp @@ -0,0 +1,750 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated C++-Header file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +#ifndef __RTTI_CPPHEADER_IMPLICIT_CPP +#define __RTTI_CPPHEADER_IMPLICIT_CPP + +#include "rtti_types.hpp" +#include "rtti_abi.hpp" + + +#ifdef _WIN32 +#include <windows.h> +#else // _WIN32 +#include <dlfcn.h> +#endif // _WIN32 +#include <array> +#include <string> +#include <memory> +#include <vector> +#include <exception> + +namespace RTTI { + +/************************************************************************************************************************* + Forward Declaration of all classes +**************************************************************************************************************************/ +class CWrapper; +class CBase; +class CAnimal; +class CMammal; +class CReptile; +class CGiraffe; +class CTiger; +class CSnake; +class CTurtle; +class CAnimalIterator; +class CZoo; + +/************************************************************************************************************************* + Declaration of deprecated class types +**************************************************************************************************************************/ +typedef CWrapper CRTTIWrapper; +typedef CBase CRTTIBase; +typedef CAnimal CRTTIAnimal; +typedef CMammal CRTTIMammal; +typedef CReptile CRTTIReptile; +typedef CGiraffe CRTTIGiraffe; +typedef CTiger CRTTITiger; +typedef CSnake CRTTISnake; +typedef CTurtle CRTTITurtle; +typedef CAnimalIterator CRTTIAnimalIterator; +typedef CZoo CRTTIZoo; + +/************************************************************************************************************************* + Declaration of shared pointer types +**************************************************************************************************************************/ +typedef std::shared_ptr<CWrapper> PWrapper; +typedef std::shared_ptr<CBase> PBase; +typedef std::shared_ptr<CAnimal> PAnimal; +typedef std::shared_ptr<CMammal> PMammal; +typedef std::shared_ptr<CReptile> PReptile; +typedef std::shared_ptr<CGiraffe> PGiraffe; +typedef std::shared_ptr<CTiger> PTiger; +typedef std::shared_ptr<CSnake> PSnake; +typedef std::shared_ptr<CTurtle> PTurtle; +typedef std::shared_ptr<CAnimalIterator> PAnimalIterator; +typedef std::shared_ptr<CZoo> PZoo; + +/************************************************************************************************************************* + Declaration of deprecated shared pointer types +**************************************************************************************************************************/ +typedef PWrapper PRTTIWrapper; +typedef PBase PRTTIBase; +typedef PAnimal PRTTIAnimal; +typedef PMammal PRTTIMammal; +typedef PReptile PRTTIReptile; +typedef PGiraffe PRTTIGiraffe; +typedef PTiger PRTTITiger; +typedef PSnake PRTTISnake; +typedef PTurtle PRTTITurtle; +typedef PAnimalIterator PRTTIAnimalIterator; +typedef PZoo PRTTIZoo; + + +/************************************************************************************************************************* + classParam Definition +**************************************************************************************************************************/ + +template<class T> class classParam { +private: + const T* m_ptr; + +public: + classParam(const T* ptr) + : m_ptr (ptr) + { + } + + classParam(std::shared_ptr <T> sharedPtr) + : m_ptr (sharedPtr.get()) + { + } + + RTTIHandle GetHandle() + { + if (m_ptr != nullptr) + return m_ptr->handle(); + return RTTIHandleNull; + } +}; + +/************************************************************************************************************************* + Class ERTTIException +**************************************************************************************************************************/ +class ERTTIException : public std::exception { +protected: + /** + * Error code for the Exception. + */ + RTTIResult m_errorCode; + /** + * Error message for the Exception. + */ + std::string m_errorMessage; + std::string m_originalErrorMessage; + +public: + /** + * Exception Constructor. + */ + ERTTIException(RTTIResult errorCode, const std::string & sErrorMessage) + : m_errorCode(errorCode), m_originalErrorMessage(sErrorMessage) + { + m_errorMessage = buildErrorMessage(); + } + + /** + * Returns error code + */ + RTTIResult getErrorCode() const noexcept + { + return m_errorCode; + } + + /** + * Returns error message + */ + const char* what() const noexcept + { + return m_errorMessage.c_str(); + } + + const char* getErrorMessage() const noexcept + { + return m_originalErrorMessage.c_str(); + } + + const char* getErrorName() const noexcept + { + switch(getErrorCode()) { + case RTTI_SUCCESS: return "SUCCESS"; + case RTTI_ERROR_NOTIMPLEMENTED: return "NOTIMPLEMENTED"; + case RTTI_ERROR_INVALIDPARAM: return "INVALIDPARAM"; + case RTTI_ERROR_INVALIDCAST: return "INVALIDCAST"; + case RTTI_ERROR_BUFFERTOOSMALL: return "BUFFERTOOSMALL"; + case RTTI_ERROR_GENERICEXCEPTION: return "GENERICEXCEPTION"; + case RTTI_ERROR_COULDNOTLOADLIBRARY: return "COULDNOTLOADLIBRARY"; + case RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT: return "COULDNOTFINDLIBRARYEXPORT"; + case RTTI_ERROR_INCOMPATIBLEBINARYVERSION: return "INCOMPATIBLEBINARYVERSION"; + } + return "UNKNOWN"; + } + + const char* getErrorDescription() const noexcept + { + switch(getErrorCode()) { + case RTTI_SUCCESS: return "success"; + case RTTI_ERROR_NOTIMPLEMENTED: return "functionality not implemented"; + case RTTI_ERROR_INVALIDPARAM: return "an invalid parameter was passed"; + case RTTI_ERROR_INVALIDCAST: return "a type cast failed"; + case RTTI_ERROR_BUFFERTOOSMALL: return "a provided buffer is too small"; + case RTTI_ERROR_GENERICEXCEPTION: return "a generic exception occurred"; + case RTTI_ERROR_COULDNOTLOADLIBRARY: return "the library could not be loaded"; + case RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT: return "a required exported symbol could not be found in the library"; + case RTTI_ERROR_INCOMPATIBLEBINARYVERSION: return "the version of the binary interface does not match the bindings interface"; + } + return "unknown error"; + } + +private: + + std::string buildErrorMessage() const noexcept + { + std::string msg = m_originalErrorMessage; + if (msg.empty()) { + msg = getErrorDescription(); + } + return std::string("Error: ") + getErrorName() + ": " + msg; + } +}; + +/************************************************************************************************************************* + Class CInputVector +**************************************************************************************************************************/ +template <typename T> +class CInputVector { +private: + + const T* m_data; + size_t m_size; + +public: + + explicit CInputVector( const std::vector<T>& vec) + : m_data( vec.data() ), m_size( vec.size() ) + { + } + + CInputVector( const T* in_data, size_t in_size) + : m_data( in_data ), m_size(in_size ) + { + } + + const T* data() const + { + return m_data; + } + + size_t size() const + { + return m_size; + } + +}; + +// declare deprecated class name +template<typename T> +using CRTTIInputVector = CInputVector<T>; + +/************************************************************************************************************************* + Class CWrapper +**************************************************************************************************************************/ +class CWrapper { +public: + + CWrapper() + { + } + + ~CWrapper() + { + } + static inline PWrapper loadLibrary() + { + return std::make_shared<CWrapper>(); + } + + inline void CheckError(CBase * pBaseClass, RTTIResult nResult); + + inline void GetVersion(RTTI_uint32 & nMajor, RTTI_uint32 & nMinor, RTTI_uint32 & nMicro); + inline bool GetLastError(classParam<CBase> pInstance, std::string & sErrorMessage); + inline void ReleaseInstance(classParam<CBase> pInstance); + inline void AcquireInstance(classParam<CBase> pInstance); + inline void InjectComponent(const std::string & sNameSpace, const RTTI_pvoid pSymbolAddressMethod); + inline RTTI_pvoid GetSymbolLookupMethod(); + inline PZoo CreateZoo(); + +private: + + RTTIResult checkBinaryVersion() + { + RTTI_uint32 nMajor, nMinor, nMicro; + GetVersion(nMajor, nMinor, nMicro); + if (nMajor != RTTI_VERSION_MAJOR) { + return RTTI_ERROR_INCOMPATIBLEBINARYVERSION; + } + return RTTI_SUCCESS; + } + + template<class U> + std::shared_ptr<U> polymorphicFactory(RTTIHandle); + + friend class CBase; + friend class CAnimal; + friend class CMammal; + friend class CReptile; + friend class CGiraffe; + friend class CTiger; + friend class CSnake; + friend class CTurtle; + friend class CAnimalIterator; + friend class CZoo; + +}; + + +/************************************************************************************************************************* + Class CBase +**************************************************************************************************************************/ +class CBase { +public: + +protected: + /* Wrapper Object that created the class. */ + CWrapper * m_pWrapper; + /* Handle to Instance in library*/ + RTTIHandle m_pHandle; + + /* Checks for an Error code and raises Exceptions */ + void CheckError(RTTIResult nResult) + { + if (m_pWrapper != nullptr) + m_pWrapper->CheckError(this, nResult); + } +public: + /** + * CBase::CBase - Constructor for Base class. + */ + CBase(CWrapper * pWrapper, RTTIHandle pHandle) + : m_pWrapper(pWrapper), m_pHandle(pHandle) + { + } + + /** + * CBase::~CBase - Destructor for Base class. + */ + virtual ~CBase() + { + if (m_pWrapper != nullptr) + m_pWrapper->ReleaseInstance(this); + m_pWrapper = nullptr; + } + + /** + * CBase::handle - Returns handle to instance. + */ + RTTIHandle handle() const + { + return m_pHandle; + } + + /** + * CBase::wrapper - Returns wrapper instance. + */ + CWrapper * wrapper() const + { + return m_pWrapper; + } + + friend class CWrapper; + inline RTTI_uint64 ClassTypeId(); +}; + +/************************************************************************************************************************* + Class CAnimal +**************************************************************************************************************************/ +class CAnimal : public CBase { +public: + + /** + * CAnimal::CAnimal - Constructor for Animal class. + */ + CAnimal(CWrapper* pWrapper, RTTIHandle pHandle) + : CBase(pWrapper, pHandle) + { + } + + inline std::string Name(); +}; + +/************************************************************************************************************************* + Class CMammal +**************************************************************************************************************************/ +class CMammal : public CAnimal { +public: + + /** + * CMammal::CMammal - Constructor for Mammal class. + */ + CMammal(CWrapper* pWrapper, RTTIHandle pHandle) + : CAnimal(pWrapper, pHandle) + { + } + +}; + +/************************************************************************************************************************* + Class CReptile +**************************************************************************************************************************/ +class CReptile : public CAnimal { +public: + + /** + * CReptile::CReptile - Constructor for Reptile class. + */ + CReptile(CWrapper* pWrapper, RTTIHandle pHandle) + : CAnimal(pWrapper, pHandle) + { + } + +}; + +/************************************************************************************************************************* + Class CGiraffe +**************************************************************************************************************************/ +class CGiraffe : public CMammal { +public: + + /** + * CGiraffe::CGiraffe - Constructor for Giraffe class. + */ + CGiraffe(CWrapper* pWrapper, RTTIHandle pHandle) + : CMammal(pWrapper, pHandle) + { + } + +}; + +/************************************************************************************************************************* + Class CTiger +**************************************************************************************************************************/ +class CTiger : public CMammal { +public: + + /** + * CTiger::CTiger - Constructor for Tiger class. + */ + CTiger(CWrapper* pWrapper, RTTIHandle pHandle) + : CMammal(pWrapper, pHandle) + { + } + + inline void Roar(); +}; + +/************************************************************************************************************************* + Class CSnake +**************************************************************************************************************************/ +class CSnake : public CReptile { +public: + + /** + * CSnake::CSnake - Constructor for Snake class. + */ + CSnake(CWrapper* pWrapper, RTTIHandle pHandle) + : CReptile(pWrapper, pHandle) + { + } + +}; + +/************************************************************************************************************************* + Class CTurtle +**************************************************************************************************************************/ +class CTurtle : public CReptile { +public: + + /** + * CTurtle::CTurtle - Constructor for Turtle class. + */ + CTurtle(CWrapper* pWrapper, RTTIHandle pHandle) + : CReptile(pWrapper, pHandle) + { + } + +}; + +/************************************************************************************************************************* + Class CAnimalIterator +**************************************************************************************************************************/ +class CAnimalIterator : public CBase { +public: + + /** + * CAnimalIterator::CAnimalIterator - Constructor for AnimalIterator class. + */ + CAnimalIterator(CWrapper* pWrapper, RTTIHandle pHandle) + : CBase(pWrapper, pHandle) + { + } + + inline PAnimal GetNextAnimal(); +}; + +/************************************************************************************************************************* + Class CZoo +**************************************************************************************************************************/ +class CZoo : public CBase { +public: + + /** + * CZoo::CZoo - Constructor for Zoo class. + */ + CZoo(CWrapper* pWrapper, RTTIHandle pHandle) + : CBase(pWrapper, pHandle) + { + } + + inline PAnimalIterator Iterator(); +}; + +/************************************************************************************************************************* + RTTI: Polymorphic Factory implementation +**************************************************************************************************************************/ + +template <class T> +std::shared_ptr<T> CWrapper::polymorphicFactory(RTTIHandle pHandle) +{ + switch(pHandle.ClassTypeId) { + case 0x1549AD28813DAE05UL: return std::dynamic_pointer_cast<T>(std::make_shared<CBase>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Base" + case 0x8B40467DA6D327AFUL: return std::dynamic_pointer_cast<T>(std::make_shared<CAnimal>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Animal" + case 0xBC9D5FA7750C1020UL: return std::dynamic_pointer_cast<T>(std::make_shared<CMammal>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Mammal" + case 0x6756AA8EA5802EC3UL: return std::dynamic_pointer_cast<T>(std::make_shared<CReptile>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Reptile" + case 0x9751971BD2C2D958UL: return std::dynamic_pointer_cast<T>(std::make_shared<CGiraffe>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Giraffe" + case 0x08D007E7B5F7BAF4UL: return std::dynamic_pointer_cast<T>(std::make_shared<CTiger>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Tiger" + case 0x5F6826EF909803B2UL: return std::dynamic_pointer_cast<T>(std::make_shared<CSnake>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Snake" + case 0x8E551B208A2E8321UL: return std::dynamic_pointer_cast<T>(std::make_shared<CTurtle>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Turtle" + case 0xF1917FE6BBE77831UL: return std::dynamic_pointer_cast<T>(std::make_shared<CAnimalIterator>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" + case 0x2262ABE80A5E7878UL: return std::dynamic_pointer_cast<T>(std::make_shared<CZoo>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Zoo" + } + return std::make_shared<T>(this, pHandle); +} + + /** + * CWrapper::GetVersion - retrieves the binary version of this library. + * @param[out] nMajor - returns the major version of this library + * @param[out] nMinor - returns the minor version of this library + * @param[out] nMicro - returns the micro version of this library + */ + inline void CWrapper::GetVersion(RTTI_uint32 & nMajor, RTTI_uint32 & nMinor, RTTI_uint32 & nMicro) + { + CheckError(nullptr,rtti_getversion(&nMajor, &nMinor, &nMicro)); + } + + /** + * CWrapper::GetLastError - Returns the last error recorded on this object + * @param[in] pInstance - Instance Handle + * @param[out] sErrorMessage - Message of the last error + * @return Is there a last error to query + */ + inline bool CWrapper::GetLastError(classParam<CBase> pInstance, std::string & sErrorMessage) + { + RTTIHandle hInstance = pInstance.GetHandle(); + RTTI_uint32 bytesNeededErrorMessage = 0; + RTTI_uint32 bytesWrittenErrorMessage = 0; + bool resultHasError = 0; + CheckError(nullptr,rtti_getlasterror(hInstance, 0, &bytesNeededErrorMessage, nullptr, &resultHasError)); + std::vector<char> bufferErrorMessage(bytesNeededErrorMessage); + CheckError(nullptr,rtti_getlasterror(hInstance, bytesNeededErrorMessage, &bytesWrittenErrorMessage, &bufferErrorMessage[0], &resultHasError)); + sErrorMessage = std::string(&bufferErrorMessage[0]); + + return resultHasError; + } + + /** + * CWrapper::ReleaseInstance - Releases shared ownership of an Instance + * @param[in] pInstance - Instance Handle + */ + inline void CWrapper::ReleaseInstance(classParam<CBase> pInstance) + { + RTTIHandle hInstance = pInstance.GetHandle(); + CheckError(nullptr,rtti_releaseinstance(hInstance)); + } + + /** + * CWrapper::AcquireInstance - Acquires shared ownership of an Instance + * @param[in] pInstance - Instance Handle + */ + inline void CWrapper::AcquireInstance(classParam<CBase> pInstance) + { + RTTIHandle hInstance = pInstance.GetHandle(); + CheckError(nullptr,rtti_acquireinstance(hInstance)); + } + + /** + * CWrapper::InjectComponent - Injects an imported component for usage within this component + * @param[in] sNameSpace - NameSpace of the injected component + * @param[in] pSymbolAddressMethod - Address of the SymbolAddressMethod of the injected component + */ + inline void CWrapper::InjectComponent(const std::string & sNameSpace, const RTTI_pvoid pSymbolAddressMethod) + { + CheckError(nullptr,rtti_injectcomponent(sNameSpace.c_str(), pSymbolAddressMethod)); + + bool bNameSpaceFound = false; + if (!bNameSpaceFound) + throw ERTTIException(RTTI_ERROR_COULDNOTLOADLIBRARY, "Unknown namespace " + sNameSpace); + } + + /** + * CWrapper::GetSymbolLookupMethod - Returns the address of the SymbolLookupMethod + * @return Address of the SymbolAddressMethod + */ + inline RTTI_pvoid CWrapper::GetSymbolLookupMethod() + { + RTTI_pvoid resultSymbolLookupMethod = 0; + CheckError(nullptr,rtti_getsymbollookupmethod(&resultSymbolLookupMethod)); + + return resultSymbolLookupMethod; + } + + /** + * CWrapper::CreateZoo - Create a new zoo with animals + * @return + */ + inline PZoo CWrapper::CreateZoo() + { + RTTIHandle hInstance = RTTIHandleNull; + CheckError(nullptr,rtti_createzoo(&hInstance)); + + if (!hInstance.Handle) { + CheckError(nullptr,RTTI_ERROR_INVALIDPARAM); + } + return this->polymorphicFactory<CZoo>(hInstance); + } + + inline void CWrapper::CheckError(CBase * pBaseClass, RTTIResult nResult) + { + if (nResult != 0) { + std::string sErrorMessage; + if (pBaseClass != nullptr) { + GetLastError(pBaseClass, sErrorMessage); + } + throw ERTTIException(nResult, sErrorMessage); + } + } + + + + /** + * Method definitions for class CBase + */ + + /** + * CBase::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 CBase::ClassTypeId() + { + RTTI_uint64 resultClassTypeId = 0; + CheckError(rtti_base_classtypeid(m_pHandle, &resultClassTypeId)); + + return resultClassTypeId; + } + + /** + * Method definitions for class CAnimal + */ + + /** + * CAnimal::Name - Get the name of the animal + * @return + */ + std::string CAnimal::Name() + { + RTTI_uint32 bytesNeededResult = 0; + RTTI_uint32 bytesWrittenResult = 0; + CheckError(rtti_animal_name(m_pHandle, 0, &bytesNeededResult, nullptr)); + std::vector<char> bufferResult(bytesNeededResult); + CheckError(rtti_animal_name(m_pHandle, bytesNeededResult, &bytesWrittenResult, &bufferResult[0])); + + return std::string(&bufferResult[0]); + } + + /** + * Method definitions for class CMammal + */ + + /** + * Method definitions for class CReptile + */ + + /** + * Method definitions for class CGiraffe + */ + + /** + * Method definitions for class CTiger + */ + + /** + * CTiger::Roar - Roar like a tiger + */ + void CTiger::Roar() + { + CheckError(rtti_tiger_roar(m_pHandle)); + } + + /** + * Method definitions for class CSnake + */ + + /** + * Method definitions for class CTurtle + */ + + /** + * Method definitions for class CAnimalIterator + */ + + /** + * CAnimalIterator::GetNextAnimal - Return next animal + * @return + */ + PAnimal CAnimalIterator::GetNextAnimal() + { + RTTIHandle hAnimal = RTTIHandleNull; + CheckError(rtti_animaliterator_getnextanimal(m_pHandle, &hAnimal)); + + if (hAnimal.Handle) { + return m_pWrapper->polymorphicFactory<CAnimal>(hAnimal); + } else { + return nullptr; + } + } + + /** + * Method definitions for class CZoo + */ + + /** + * CZoo::Iterator - Return an iterator over all zoo animals + * @return + */ + PAnimalIterator CZoo::Iterator() + { + RTTIHandle hIterator = RTTIHandleNull; + CheckError(rtti_zoo_iterator(m_pHandle, &hIterator)); + + if (!hIterator.Handle) { + CheckError(RTTI_ERROR_INVALIDPARAM); + } + return m_pWrapper->polymorphicFactory<CAnimalIterator>(hIterator); + } + +} // namespace RTTI + +#endif // __RTTI_CPPHEADER_IMPLICIT_CPP + diff --git a/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_types.hpp b/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_types.hpp new file mode 100644 index 00000000..7cbf7886 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_types.hpp @@ -0,0 +1,145 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated C++-Header file with basic types in +order to allow an easy use of RTTI + +Interface version: 1.0.0 + +*/ + +#ifndef __RTTI_TYPES_HEADER_CPP +#define __RTTI_TYPES_HEADER_CPP + + +/************************************************************************************************************************* + Scalar types definition +**************************************************************************************************************************/ + +#ifdef RTTI_USELEGACYINTEGERTYPES + +typedef unsigned char RTTI_uint8; +typedef unsigned short RTTI_uint16 ; +typedef unsigned int RTTI_uint32; +typedef unsigned long long RTTI_uint64; +typedef char RTTI_int8; +typedef short RTTI_int16; +typedef int RTTI_int32; +typedef long long RTTI_int64; + +#else // RTTI_USELEGACYINTEGERTYPES + +#include <stdint.h> + +typedef uint8_t RTTI_uint8; +typedef uint16_t RTTI_uint16; +typedef uint32_t RTTI_uint32; +typedef uint64_t RTTI_uint64; +typedef int8_t RTTI_int8; +typedef int16_t RTTI_int16; +typedef int32_t RTTI_int32; +typedef int64_t RTTI_int64 ; + +#endif // RTTI_USELEGACYINTEGERTYPES + +typedef float RTTI_single; +typedef double RTTI_double; + +/************************************************************************************************************************* + General type definitions +**************************************************************************************************************************/ + +typedef RTTI_int32 RTTIResult; +#pragma pack (1) +typedef struct { + void * Handle; + RTTI_uint64 ClassTypeId; +} RTTIHandle; +#pragma pack () +#define RTTIHandleNull { nullptr, 0 } +typedef void * RTTI_pvoid; + +/************************************************************************************************************************* + Version for RTTI +**************************************************************************************************************************/ + +#define RTTI_VERSION_MAJOR 1 +#define RTTI_VERSION_MINOR 0 +#define RTTI_VERSION_MICRO 0 +#define RTTI_VERSION_PRERELEASEINFO "" +#define RTTI_VERSION_BUILDINFO "" + +/************************************************************************************************************************* + Error constants for RTTI +**************************************************************************************************************************/ + +#define RTTI_SUCCESS 0 +#define RTTI_ERROR_NOTIMPLEMENTED 1 /** functionality not implemented */ +#define RTTI_ERROR_INVALIDPARAM 2 /** an invalid parameter was passed */ +#define RTTI_ERROR_INVALIDCAST 3 /** a type cast failed */ +#define RTTI_ERROR_BUFFERTOOSMALL 4 /** a provided buffer is too small */ +#define RTTI_ERROR_GENERICEXCEPTION 5 /** a generic exception occurred */ +#define RTTI_ERROR_COULDNOTLOADLIBRARY 6 /** the library could not be loaded */ +#define RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT 7 /** a required exported symbol could not be found in the library */ +#define RTTI_ERROR_INCOMPATIBLEBINARYVERSION 8 /** the version of the binary interface does not match the bindings interface */ + +/************************************************************************************************************************* + Error strings for RTTI +**************************************************************************************************************************/ + +inline const char * RTTI_GETERRORSTRING (RTTIResult nErrorCode) { + switch (nErrorCode) { + case RTTI_SUCCESS: return "no error"; + case RTTI_ERROR_NOTIMPLEMENTED: return "functionality not implemented"; + case RTTI_ERROR_INVALIDPARAM: return "an invalid parameter was passed"; + case RTTI_ERROR_INVALIDCAST: return "a type cast failed"; + case RTTI_ERROR_BUFFERTOOSMALL: return "a provided buffer is too small"; + case RTTI_ERROR_GENERICEXCEPTION: return "a generic exception occurred"; + case RTTI_ERROR_COULDNOTLOADLIBRARY: return "the library could not be loaded"; + case RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT: return "a required exported symbol could not be found in the library"; + case RTTI_ERROR_INCOMPATIBLEBINARYVERSION: return "the version of the binary interface does not match the bindings interface"; + default: return "unknown error"; + } +} + +/************************************************************************************************************************* + Declaration of handle classes +**************************************************************************************************************************/ + +typedef RTTIHandle RTTI_Base; +typedef RTTIHandle RTTI_Animal; +typedef RTTIHandle RTTI_Mammal; +typedef RTTIHandle RTTI_Reptile; +typedef RTTIHandle RTTI_Giraffe; +typedef RTTIHandle RTTI_Tiger; +typedef RTTIHandle RTTI_Snake; +typedef RTTIHandle RTTI_Turtle; +typedef RTTIHandle RTTI_AnimalIterator; +typedef RTTIHandle RTTI_Zoo; + +namespace RTTI { + + /************************************************************************************************************************* + Declaration of structs + **************************************************************************************************************************/ + + #pragma pack (1) + + typedef struct { + RTTI_int32 m_X; + RTTI_int32 m_Y; + } sTestStruct; + + #pragma pack () + +} // namespace RTTI; + +// define legacy C-names for enums, structs and function types +typedef RTTI::sTestStruct sRTTITestStruct; + +#endif // __RTTI_TYPES_HEADER_CPP diff --git a/Examples/RTTI/RTTI_component/Examples/Cpp/CMakeLists.txt b/Examples/RTTI/RTTI_component/Examples/Cpp/CMakeLists.txt new file mode 100644 index 00000000..a0eb221b --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Cpp/CMakeLists.txt @@ -0,0 +1,25 @@ +#[[++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated CMake Project that demonstrates the + usage of the C++ bindings of RTTI + +Interface version: 1.0.0 + + +]] + +cmake_minimum_required(VERSION 3.5) + +set(CMAKE_CURRENT_BINDING_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../Bindings/Cpp) +project(RTTIExample_CPPImplicit) +set(CMAKE_CXX_STANDARD 11) +add_executable(RTTIExample_CPPImplicit "${CMAKE_CURRENT_SOURCE_DIR}/RTTI_example.cpp") +find_library(RTTILOCATION rtti PATHS "/Users/anpiloa/git/AutomaticComponentToolkit/Examples/build-lib") +target_link_libraries(RTTIExample_CPPImplicit ${RTTILOCATION}) +target_include_directories(RTTIExample_CPPImplicit PRIVATE "${CMAKE_CURRENT_BINDING_DIR}") diff --git a/Examples/RTTI/RTTI_component/Examples/Cpp/RTTI_example.cpp b/Examples/RTTI/RTTI_component/Examples/Cpp/RTTI_example.cpp new file mode 100644 index 00000000..b93aeb2a --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Cpp/RTTI_example.cpp @@ -0,0 +1,49 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated C++ application that demonstrates the + usage of the C++ bindings of RTTI + +Interface version: 1.0.0 + +*/ + +#include <iostream> +#include "rtti_implicit.hpp" + + +int main() +{ + try + { + auto wrapper = RTTI::CWrapper::loadLibrary(); + RTTI_uint32 nMajor, nMinor, nMicro; + wrapper->GetVersion(nMajor, nMinor, nMicro); + std::cout << "RTTI.Version = " << nMajor << "." << nMinor << "." << nMicro; + std::cout << std::endl; + + auto zoo = wrapper->CreateZoo(); + auto iter = zoo->Iterator(); + + using namespace RTTI; + while (auto animal = iter->GetNextAnimal()) { + std::cout << "Animal name: " << animal->Name() << std::endl; + if (auto tiger = std::dynamic_pointer_cast<CTiger>(animal)) { + std::cout << " ^ is a real tiger!!!" << std::endl; + tiger->Roar(); + } + } + } + catch (std::exception &e) + { + std::cout << e.what() << std::endl; + return 1; + } + return 0; +} + From 5fafb2c3592da01f02429d8b6d8f27729e5e243b Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Fri, 22 Oct 2021 13:05:11 -0700 Subject: [PATCH 044/143] Add Go bindings support and example --- Examples/RTTI/RTTI.xml | 1 + .../RTTI/RTTI_component/Bindings/Go/cfunc.go | 24 + .../RTTI/RTTI_component/Bindings/Go/rtti.go | 520 ++++++++++++++++++ .../Bindings/Go/rtti_dynamic.cc | 206 +++++++ .../RTTI_component/Bindings/Go/rtti_dynamic.h | 204 +++++++ .../RTTI_component/Bindings/Go/rtti_types.h | 140 +++++ .../RTTI/RTTI_component/Examples/Go/README.md | 7 + .../Examples/Go/RTTI_example.go | 55 ++ Source/buildbindinggo.go | 18 +- 9 files changed, 1167 insertions(+), 8 deletions(-) create mode 100644 Examples/RTTI/RTTI_component/Bindings/Go/cfunc.go create mode 100644 Examples/RTTI/RTTI_component/Bindings/Go/rtti.go create mode 100644 Examples/RTTI/RTTI_component/Bindings/Go/rtti_dynamic.cc create mode 100644 Examples/RTTI/RTTI_component/Bindings/Go/rtti_dynamic.h create mode 100644 Examples/RTTI/RTTI_component/Bindings/Go/rtti_types.h create mode 100644 Examples/RTTI/RTTI_component/Examples/Go/README.md create mode 100644 Examples/RTTI/RTTI_component/Examples/Go/RTTI_example.go diff --git a/Examples/RTTI/RTTI.xml b/Examples/RTTI/RTTI.xml index f5e77960..46291eba 100644 --- a/Examples/RTTI/RTTI.xml +++ b/Examples/RTTI/RTTI.xml @@ -9,6 +9,7 @@ <bindings> <binding language="CDynamic" indentation="tabs" /> + <binding language="Go" indentation="tabs" /> </bindings> <implementations> <implementation language="Cpp" indentation="tabs"/> diff --git a/Examples/RTTI/RTTI_component/Bindings/Go/cfunc.go b/Examples/RTTI/RTTI_component/Bindings/Go/cfunc.go new file mode 100644 index 00000000..ec26db47 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Go/cfunc.go @@ -0,0 +1,24 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Go wrapper file in order to allow an easy +use of RTTI. + +Interface version: 1.0.0 + +*/ + +// Code generated by Automatic Component Toolkit (ACT); DO NOT EDIT. + +package rtti + +/* +#include "rtti_types.h" +*/ +import "C" + diff --git a/Examples/RTTI/RTTI_component/Bindings/Go/rtti.go b/Examples/RTTI/RTTI_component/Bindings/Go/rtti.go new file mode 100644 index 00000000..2bd4a5a3 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Go/rtti.go @@ -0,0 +1,520 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Go wrapper file in order to allow an easy +use of RTTI. + +Interface version: 1.0.0 + +*/ + +// Code generated by Automatic Component Toolkit (ACT); DO NOT EDIT. + +package rtti + +/* +#include "rtti_dynamic.cc" + +RTTI_pvoid loadRTTILibrary (const char * pFileName) +{ + RTTIResult nResult; + sRTTIDynamicWrapperTable * pWrapperTable = (sRTTIDynamicWrapperTable *) malloc (sizeof (sRTTIDynamicWrapperTable)); + if (pWrapperTable != NULL) { + nResult = InitRTTIWrapperTable (pWrapperTable); + if (nResult != RTTI_SUCCESS) { + free (pWrapperTable); + return 0; + } + + nResult = LoadRTTIWrapperTable (pWrapperTable, pFileName); + if (nResult != RTTI_SUCCESS) { + free (pWrapperTable); + return 0; + } + + return (RTTI_pvoid) pWrapperTable; + } + return 0; +} + +void unloadRTTILibrary (RTTI_pvoid nLibraryHandle) +{ + sRTTIDynamicWrapperTable * pWrapperTable = (sRTTIDynamicWrapperTable *) malloc (sizeof (sRTTIDynamicWrapperTable)); + if (pWrapperTable != NULL) { + ReleaseRTTIWrapperTable (pWrapperTable); + free (pWrapperTable); + } +} + + +RTTIResult CCall_rtti_base_classtypeid(RTTI_pvoid libraryHandle, RTTI_Base pBase, RTTI_uint64 * pClassTypeId) +{ + if (libraryHandle == 0) + return RTTI_ERROR_INVALIDCAST; + sRTTIDynamicWrapperTable * wrapperTable = (sRTTIDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_Base_ClassTypeId (pBase, pClassTypeId); +} + + +RTTIResult CCall_rtti_animal_name(RTTI_pvoid libraryHandle, RTTI_Animal pAnimal, const RTTI_uint32 nResultBufferSize, RTTI_uint32* pResultNeededChars, char * pResultBuffer) +{ + if (libraryHandle == 0) + return RTTI_ERROR_INVALIDCAST; + sRTTIDynamicWrapperTable * wrapperTable = (sRTTIDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_Animal_Name (pAnimal, nResultBufferSize, pResultNeededChars, pResultBuffer); +} + + +RTTIResult CCall_rtti_tiger_roar(RTTI_pvoid libraryHandle, RTTI_Tiger pTiger) +{ + if (libraryHandle == 0) + return RTTI_ERROR_INVALIDCAST; + sRTTIDynamicWrapperTable * wrapperTable = (sRTTIDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_Tiger_Roar (pTiger); +} + + +RTTIResult CCall_rtti_animaliterator_getnextanimal(RTTI_pvoid libraryHandle, RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal) +{ + if (libraryHandle == 0) + return RTTI_ERROR_INVALIDCAST; + sRTTIDynamicWrapperTable * wrapperTable = (sRTTIDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_AnimalIterator_GetNextAnimal (pAnimalIterator, pAnimal); +} + + +RTTIResult CCall_rtti_zoo_iterator(RTTI_pvoid libraryHandle, RTTI_Zoo pZoo, RTTI_AnimalIterator * pIterator) +{ + if (libraryHandle == 0) + return RTTI_ERROR_INVALIDCAST; + sRTTIDynamicWrapperTable * wrapperTable = (sRTTIDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_Zoo_Iterator (pZoo, pIterator); +} + + +RTTIResult CCall_rtti_getversion(RTTI_pvoid libraryHandle, RTTI_uint32 * pMajor, RTTI_uint32 * pMinor, RTTI_uint32 * pMicro) +{ + if (libraryHandle == 0) + return RTTI_ERROR_INVALIDCAST; + sRTTIDynamicWrapperTable * wrapperTable = (sRTTIDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_GetVersion (pMajor, pMinor, pMicro); +} + + +RTTIResult CCall_rtti_getlasterror(RTTI_pvoid libraryHandle, RTTI_Base pInstance, const RTTI_uint32 nErrorMessageBufferSize, RTTI_uint32* pErrorMessageNeededChars, char * pErrorMessageBuffer, bool * pHasError) +{ + if (libraryHandle == 0) + return RTTI_ERROR_INVALIDCAST; + sRTTIDynamicWrapperTable * wrapperTable = (sRTTIDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_GetLastError (pInstance, nErrorMessageBufferSize, pErrorMessageNeededChars, pErrorMessageBuffer, pHasError); +} + + +RTTIResult CCall_rtti_releaseinstance(RTTI_pvoid libraryHandle, RTTI_Base pInstance) +{ + if (libraryHandle == 0) + return RTTI_ERROR_INVALIDCAST; + sRTTIDynamicWrapperTable * wrapperTable = (sRTTIDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_ReleaseInstance (pInstance); +} + + +RTTIResult CCall_rtti_acquireinstance(RTTI_pvoid libraryHandle, RTTI_Base pInstance) +{ + if (libraryHandle == 0) + return RTTI_ERROR_INVALIDCAST; + sRTTIDynamicWrapperTable * wrapperTable = (sRTTIDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_AcquireInstance (pInstance); +} + + +RTTIResult CCall_rtti_injectcomponent(RTTI_pvoid libraryHandle, const char * pNameSpace, RTTI_pvoid pSymbolAddressMethod) +{ + if (libraryHandle == 0) + return RTTI_ERROR_INVALIDCAST; + sRTTIDynamicWrapperTable * wrapperTable = (sRTTIDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_InjectComponent (pNameSpace, pSymbolAddressMethod); +} + + +RTTIResult CCall_rtti_getsymbollookupmethod(RTTI_pvoid libraryHandle, RTTI_pvoid * pSymbolLookupMethod) +{ + if (libraryHandle == 0) + return RTTI_ERROR_INVALIDCAST; + sRTTIDynamicWrapperTable * wrapperTable = (sRTTIDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_GetSymbolLookupMethod (pSymbolLookupMethod); +} + + +RTTIResult CCall_rtti_createzoo(RTTI_pvoid libraryHandle, RTTI_Zoo * pInstance) +{ + if (libraryHandle == 0) + return RTTI_ERROR_INVALIDCAST; + sRTTIDynamicWrapperTable * wrapperTable = (sRTTIDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_CreateZoo (pInstance); +} + +*/ +import "C" + +import ( + "fmt" + "unsafe" + "runtime" +) + +type ref = C.RTTIHandle +type refVoid = C.RTTI_pvoid + +// TestStruct represents a RTTI struct. +type TestStruct struct { + X int32 + Y int32 +} + +// Error constants for RTTI. +const RTTI_ERROR_NOTIMPLEMENTED = 1; +const RTTI_ERROR_INVALIDPARAM = 2; +const RTTI_ERROR_INVALIDCAST = 3; +const RTTI_ERROR_BUFFERTOOSMALL = 4; +const RTTI_ERROR_GENERICEXCEPTION = 5; +const RTTI_ERROR_COULDNOTLOADLIBRARY = 6; +const RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT = 7; +const RTTI_ERROR_INCOMPATIBLEBINARYVERSION = 8; + +// WrappedError is an error that wraps a RTTI error. +type WrappedError struct { + Code uint32 + Message string +} + +func (e *WrappedError) Error() string { + return fmt.Sprintf("rtti: %s (%d)", e.Message, e.Code) +} + +func errorMessage(errorcode uint32) string { + switch (errorcode) { + case RTTI_ERROR_NOTIMPLEMENTED: + return "functionality not implemented"; + case RTTI_ERROR_INVALIDPARAM: + return "an invalid parameter was passed"; + case RTTI_ERROR_INVALIDCAST: + return "a type cast failed"; + case RTTI_ERROR_BUFFERTOOSMALL: + return "a provided buffer is too small"; + case RTTI_ERROR_GENERICEXCEPTION: + return "a generic exception occurred"; + case RTTI_ERROR_COULDNOTLOADLIBRARY: + return "the library could not be loaded"; + case RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT: + return "a required exported symbol could not be found in the library"; + case RTTI_ERROR_INCOMPATIBLEBINARYVERSION: + return "the version of the binary interface does not match the bindings interface"; + default: + return "unknown"; + } +} + +func makeError(errorcode uint32) error { + return &WrappedError{errorcode, errorMessage(uint32(errorcode))} +} + +// Wrapper represents the number wrapper +type Wrapper struct { + _ [0]func() // uncomparable; to make == not compile + LibraryHandle refVoid +} + +// Base represents a RTTI class. +type Base struct { + _ [0]func() // uncomparable; to make == not compile + Ref ref // identifies a C value, see ref type + wrapperRef Wrapper + gcPtr *ref // used to trigger the finalizer when the Value is not referenced any more +} + +// NewBase creates a new Base. +// The wrapped C pointer will be freed when the Go pointer is finalized, +// but one can release it manually calling Release. +func (wrapper Wrapper) NewBase(r ref) Base { + gcPtr := new(ref) + *gcPtr = r + runtime.SetFinalizer(gcPtr, wrapper.releaseC) + return Base{Ref: r, gcPtr: gcPtr, wrapperRef: wrapper} +} + +// Release releases the C pointer. +func (inst Base) Release() error { + err := inst.wrapperRef.ReleaseInstance(inst) + (*inst.gcPtr).Handle = nil + return err +} + +// Equal reports whether inst and w refer to the same C pointer. +func (inst Base) Equal(w Base) bool { + return inst.Ref == w.Ref +} +// ClassTypeId get Class Type Id. +func (inst Base) ClassTypeId() (uint64, error) { + var classTypeId C.uint64_t + ret := C.CCall_rtti_base_classtypeid(inst.wrapperRef.LibraryHandle, inst.Ref, &classTypeId) + if ret != 0 { + return 0, makeError(uint32(ret)) + } + return uint64(classTypeId), nil +} + + +// Animal represents a RTTI class. +type Animal struct { + Base +} + +func (wrapper Wrapper) NewAnimal(r ref) Animal { + return Animal{wrapper.NewBase(r)} +} + +// Name get the name of the animal. +func (inst Animal) Name() (string, error) { + var neededforresult C.uint32_t + var filledinresult C.uint32_t + ret := C.CCall_rtti_animal_name(inst.wrapperRef.LibraryHandle, inst.Ref, 0, &neededforresult, nil) + if ret != 0 { + return "", makeError(uint32(ret)) + } + bufferSizeresult := neededforresult + bufferresult := make([]byte, bufferSizeresult) + ret = C.CCall_rtti_animal_name(inst.wrapperRef.LibraryHandle, inst.Ref, bufferSizeresult, &filledinresult, (*C.char)(unsafe.Pointer(&bufferresult[0]))) + if ret != 0 { + return "", makeError(uint32(ret)) + } + return string(bufferresult[:(filledinresult-1)]), nil +} + + +// Mammal represents a RTTI class. +type Mammal struct { + Animal +} + +func (wrapper Wrapper) NewMammal(r ref) Mammal { + return Mammal{wrapper.NewAnimal(r)} +} + + +// Reptile represents a RTTI class. +type Reptile struct { + Animal +} + +func (wrapper Wrapper) NewReptile(r ref) Reptile { + return Reptile{wrapper.NewAnimal(r)} +} + + +// Giraffe represents a RTTI class. +type Giraffe struct { + Mammal +} + +func (wrapper Wrapper) NewGiraffe(r ref) Giraffe { + return Giraffe{wrapper.NewMammal(r)} +} + + +// Tiger represents a RTTI class. +type Tiger struct { + Mammal +} + +func (wrapper Wrapper) NewTiger(r ref) Tiger { + return Tiger{wrapper.NewMammal(r)} +} + +// Roar roar like a tiger. +func (inst Tiger) Roar() error { + ret := C.CCall_rtti_tiger_roar(inst.wrapperRef.LibraryHandle, inst.Ref) + if ret != 0 { + return makeError(uint32(ret)) + } + return nil +} + + +// Snake represents a RTTI class. +type Snake struct { + Reptile +} + +func (wrapper Wrapper) NewSnake(r ref) Snake { + return Snake{wrapper.NewReptile(r)} +} + + +// Turtle represents a RTTI class. +type Turtle struct { + Reptile +} + +func (wrapper Wrapper) NewTurtle(r ref) Turtle { + return Turtle{wrapper.NewReptile(r)} +} + + +// AnimalIterator represents a RTTI class. +type AnimalIterator struct { + Base +} + +func (wrapper Wrapper) NewAnimalIterator(r ref) AnimalIterator { + return AnimalIterator{wrapper.NewBase(r)} +} + +// GetNextAnimal return next animal. +func (inst AnimalIterator) GetNextAnimal() (*Animal, error) { + var animal ref + ret := C.CCall_rtti_animaliterator_getnextanimal(inst.wrapperRef.LibraryHandle, inst.Ref, &animal) + if ret != 0 { + return nil, makeError(uint32(ret)) + } + var _animalPtr *Animal + if animal.Handle != nil { + _animalPtrVal := inst.wrapperRef.NewAnimal(animal) + _animalPtr = &_animalPtrVal + } + return _animalPtr, nil +} + + +// Zoo represents a RTTI class. +type Zoo struct { + Base +} + +func (wrapper Wrapper) NewZoo(r ref) Zoo { + return Zoo{wrapper.NewBase(r)} +} + +// Iterator return an iterator over all zoo animals. +func (inst Zoo) Iterator() (AnimalIterator, error) { + var iterator ref + ret := C.CCall_rtti_zoo_iterator(inst.wrapperRef.LibraryHandle, inst.Ref, &iterator) + if ret != 0 { + return AnimalIterator{}, makeError(uint32(ret)) + } + return inst.wrapperRef.NewAnimalIterator(iterator), nil +} + + +// GetVersion retrieves the binary version of this library. +func (wrapper Wrapper) GetVersion() (uint32, uint32, uint32, error) { + var major C.uint32_t + var minor C.uint32_t + var micro C.uint32_t + ret := C.CCall_rtti_getversion(wrapper.LibraryHandle, &major, &minor, µ) + if ret != 0 { + return 0, 0, 0, makeError(uint32(ret)) + } + return uint32(major), uint32(minor), uint32(micro), nil +} + +// GetLastError returns the last error recorded on this object. +func (wrapper Wrapper) GetLastError(instance Base) (string, bool, error) { + var neededforerrorMessage C.uint32_t + var filledinerrorMessage C.uint32_t + var hasError C.bool + ret := C.CCall_rtti_getlasterror(wrapper.LibraryHandle, instance.Ref, 0, &neededforerrorMessage, nil, &hasError) + if ret != 0 { + return "", false, makeError(uint32(ret)) + } + bufferSizeerrorMessage := neededforerrorMessage + buffererrorMessage := make([]byte, bufferSizeerrorMessage) + ret = C.CCall_rtti_getlasterror(wrapper.LibraryHandle, instance.Ref, bufferSizeerrorMessage, &filledinerrorMessage, (*C.char)(unsafe.Pointer(&buffererrorMessage[0])), &hasError) + if ret != 0 { + return "", false, makeError(uint32(ret)) + } + return string(buffererrorMessage[:(filledinerrorMessage-1)]), bool(hasError), nil +} + +// ReleaseInstance releases shared ownership of an Instance. +func (wrapper Wrapper) ReleaseInstance(instance Base) error { + ret := C.CCall_rtti_releaseinstance(wrapper.LibraryHandle, instance.Ref) + if ret != 0 { + return makeError(uint32(ret)) + } + return nil +} + +// AcquireInstance acquires shared ownership of an Instance. +func (wrapper Wrapper) AcquireInstance(instance Base) error { + ret := C.CCall_rtti_acquireinstance(wrapper.LibraryHandle, instance.Ref) + if ret != 0 { + return makeError(uint32(ret)) + } + return nil +} + +// InjectComponent injects an imported component for usage within this component. +func (wrapper Wrapper) InjectComponent(nameSpace string, symbolAddressMethod uint64) error { + ret := C.CCall_rtti_injectcomponent(wrapper.LibraryHandle, (*C.char)(unsafe.Pointer(&[]byte(nameSpace)[0])), (C.uint64_t)(symbolAddressMethod)) + if ret != 0 { + return makeError(uint32(ret)) + } + return nil +} + +// GetSymbolLookupMethod returns the address of the SymbolLookupMethod. +func (wrapper Wrapper) GetSymbolLookupMethod() (uint64, error) { + var symbolLookupMethod C.uint64_t + ret := C.CCall_rtti_getsymbollookupmethod(wrapper.LibraryHandle, &symbolLookupMethod) + if ret != 0 { + return 0, makeError(uint32(ret)) + } + return uint64(symbolLookupMethod), nil +} + +// CreateZoo create a new zoo with animals. +func (wrapper Wrapper) CreateZoo() (Zoo, error) { + var instance ref + ret := C.CCall_rtti_createzoo(wrapper.LibraryHandle, &instance) + if ret != 0 { + return Zoo{}, makeError(uint32(ret)) + } + return wrapper.NewZoo(instance), nil +} + +func (wrapper Wrapper) releaseC(r *ref) error { + if r == nil || (*r).Handle == nil { + return nil + } + return wrapper.ReleaseInstance(Base{Ref: *r}) +} + +func (wrapper Wrapper) CheckBinaryVersion() error { + var nBindingMajor uint32 = 1; + var nBindingMinor uint32 = 0; + nMajor, nMinor, _, err := wrapper.GetVersion() + if err != nil { + return err; + } + if (nMajor != nBindingMajor) || (nMinor < nBindingMinor) { + return makeError(0) + } + return nil +} + +func LoadLibrary (libraryPath string) (Wrapper, error) { + var wrapper Wrapper; + wrapper.LibraryHandle = C.loadRTTILibrary (C.CString (libraryPath)); + if (wrapper.LibraryHandle == nil) { + return wrapper, makeError (RTTI_ERROR_COULDNOTLOADLIBRARY) + } + + return wrapper, nil + +} diff --git a/Examples/RTTI/RTTI_component/Bindings/Go/rtti_dynamic.cc b/Examples/RTTI/RTTI_component/Bindings/Go/rtti_dynamic.cc new file mode 100644 index 00000000..6cbe5c24 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Go/rtti_dynamic.cc @@ -0,0 +1,206 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated plain C Header file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +#include "rtti_types.h" +#include "rtti_dynamic.h" +#ifdef _WIN32 +#include <windows.h> +#else // _WIN32 +#include <dlfcn.h> +#include <stdlib.h> +#endif // _WIN32 + +RTTIResult InitRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable) +{ + if (pWrapperTable == NULL) + return RTTI_ERROR_INVALIDPARAM; + + pWrapperTable->m_LibraryHandle = NULL; + pWrapperTable->m_Base_ClassTypeId = NULL; + pWrapperTable->m_Animal_Name = NULL; + pWrapperTable->m_Tiger_Roar = NULL; + pWrapperTable->m_AnimalIterator_GetNextAnimal = NULL; + pWrapperTable->m_Zoo_Iterator = NULL; + pWrapperTable->m_GetVersion = NULL; + pWrapperTable->m_GetLastError = NULL; + pWrapperTable->m_ReleaseInstance = NULL; + pWrapperTable->m_AcquireInstance = NULL; + pWrapperTable->m_InjectComponent = NULL; + pWrapperTable->m_GetSymbolLookupMethod = NULL; + pWrapperTable->m_CreateZoo = NULL; + + return RTTI_SUCCESS; +} + +RTTIResult ReleaseRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable) +{ + if (pWrapperTable == NULL) + return RTTI_ERROR_INVALIDPARAM; + + if (pWrapperTable->m_LibraryHandle != NULL) { + #ifdef _WIN32 + HMODULE hModule = (HMODULE) pWrapperTable->m_LibraryHandle; + FreeLibrary(hModule); + #else // _WIN32 + dlclose(pWrapperTable->m_LibraryHandle); + #endif // _WIN32 + return InitRTTIWrapperTable(pWrapperTable); + } + + return RTTI_SUCCESS; +} + +RTTIResult LoadRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable, const char * pLibraryFileName) +{ + if (pWrapperTable == NULL) + return RTTI_ERROR_INVALIDPARAM; + if (pLibraryFileName == NULL) + return RTTI_ERROR_INVALIDPARAM; + + #ifdef _WIN32 + // Convert filename to UTF16-string + int nLength = static_cast<int>(strnlen_s(pLibraryFileName, MAX_PATH)); + int nBufferSize = nLength * 2 + 2; + wchar_t* wsLibraryFileName = (wchar_t*)malloc(nBufferSize*sizeof(wchar_t)); + memset(wsLibraryFileName, 0, nBufferSize*sizeof(wchar_t)); + int nResult = MultiByteToWideChar(CP_UTF8, 0, pLibraryFileName, nLength, wsLibraryFileName, nBufferSize); + if (nResult == 0) { + free(wsLibraryFileName); + return RTTI_ERROR_COULDNOTLOADLIBRARY; + } + + HMODULE hLibrary = LoadLibraryW(wsLibraryFileName); + free(wsLibraryFileName); + if (hLibrary == 0) + return RTTI_ERROR_COULDNOTLOADLIBRARY; + #else // _WIN32 + void* hLibrary = dlopen(pLibraryFileName, RTLD_LAZY); + if (hLibrary == 0) + return RTTI_ERROR_COULDNOTLOADLIBRARY; + dlerror(); + #endif // _WIN32 + + #ifdef _WIN32 + pWrapperTable->m_Base_ClassTypeId = (PRTTIBase_ClassTypeIdPtr) GetProcAddress(hLibrary, "rtti_base_classtypeid"); + #else // _WIN32 + pWrapperTable->m_Base_ClassTypeId = (PRTTIBase_ClassTypeIdPtr) dlsym(hLibrary, "rtti_base_classtypeid"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_Base_ClassTypeId == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_Animal_Name = (PRTTIAnimal_NamePtr) GetProcAddress(hLibrary, "rtti_animal_name"); + #else // _WIN32 + pWrapperTable->m_Animal_Name = (PRTTIAnimal_NamePtr) dlsym(hLibrary, "rtti_animal_name"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_Animal_Name == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_Tiger_Roar = (PRTTITiger_RoarPtr) GetProcAddress(hLibrary, "rtti_tiger_roar"); + #else // _WIN32 + pWrapperTable->m_Tiger_Roar = (PRTTITiger_RoarPtr) dlsym(hLibrary, "rtti_tiger_roar"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_Tiger_Roar == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_AnimalIterator_GetNextAnimal = (PRTTIAnimalIterator_GetNextAnimalPtr) GetProcAddress(hLibrary, "rtti_animaliterator_getnextanimal"); + #else // _WIN32 + pWrapperTable->m_AnimalIterator_GetNextAnimal = (PRTTIAnimalIterator_GetNextAnimalPtr) dlsym(hLibrary, "rtti_animaliterator_getnextanimal"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_AnimalIterator_GetNextAnimal == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_Zoo_Iterator = (PRTTIZoo_IteratorPtr) GetProcAddress(hLibrary, "rtti_zoo_iterator"); + #else // _WIN32 + pWrapperTable->m_Zoo_Iterator = (PRTTIZoo_IteratorPtr) dlsym(hLibrary, "rtti_zoo_iterator"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_Zoo_Iterator == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_GetVersion = (PRTTIGetVersionPtr) GetProcAddress(hLibrary, "rtti_getversion"); + #else // _WIN32 + pWrapperTable->m_GetVersion = (PRTTIGetVersionPtr) dlsym(hLibrary, "rtti_getversion"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_GetVersion == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_GetLastError = (PRTTIGetLastErrorPtr) GetProcAddress(hLibrary, "rtti_getlasterror"); + #else // _WIN32 + pWrapperTable->m_GetLastError = (PRTTIGetLastErrorPtr) dlsym(hLibrary, "rtti_getlasterror"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_GetLastError == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_ReleaseInstance = (PRTTIReleaseInstancePtr) GetProcAddress(hLibrary, "rtti_releaseinstance"); + #else // _WIN32 + pWrapperTable->m_ReleaseInstance = (PRTTIReleaseInstancePtr) dlsym(hLibrary, "rtti_releaseinstance"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_ReleaseInstance == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_AcquireInstance = (PRTTIAcquireInstancePtr) GetProcAddress(hLibrary, "rtti_acquireinstance"); + #else // _WIN32 + pWrapperTable->m_AcquireInstance = (PRTTIAcquireInstancePtr) dlsym(hLibrary, "rtti_acquireinstance"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_AcquireInstance == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_InjectComponent = (PRTTIInjectComponentPtr) GetProcAddress(hLibrary, "rtti_injectcomponent"); + #else // _WIN32 + pWrapperTable->m_InjectComponent = (PRTTIInjectComponentPtr) dlsym(hLibrary, "rtti_injectcomponent"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_InjectComponent == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_GetSymbolLookupMethod = (PRTTIGetSymbolLookupMethodPtr) GetProcAddress(hLibrary, "rtti_getsymbollookupmethod"); + #else // _WIN32 + pWrapperTable->m_GetSymbolLookupMethod = (PRTTIGetSymbolLookupMethodPtr) dlsym(hLibrary, "rtti_getsymbollookupmethod"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_GetSymbolLookupMethod == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_CreateZoo = (PRTTICreateZooPtr) GetProcAddress(hLibrary, "rtti_createzoo"); + #else // _WIN32 + pWrapperTable->m_CreateZoo = (PRTTICreateZooPtr) dlsym(hLibrary, "rtti_createzoo"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_CreateZoo == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + pWrapperTable->m_LibraryHandle = hLibrary; + return RTTI_SUCCESS; +} + diff --git a/Examples/RTTI/RTTI_component/Bindings/Go/rtti_dynamic.h b/Examples/RTTI/RTTI_component/Bindings/Go/rtti_dynamic.h new file mode 100644 index 00000000..871f180d --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Go/rtti_dynamic.h @@ -0,0 +1,204 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated plain C Header file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +#ifndef __RTTI_DYNAMICHEADER +#define __RTTI_DYNAMICHEADER + +#include "rtti_types.h" + + + +/************************************************************************************************************************* + Class definition for Base +**************************************************************************************************************************/ + +/** +* Get Class Type Id +* +* @param[in] pBase - Base instance. +* @param[out] pClassTypeId - Class type as a 64 bits integer +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIBase_ClassTypeIdPtr) (RTTI_Base pBase, RTTI_uint64 * pClassTypeId); + +/************************************************************************************************************************* + Class definition for Animal +**************************************************************************************************************************/ + +/** +* Get the name of the animal +* +* @param[in] pAnimal - Animal instance. +* @param[in] nResultBufferSize - size of the buffer (including trailing 0) +* @param[out] pResultNeededChars - will be filled with the count of the written bytes, or needed buffer size. +* @param[out] pResultBuffer - buffer of , may be NULL +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIAnimal_NamePtr) (RTTI_Animal pAnimal, const RTTI_uint32 nResultBufferSize, RTTI_uint32* pResultNeededChars, char * pResultBuffer); + +/************************************************************************************************************************* + Class definition for Mammal +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Reptile +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Giraffe +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Tiger +**************************************************************************************************************************/ + +/** +* Roar like a tiger +* +* @param[in] pTiger - Tiger instance. +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTITiger_RoarPtr) (RTTI_Tiger pTiger); + +/************************************************************************************************************************* + Class definition for Snake +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for Turtle +**************************************************************************************************************************/ + +/************************************************************************************************************************* + Class definition for AnimalIterator +**************************************************************************************************************************/ + +/** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIAnimalIterator_GetNextAnimalPtr) (RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal); + +/************************************************************************************************************************* + Class definition for Zoo +**************************************************************************************************************************/ + +/** +* Return an iterator over all zoo animals +* +* @param[in] pZoo - Zoo instance. +* @param[out] pIterator - +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIZoo_IteratorPtr) (RTTI_Zoo pZoo, RTTI_AnimalIterator * pIterator); + +/************************************************************************************************************************* + Global functions +**************************************************************************************************************************/ + +/** +* retrieves the binary version of this library. +* +* @param[out] pMajor - returns the major version of this library +* @param[out] pMinor - returns the minor version of this library +* @param[out] pMicro - returns the micro version of this library +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIGetVersionPtr) (RTTI_uint32 * pMajor, RTTI_uint32 * pMinor, RTTI_uint32 * pMicro); + +/** +* Returns the last error recorded on this object +* +* @param[in] pInstance - Instance Handle +* @param[in] nErrorMessageBufferSize - size of the buffer (including trailing 0) +* @param[out] pErrorMessageNeededChars - will be filled with the count of the written bytes, or needed buffer size. +* @param[out] pErrorMessageBuffer - buffer of Message of the last error, may be NULL +* @param[out] pHasError - Is there a last error to query +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIGetLastErrorPtr) (RTTI_Base pInstance, const RTTI_uint32 nErrorMessageBufferSize, RTTI_uint32* pErrorMessageNeededChars, char * pErrorMessageBuffer, bool * pHasError); + +/** +* Releases shared ownership of an Instance +* +* @param[in] pInstance - Instance Handle +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIReleaseInstancePtr) (RTTI_Base pInstance); + +/** +* Acquires shared ownership of an Instance +* +* @param[in] pInstance - Instance Handle +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIAcquireInstancePtr) (RTTI_Base pInstance); + +/** +* Injects an imported component for usage within this component +* +* @param[in] pNameSpace - NameSpace of the injected component +* @param[in] pSymbolAddressMethod - Address of the SymbolAddressMethod of the injected component +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIInjectComponentPtr) (const char * pNameSpace, RTTI_pvoid pSymbolAddressMethod); + +/** +* Returns the address of the SymbolLookupMethod +* +* @param[out] pSymbolLookupMethod - Address of the SymbolAddressMethod +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIGetSymbolLookupMethodPtr) (RTTI_pvoid * pSymbolLookupMethod); + +/** +* Create a new zoo with animals +* +* @param[out] pInstance - +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTICreateZooPtr) (RTTI_Zoo * pInstance); + +/************************************************************************************************************************* + Function Table Structure +**************************************************************************************************************************/ + +typedef struct { + void * m_LibraryHandle; + PRTTIBase_ClassTypeIdPtr m_Base_ClassTypeId; + PRTTIAnimal_NamePtr m_Animal_Name; + PRTTITiger_RoarPtr m_Tiger_Roar; + PRTTIAnimalIterator_GetNextAnimalPtr m_AnimalIterator_GetNextAnimal; + PRTTIZoo_IteratorPtr m_Zoo_Iterator; + PRTTIGetVersionPtr m_GetVersion; + PRTTIGetLastErrorPtr m_GetLastError; + PRTTIReleaseInstancePtr m_ReleaseInstance; + PRTTIAcquireInstancePtr m_AcquireInstance; + PRTTIInjectComponentPtr m_InjectComponent; + PRTTIGetSymbolLookupMethodPtr m_GetSymbolLookupMethod; + PRTTICreateZooPtr m_CreateZoo; +} sRTTIDynamicWrapperTable; + +/************************************************************************************************************************* + Load DLL dynamically +**************************************************************************************************************************/ +RTTIResult InitRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable); +RTTIResult ReleaseRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable); +RTTIResult LoadRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable, const char * pLibraryFileName); + +#endif // __RTTI_DYNAMICHEADER + diff --git a/Examples/RTTI/RTTI_component/Bindings/Go/rtti_types.h b/Examples/RTTI/RTTI_component/Bindings/Go/rtti_types.h new file mode 100644 index 00000000..1e3a2608 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Go/rtti_types.h @@ -0,0 +1,140 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated plain C Header file with basic types in +order to allow an easy use of RTTI + +Interface version: 1.0.0 + +*/ + +#ifndef __RTTI_TYPES_HEADER +#define __RTTI_TYPES_HEADER + +#include <stdbool.h> + +/************************************************************************************************************************* + Scalar types definition +**************************************************************************************************************************/ + +#ifdef RTTI_USELEGACYINTEGERTYPES + +typedef unsigned char RTTI_uint8; +typedef unsigned short RTTI_uint16 ; +typedef unsigned int RTTI_uint32; +typedef unsigned long long RTTI_uint64; +typedef char RTTI_int8; +typedef short RTTI_int16; +typedef int RTTI_int32; +typedef long long RTTI_int64; + +#else // RTTI_USELEGACYINTEGERTYPES + +#include <stdint.h> + +typedef uint8_t RTTI_uint8; +typedef uint16_t RTTI_uint16; +typedef uint32_t RTTI_uint32; +typedef uint64_t RTTI_uint64; +typedef int8_t RTTI_int8; +typedef int16_t RTTI_int16; +typedef int32_t RTTI_int32; +typedef int64_t RTTI_int64 ; + +#endif // RTTI_USELEGACYINTEGERTYPES + +typedef float RTTI_single; +typedef double RTTI_double; + +/************************************************************************************************************************* + General type definitions +**************************************************************************************************************************/ + +typedef RTTI_int32 RTTIResult; +#pragma pack (1) +typedef struct { + void * Handle; + RTTI_uint64 ClassTypeId; +} RTTIHandle; +#pragma pack () +#define RTTIHandleNull { nullptr, 0 } +typedef void * RTTI_pvoid; + +/************************************************************************************************************************* + Version for RTTI +**************************************************************************************************************************/ + +#define RTTI_VERSION_MAJOR 1 +#define RTTI_VERSION_MINOR 0 +#define RTTI_VERSION_MICRO 0 +#define RTTI_VERSION_PRERELEASEINFO "" +#define RTTI_VERSION_BUILDINFO "" + +/************************************************************************************************************************* + Error constants for RTTI +**************************************************************************************************************************/ + +#define RTTI_SUCCESS 0 +#define RTTI_ERROR_NOTIMPLEMENTED 1 /** functionality not implemented */ +#define RTTI_ERROR_INVALIDPARAM 2 /** an invalid parameter was passed */ +#define RTTI_ERROR_INVALIDCAST 3 /** a type cast failed */ +#define RTTI_ERROR_BUFFERTOOSMALL 4 /** a provided buffer is too small */ +#define RTTI_ERROR_GENERICEXCEPTION 5 /** a generic exception occurred */ +#define RTTI_ERROR_COULDNOTLOADLIBRARY 6 /** the library could not be loaded */ +#define RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT 7 /** a required exported symbol could not be found in the library */ +#define RTTI_ERROR_INCOMPATIBLEBINARYVERSION 8 /** the version of the binary interface does not match the bindings interface */ + +/************************************************************************************************************************* + Error strings for RTTI +**************************************************************************************************************************/ + +inline const char * RTTI_GETERRORSTRING (RTTIResult nErrorCode) { + switch (nErrorCode) { + case RTTI_SUCCESS: return "no error"; + case RTTI_ERROR_NOTIMPLEMENTED: return "functionality not implemented"; + case RTTI_ERROR_INVALIDPARAM: return "an invalid parameter was passed"; + case RTTI_ERROR_INVALIDCAST: return "a type cast failed"; + case RTTI_ERROR_BUFFERTOOSMALL: return "a provided buffer is too small"; + case RTTI_ERROR_GENERICEXCEPTION: return "a generic exception occurred"; + case RTTI_ERROR_COULDNOTLOADLIBRARY: return "the library could not be loaded"; + case RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT: return "a required exported symbol could not be found in the library"; + case RTTI_ERROR_INCOMPATIBLEBINARYVERSION: return "the version of the binary interface does not match the bindings interface"; + default: return "unknown error"; + } +} + +/************************************************************************************************************************* + Declaration of handle classes +**************************************************************************************************************************/ + +typedef RTTIHandle RTTI_Base; +typedef RTTIHandle RTTI_Animal; +typedef RTTIHandle RTTI_Mammal; +typedef RTTIHandle RTTI_Reptile; +typedef RTTIHandle RTTI_Giraffe; +typedef RTTIHandle RTTI_Tiger; +typedef RTTIHandle RTTI_Snake; +typedef RTTIHandle RTTI_Turtle; +typedef RTTIHandle RTTI_AnimalIterator; +typedef RTTIHandle RTTI_Zoo; + +/************************************************************************************************************************* + Declaration of structs +**************************************************************************************************************************/ + +#pragma pack (1) + +typedef struct { + RTTI_int32 m_X; + RTTI_int32 m_Y; +} sRTTITestStruct; + +#pragma pack () + + +#endif // __RTTI_TYPES_HEADER diff --git a/Examples/RTTI/RTTI_component/Examples/Go/README.md b/Examples/RTTI/RTTI_component/Examples/Go/README.md new file mode 100644 index 00000000..ccca3647 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Go/README.md @@ -0,0 +1,7 @@ +## How to Build + +`GO111MODULE=off` environment variable must be set to allow local modules. + +``` +DYLD_LIBRARY_PATH=_path_to_the_lib_ GO111MODULE=off go run RTTI_example.go +``` \ No newline at end of file diff --git a/Examples/RTTI/RTTI_component/Examples/Go/RTTI_example.go b/Examples/RTTI/RTTI_component/Examples/Go/RTTI_example.go new file mode 100644 index 00000000..32cc0eb8 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Go/RTTI_example.go @@ -0,0 +1,55 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Go application that demonstrates the + usage of the Go bindings of RTTI + +Interface version: 1.0.0 + +*/ + + +package main + +import ( + "fmt" + "log" + "../../Bindings/Go" +) + +func main() { + fmt.Println("Start") + wrapper, err := rtti.LoadLibrary("rtti.dylib") + if err != nil { + fmt.Println(err) + } + nMajor, nMinor, nMicro, err := wrapper.GetVersion() + if err != nil { + log.Fatal(err) + } + versionString := fmt.Sprintf("rtti.version = %d.%d.%d", nMajor, nMinor, nMicro) + + fmt.Println(versionString) + Zoo, err := wrapper.CreateZoo() + Iterator, err := Zoo.Iterator() + for true { + Animal, _ := Iterator.GetNextAnimal() + if Animal == nil { + fmt.Println("No more Animals") + break + } + Name, _ := Animal.Name() + fmt.Println("Animal name: %s", Name) + Type := fmt.Sprintf("%T", Animal) + if Type == "*rtti.Tiger" { + fmt.Println(" it's an animal") + } + } + fmt.Println("Done!") +} + diff --git a/Source/buildbindinggo.go b/Source/buildbindinggo.go index 030fba7e..8ad1a131 100644 --- a/Source/buildbindinggo.go +++ b/Source/buildbindinggo.go @@ -423,7 +423,7 @@ func buildGoClass(component ComponentDefinition, class ComponentDefinitionClass, w.Writeln("// Release releases the C pointer.") w.Writeln("func (inst %s) Release() error {", class.ClassName) w.Writeln(" err := inst.wrapperRef.%s(inst)", component.Global.ReleaseMethod) - w.Writeln(" *inst.gcPtr = nil") + w.Writeln(" (*inst.gcPtr).Handle = nil") w.Writeln(" return err") w.Writeln("}") w.Writeln("") @@ -478,7 +478,7 @@ func WriteCGoAbiMethod(method ComponentDefinitionMethod, w LanguageWriter, NameS } w.Writeln("") - w.Writeln("%sResult CCall_%s(%sHandle libraryHandle, %s)", NameSpace, CMethodName, NameSpace, strings.Join(parameters, ", ")) + w.Writeln("%sResult CCall_%s(%s_pvoid libraryHandle, %s)", NameSpace, CMethodName, NameSpace, strings.Join(parameters, ", ")) w.Writeln("{") w.Writeln(" if (libraryHandle == 0) ") w.Writeln(" return %s_ERROR_INVALIDCAST;", strings.ToUpper(NameSpace)) @@ -535,7 +535,7 @@ func buildGoWrapper(component ComponentDefinition, w LanguageWriter) error { w.Writeln("/*") w.Writeln("#include \"%s_dynamic.cc\"", packageName) w.Writeln("") - w.Writeln("%sHandle load%sLibrary (const char * pFileName)", component.NameSpace, component.NameSpace) + w.Writeln("%s_pvoid load%sLibrary (const char * pFileName)", component.NameSpace, component.NameSpace) w.Writeln("{") w.Writeln(" %sResult nResult;", component.NameSpace) w.Writeln(" s%sDynamicWrapperTable * pWrapperTable = (s%sDynamicWrapperTable *) malloc (sizeof (s%sDynamicWrapperTable));", component.NameSpace, component.NameSpace, component.NameSpace) @@ -552,11 +552,12 @@ func buildGoWrapper(component ComponentDefinition, w LanguageWriter) error { w.Writeln(" return 0;") w.Writeln(" }") w.Writeln("") - w.Writeln(" return (%sHandle) pWrapperTable;", component.NameSpace) + w.Writeln(" return (%s_pvoid) pWrapperTable;", component.NameSpace) w.Writeln(" }") + w.Writeln(" return 0;") w.Writeln("}") w.Writeln("") - w.Writeln("void unload%sLibrary (%sHandle nLibraryHandle)", component.NameSpace, component.NameSpace) + w.Writeln("void unload%sLibrary (%s_pvoid nLibraryHandle)", component.NameSpace, component.NameSpace) w.Writeln("{") w.Writeln(" s%sDynamicWrapperTable * pWrapperTable = (s%sDynamicWrapperTable *) malloc (sizeof (s%sDynamicWrapperTable));", component.NameSpace, component.NameSpace, component.NameSpace) w.Writeln(" if (pWrapperTable != NULL) {") @@ -589,6 +590,7 @@ func buildGoWrapper(component ComponentDefinition, w LanguageWriter) error { w.Writeln(")") w.Writeln("") w.Writeln("type ref = C.%sHandle", component.NameSpace) + w.Writeln("type refVoid = C.%s_pvoid", component.NameSpace) w.Writeln("") buildGoEnums(component, w) @@ -608,7 +610,7 @@ func buildGoWrapper(component ComponentDefinition, w LanguageWriter) error { w.Writeln("// Wrapper represents the number wrapper") w.Writeln("type Wrapper struct {") w.Writeln(" _ [0]func() // uncomparable; to make == not compile") - w.Writeln(" LibraryHandle ref") + w.Writeln(" LibraryHandle refVoid") w.Writeln("}") for _, class := range component.Classes { @@ -628,7 +630,7 @@ func buildGoWrapper(component ComponentDefinition, w LanguageWriter) error { } w.Writeln("func (wrapper Wrapper) releaseC(r *ref) error {") - w.Writeln(" if r == nil || *r == nil {") + w.Writeln(" if r == nil || (*r).Handle == nil {") w.Writeln(" return nil") w.Writeln(" }") w.Writeln(" return wrapper.%s(%s{Ref: *r})", component.Global.ReleaseMethod, component.Global.BaseClassName) @@ -903,7 +905,7 @@ func writeGoMethod(method ComponentDefinitionMethod, w LanguageWriter, NameSpace initCallParameters = append(initCallParameters, callParam) if param.ParamType == "optionalclass" { preOKReturn = append(preOKReturn, fmt.Sprintf("var _%sPtr %s", param.ParamName, tp.Type)) - preOKReturn = append(preOKReturn, fmt.Sprintf("if %s == nil {", param.ParamName)) + preOKReturn = append(preOKReturn, fmt.Sprintf("if %s.Handle != nil {", param.ParamName)) if isGlobal { preOKReturn = append(preOKReturn, fmt.Sprintf(" _%sPtrVal := wrapper.New%s(%s)", param.ParamName, param.ParamClass, param.ParamName)) From c89915162fe6a403ca816b5c8693cfab073958c1 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Fri, 22 Oct 2021 13:08:00 -0700 Subject: [PATCH 045/143] Add C# bindings support and example --- Examples/RTTI/RTTI.xml | 1 + .../RTTI_component/Bindings/CSharp/RTTI.cs | 346 ++++++++++++++++++ .../RTTI_component/Examples/CSharp/README.md | 23 ++ .../Examples/CSharp/RTTI_Example.cs | 55 +++ .../Examples/CSharp/RTTI_Example.csproj | 19 + .../Examples/CSharp/RTTI_Example.sln | 25 ++ Source/buildbindingcsharp.go | 58 ++- 7 files changed, 510 insertions(+), 17 deletions(-) create mode 100644 Examples/RTTI/RTTI_component/Bindings/CSharp/RTTI.cs create mode 100644 Examples/RTTI/RTTI_component/Examples/CSharp/README.md create mode 100644 Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.cs create mode 100644 Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.csproj create mode 100644 Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.sln diff --git a/Examples/RTTI/RTTI.xml b/Examples/RTTI/RTTI.xml index 46291eba..d3670010 100644 --- a/Examples/RTTI/RTTI.xml +++ b/Examples/RTTI/RTTI.xml @@ -10,6 +10,7 @@ <bindings> <binding language="CDynamic" indentation="tabs" /> <binding language="Go" indentation="tabs" /> + <binding language="CSharp" indentation="tabs" /> </bindings> <implementations> <implementation language="Cpp" indentation="tabs"/> diff --git a/Examples/RTTI/RTTI_component/Bindings/CSharp/RTTI.cs b/Examples/RTTI/RTTI_component/Bindings/CSharp/RTTI.cs new file mode 100644 index 00000000..ce1110c1 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/CSharp/RTTI.cs @@ -0,0 +1,346 @@ +using System; +using System.Text; +using System.Runtime.InteropServices; + +namespace RTTI { + + public struct sTestStruct + { + public Int32 X; + public Int32 Y; + } + + + namespace Internal { + + [StructLayout(LayoutKind.Explicit, Size=16)] + public unsafe struct RTTIHandle + { + [FieldOffset(0)] public UInt64 Handle; + [FieldOffset(8)] public UInt64 ClassTypeId; + } + + [StructLayout(LayoutKind.Explicit, Size=8)] + public unsafe struct InternalTestStruct + { + [FieldOffset(0)] public Int32 X; + [FieldOffset(4)] public Int32 Y; + } + + + public class RTTIWrapper + { + [DllImport("rtti.dll", EntryPoint = "rtti_base_classtypeid", CallingConvention=CallingConvention.Cdecl)] + public unsafe extern static Int32 Base_ClassTypeId (RTTIHandle Handle, out UInt64 AClassTypeId); + + [DllImport("rtti.dll", EntryPoint = "rtti_animal_name", CallingConvention=CallingConvention.Cdecl)] + public unsafe extern static Int32 Animal_Name (RTTIHandle Handle, UInt32 sizeResult, out UInt32 neededResult, IntPtr dataResult); + + [DllImport("rtti.dll", EntryPoint = "rtti_tiger_roar", CallingConvention=CallingConvention.Cdecl)] + public unsafe extern static Int32 Tiger_Roar (RTTIHandle Handle); + + [DllImport("rtti.dll", EntryPoint = "rtti_animaliterator_getnextanimal", CallingConvention=CallingConvention.Cdecl)] + public unsafe extern static Int32 AnimalIterator_GetNextAnimal (RTTIHandle Handle, out RTTIHandle AAnimal); + + [DllImport("rtti.dll", EntryPoint = "rtti_zoo_iterator", CallingConvention=CallingConvention.Cdecl)] + public unsafe extern static Int32 Zoo_Iterator (RTTIHandle Handle, out RTTIHandle AIterator); + + [DllImport("rtti.dll", EntryPoint = "rtti_getversion", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 GetVersion (out UInt32 AMajor, out UInt32 AMinor, out UInt32 AMicro); + + [DllImport("rtti.dll", EntryPoint = "rtti_getlasterror", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 GetLastError (RTTIHandle AInstance, UInt32 sizeErrorMessage, out UInt32 neededErrorMessage, IntPtr dataErrorMessage, out Byte AHasError); + + [DllImport("rtti.dll", EntryPoint = "rtti_releaseinstance", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 ReleaseInstance (RTTIHandle AInstance); + + [DllImport("rtti.dll", EntryPoint = "rtti_acquireinstance", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 AcquireInstance (RTTIHandle AInstance); + + [DllImport("rtti.dll", EntryPoint = "rtti_injectcomponent", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 InjectComponent (byte[] ANameSpace, UInt64 ASymbolAddressMethod); + + [DllImport("rtti.dll", EntryPoint = "rtti_getsymbollookupmethod", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 GetSymbolLookupMethod (out UInt64 ASymbolLookupMethod); + + [DllImport("rtti.dll", EntryPoint = "rtti_createzoo", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 CreateZoo (out RTTIHandle AInstance); + + public unsafe static sTestStruct convertInternalToStruct_TestStruct (InternalTestStruct intTestStruct) + { + sTestStruct TestStruct; + TestStruct.X = intTestStruct.X; + TestStruct.Y = intTestStruct.Y; + return TestStruct; + } + + public unsafe static InternalTestStruct convertStructToInternal_TestStruct (sTestStruct TestStruct) + { + InternalTestStruct intTestStruct; + intTestStruct.X = TestStruct.X; + intTestStruct.Y = TestStruct.Y; + return intTestStruct; + } + + public static void ThrowError(RTTIHandle Handle, Int32 errorCode) + { + String sMessage = "RTTI Error"; + if (Handle.Handle != 0) { + UInt32 sizeMessage = 0; + UInt32 neededMessage = 0; + Byte hasLastError = 0; + Int32 resultCode1 = GetLastError (Handle, sizeMessage, out neededMessage, IntPtr.Zero, out hasLastError); + if ((resultCode1 == 0) && (hasLastError != 0)) { + sizeMessage = neededMessage; + byte[] bytesMessage = new byte[sizeMessage]; + + GCHandle dataMessage = GCHandle.Alloc(bytesMessage, GCHandleType.Pinned); + Int32 resultCode2 = GetLastError(Handle, sizeMessage, out neededMessage, dataMessage.AddrOfPinnedObject(), out hasLastError); + dataMessage.Free(); + + if ((resultCode2 == 0) && (hasLastError != 0)) { + sMessage = sMessage + ": " + Encoding.UTF8.GetString(bytesMessage).TrimEnd(char.MinValue); + } + } + } + + throw new Exception(sMessage + "(# " + errorCode + ")"); + } + + public static T PolymorphicFactory<T>(RTTIHandle Handle) where T : class + { + T Object; + switch (Handle.ClassTypeId) { + case 0x1549AD28813DAE05: Object = new CBase(Handle) as T; break; // First 64 bits of SHA1 of a string: "RTTI::Base" + case 0x8B40467DA6D327AF: Object = new CAnimal(Handle) as T; break; // First 64 bits of SHA1 of a string: "RTTI::Animal" + case 0xBC9D5FA7750C1020: Object = new CMammal(Handle) as T; break; // First 64 bits of SHA1 of a string: "RTTI::Mammal" + case 0x6756AA8EA5802EC3: Object = new CReptile(Handle) as T; break; // First 64 bits of SHA1 of a string: "RTTI::Reptile" + case 0x9751971BD2C2D958: Object = new CGiraffe(Handle) as T; break; // First 64 bits of SHA1 of a string: "RTTI::Giraffe" + case 0x08D007E7B5F7BAF4: Object = new CTiger(Handle) as T; break; // First 64 bits of SHA1 of a string: "RTTI::Tiger" + case 0x5F6826EF909803B2: Object = new CSnake(Handle) as T; break; // First 64 bits of SHA1 of a string: "RTTI::Snake" + case 0x8E551B208A2E8321: Object = new CTurtle(Handle) as T; break; // First 64 bits of SHA1 of a string: "RTTI::Turtle" + case 0xF1917FE6BBE77831: Object = new CAnimalIterator(Handle) as T; break; // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" + case 0x2262ABE80A5E7878: Object = new CZoo(Handle) as T; break; // First 64 bits of SHA1 of a string: "RTTI::Zoo" + default: Object = System.Activator.CreateInstance(typeof(T), Handle) as T; break; + } + return Object; + } + + } + } + + + public class CBase + { + protected Internal.RTTIHandle Handle; + + public CBase (Internal.RTTIHandle NewHandle) + { + Handle = NewHandle; + } + + ~CBase () + { + if (Handle.Handle != 0) { + Internal.RTTIWrapper.ReleaseInstance (Handle); + Handle.Handle = 0; + } + } + + protected void CheckError (Int32 errorCode) + { + if (errorCode != 0) { + Internal.RTTIWrapper.ThrowError (Handle, errorCode); + } + } + + public Internal.RTTIHandle GetHandle () + { + return Handle; + } + + public UInt64 ClassTypeId () + { + UInt64 resultClassTypeId = 0; + + CheckError(Internal.RTTIWrapper.Base_ClassTypeId (Handle, out resultClassTypeId)); + return resultClassTypeId; + } + + } + + public class CAnimal : CBase + { + public CAnimal (Internal.RTTIHandle NewHandle) : base (NewHandle) + { + } + + public String Name () + { + UInt32 sizeResult = 0; + UInt32 neededResult = 0; + CheckError(Internal.RTTIWrapper.Animal_Name (Handle, sizeResult, out neededResult, IntPtr.Zero)); + sizeResult = neededResult; + byte[] bytesResult = new byte[sizeResult]; + GCHandle dataResult = GCHandle.Alloc(bytesResult, GCHandleType.Pinned); + + CheckError(Internal.RTTIWrapper.Animal_Name (Handle, sizeResult, out neededResult, dataResult.AddrOfPinnedObject())); + dataResult.Free(); + return Encoding.UTF8.GetString(bytesResult).TrimEnd(char.MinValue); + } + + } + + public class CMammal : CAnimal + { + public CMammal (Internal.RTTIHandle NewHandle) : base (NewHandle) + { + } + + } + + public class CReptile : CAnimal + { + public CReptile (Internal.RTTIHandle NewHandle) : base (NewHandle) + { + } + + } + + public class CGiraffe : CMammal + { + public CGiraffe (Internal.RTTIHandle NewHandle) : base (NewHandle) + { + } + + } + + public class CTiger : CMammal + { + public CTiger (Internal.RTTIHandle NewHandle) : base (NewHandle) + { + } + + public void Roar () + { + + CheckError(Internal.RTTIWrapper.Tiger_Roar (Handle)); + } + + } + + public class CSnake : CReptile + { + public CSnake (Internal.RTTIHandle NewHandle) : base (NewHandle) + { + } + + } + + public class CTurtle : CReptile + { + public CTurtle (Internal.RTTIHandle NewHandle) : base (NewHandle) + { + } + + } + + public class CAnimalIterator : CBase + { + public CAnimalIterator (Internal.RTTIHandle NewHandle) : base (NewHandle) + { + } + + public CAnimal GetNextAnimal () + { + Internal.RTTIHandle newAnimal = new Internal.RTTIHandle{ Handle = 0, ClassTypeId = 0}; + + CheckError(Internal.RTTIWrapper.AnimalIterator_GetNextAnimal (Handle, out newAnimal)); + return Internal.RTTIWrapper.PolymorphicFactory<CAnimal>(newAnimal); + } + + } + + public class CZoo : CBase + { + public CZoo (Internal.RTTIHandle NewHandle) : base (NewHandle) + { + } + + public CAnimalIterator Iterator () + { + Internal.RTTIHandle newIterator = new Internal.RTTIHandle{ Handle = 0, ClassTypeId = 0}; + + CheckError(Internal.RTTIWrapper.Zoo_Iterator (Handle, out newIterator)); + return Internal.RTTIWrapper.PolymorphicFactory<CAnimalIterator>(newIterator); + } + + } + + class Wrapper + { + private static void CheckError (Int32 errorCode) + { + if (errorCode != 0) { + Internal.RTTIWrapper.ThrowError (new Internal.RTTIHandle{ Handle = 0, ClassTypeId = 0 }, errorCode); + } + } + + public static void GetVersion (out UInt32 AMajor, out UInt32 AMinor, out UInt32 AMicro) + { + + CheckError(Internal.RTTIWrapper.GetVersion (out AMajor, out AMinor, out AMicro)); + } + + public static bool GetLastError (CBase AInstance, out String AErrorMessage) + { + Byte resultHasError = 0; + UInt32 sizeErrorMessage = 0; + UInt32 neededErrorMessage = 0; + CheckError(Internal.RTTIWrapper.GetLastError (AInstance.GetHandle(), sizeErrorMessage, out neededErrorMessage, IntPtr.Zero, out resultHasError)); + sizeErrorMessage = neededErrorMessage; + byte[] bytesErrorMessage = new byte[sizeErrorMessage]; + GCHandle dataErrorMessage = GCHandle.Alloc(bytesErrorMessage, GCHandleType.Pinned); + + CheckError(Internal.RTTIWrapper.GetLastError (AInstance.GetHandle(), sizeErrorMessage, out neededErrorMessage, dataErrorMessage.AddrOfPinnedObject(), out resultHasError)); + dataErrorMessage.Free(); + AErrorMessage = Encoding.UTF8.GetString(bytesErrorMessage).TrimEnd(char.MinValue); + return (resultHasError != 0); + } + + public static void ReleaseInstance (CBase AInstance) + { + + CheckError(Internal.RTTIWrapper.ReleaseInstance (AInstance.GetHandle())); + } + + public static void AcquireInstance (CBase AInstance) + { + + CheckError(Internal.RTTIWrapper.AcquireInstance (AInstance.GetHandle())); + } + + public static void InjectComponent (String ANameSpace, UInt64 ASymbolAddressMethod) + { + throw new Exception("Component injection is not supported in CSharp."); + } + + public static UInt64 GetSymbolLookupMethod () + { + UInt64 resultSymbolLookupMethod = 0; + + CheckError(Internal.RTTIWrapper.GetSymbolLookupMethod (out resultSymbolLookupMethod)); + return resultSymbolLookupMethod; + } + + public static CZoo CreateZoo () + { + Internal.RTTIHandle newInstance = new Internal.RTTIHandle{ Handle = 0, ClassTypeId = 0}; + + CheckError(Internal.RTTIWrapper.CreateZoo (out newInstance)); + return Internal.RTTIWrapper.PolymorphicFactory<CZoo>(newInstance); + } + + } + +} diff --git a/Examples/RTTI/RTTI_component/Examples/CSharp/README.md b/Examples/RTTI/RTTI_component/Examples/CSharp/README.md new file mode 100644 index 00000000..e17cc974 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/CSharp/README.md @@ -0,0 +1,23 @@ +## How to Build + +Initialize NuGet packages (run once): +``` +msbuild /p:Configuration=Debug /t:Restore RTTI_Example.csproj +``` + +Allow unsafe code during the build: +``` +msbuild /p:Configuration=Debug /p:AllowUnsafeBlocks=true RTTI_Example.csproj +``` + +## Run: +``` +DYLD_LIBRARY_PATH=_path_to_the_lib_ mono bin/Debug/netstandard2.0/RTTI_Example.dll +``` + +## Super command: +``` +../../Build/build.sh && rm -fr RTTI_component/Bindings/Go && ../../act.darwin RTTI.xml && msbuild /p:Configuration=Debug /p:AllowUnsafeBlocks=true RTTI_component/Examples/CSharp/RTTI_Example.csproj && DYLD_LIBRARY_PATH=_path_to_rtti_lib_ mono RTTI_component/Examples/CSharp/bin/Debug/netstandard2.0/RTTI_Example.dll +``` + +NOTE: On Mac original library has `rtti.dylib` name. Rename it or make a symlink `rtti.dll`. diff --git a/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.cs b/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.cs new file mode 100644 index 00000000..05446c09 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.cs @@ -0,0 +1,55 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated CSharp application that demonstrates the + usage of the CSharp bindings of RTTI + +Interface version: 1.0.0 + +*/ + + +using System; +namespace RTTI_Example +{ + class RTTI_Example + { + static void Main() + { + try + { + UInt32 nMajor, nMinor, nMicro; + RTTI.Wrapper.GetVersion(out nMajor, out nMinor, out nMicro); + string versionString = string.Format("RTTI.version = {0}.{1}.{2}", nMajor, nMinor, nMicro); + Console.WriteLine(versionString); + + RTTI.CZoo Zoo = RTTI.Wrapper.CreateZoo(); + RTTI.CAnimalIterator Iterator = Zoo.Iterator(); + + while (true) { + RTTI.CAnimal Animal = Iterator.GetNextAnimal(); + if (Animal.GetHandle().Handle == 0) + break; + Console.WriteLine("Animal name: " + Animal.Name()); + if (Animal is RTTI.CTiger) { + Console.WriteLine(" ^ is a real tiger!!!"); + (Animal as RTTI.CTiger).Roar(); + } + } + + } + catch (Exception e) + { + Console.WriteLine("Exception: \"" + e.Message + "\""); + } + Console.WriteLine("Press any key to exit."); + Console.ReadKey(); + } + } +} + diff --git a/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.csproj b/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.csproj new file mode 100644 index 00000000..02155e0f --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.csproj @@ -0,0 +1,19 @@ + +<Project Sdk="Microsoft.NET.Sdk"> + <PropertyGroup> + <OutputType>Exe</OutputType> + <TargetFramework>netstandard2.0</TargetFramework> + <StartupObject>RTTI_Example.RTTI_Example</StartupObject> + <ApplicationIcon /> + <Platforms>x64</Platforms> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + </PropertyGroup> + <ItemGroup> + <Compile Include="..\..\Bindings\CSharp\RTTI.cs" Link="RTTI.cs" /> + </ItemGroup> +</Project> diff --git a/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.sln b/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.sln new file mode 100644 index 00000000..15e7d137 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.539 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("4aaa827b-5f87-4959-8157-ddd119e0b20e") = "RTTI_Example", "RTTI_Example.csproj", "b753848c-eac6-4a48-b747-6b962ee2c914" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + b753848c-eac6-4a48-b747-6b962ee2c914.Debug|x64.ActiveCfg = Debug|x64 + b753848c-eac6-4a48-b747-6b962ee2c914.Debug|x64.Build.0 = Debug|x64 + b753848c-eac6-4a48-b747-6b962ee2c914.Release|x64.ActiveCfg = Release|x64 + b753848c-eac6-4a48-b747-6b962ee2c914.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = 6a901066-f61e-4ca7-88a9-c64df3a67acb + EndGlobalSection +EndGlobal diff --git a/Source/buildbindingcsharp.go b/Source/buildbindingcsharp.go index 2664231a..040cd005 100644 --- a/Source/buildbindingcsharp.go +++ b/Source/buildbindingcsharp.go @@ -200,11 +200,11 @@ func getCSharpParameterType(ParamTypeName string, NameSpace string, ParamClass s case "class", "optionalclass": if isPlain { - CSharpParamTypeName = "IntPtr" + CSharpParamTypeName = fmt.Sprintf("%sHandle", NameSpace) } else { paramNameSpace, _, _ := decomposeParamClassName(ParamClass) if len(paramNameSpace) > 0 { - CSharpParamTypeName = "IntPtr" + CSharpParamTypeName = fmt.Sprintf("%sHandle", NameSpace) } else { CSharpParamTypeName = "C" + ParamClass } @@ -518,10 +518,10 @@ func writeCSharpClassMethodImplementation(method ComponentDefinitionMethod, w La doInitCall = true case "class", "optionalclass": - defineCommands = append(defineCommands, fmt.Sprintf(" IntPtr new%s = IntPtr.Zero;", param.ParamName)) + defineCommands = append(defineCommands, fmt.Sprintf(" Internal.%sHandle new%s = Internal.%sHandle{ Handle = 0, ClassTypeId = 0};", NameSpace, NameSpace, param.ParamName)) callFunctionParameter = "out new" + param.ParamName initCallParameter = callFunctionParameter - resultCommands = append(resultCommands, fmt.Sprintf(" A%s = new C%s (new%s );", param.ParamName, param.ParamClass, param.ParamName)) + resultCommands = append(resultCommands, fmt.Sprintf(" A%s = Internal.RTTIWrapper.PolymorphicFactory<C%s>(new%s);", param.ParamName, param.ParamClass, param.ParamName)) default: return fmt.Errorf("invalid method parameter type \"%s\" for %s.%s (%s)", param.ParamType, ClassName, method.MethodName, param.ParamName) @@ -574,13 +574,13 @@ func writeCSharpClassMethodImplementation(method ComponentDefinitionMethod, w La returnCodeLines = append(returnCodeLines, fmt.Sprintf(" return Internal.%sWrapper.convertInternalToStruct_%s (intresult%s);", NameSpace, param.ParamClass, param.ParamName)) case "class", "optionalclass": - defineCommands = append(defineCommands, fmt.Sprintf(" IntPtr new%s = IntPtr.Zero;", param.ParamName)) + defineCommands = append(defineCommands, fmt.Sprintf(" Internal.%sHandle new%s = new Internal.%sHandle{ Handle = 0, ClassTypeId = 0};", NameSpace, param.ParamName, NameSpace)) callFunctionParameter = "out new" + param.ParamName initCallParameter = callFunctionParameter if (ParamTypeName == "IntPtr") { returnCodeLines = append(returnCodeLines, fmt.Sprintf(" return new%s;", param.ParamName)) } else { - returnCodeLines = append(returnCodeLines, fmt.Sprintf(" return new %s (new%s );", ParamTypeName, param.ParamName)) + returnCodeLines = append(returnCodeLines, fmt.Sprintf(" return Internal.RTTIWrapper.PolymorphicFactory<%s>(new%s);", ParamTypeName, param.ParamName)) } default: @@ -719,6 +719,14 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW w.Writeln(" namespace Internal {") w.Writeln("") + + w.Writeln(" [StructLayout(LayoutKind.Explicit, Size=16)]") + w.Writeln(" public unsafe struct %sHandle", NameSpace) + w.Writeln(" {") + w.Writeln(" [FieldOffset(0)] public UInt64 Handle;") + w.Writeln(" [FieldOffset(8)] public UInt64 ClassTypeId;") + w.Writeln(" }") + w.Writeln("") for i := 0; i < len(component.Structs); i++ { structinfo := component.Structs[i] @@ -816,9 +824,9 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW w.Writeln(" [DllImport(\"%s.dll\", EntryPoint = \"%s_%s_%s\", CallingConvention=CallingConvention.Cdecl)]", baseName, strings.ToLower(NameSpace), strings.ToLower(class.ClassName), strings.ToLower(method.MethodName)) if parameters == "" { - parameters = "IntPtr Handle" + parameters = "RTTIHandle Handle" } else { - parameters = "IntPtr Handle, " + parameters + parameters = "RTTIHandle Handle, " + parameters } w.Writeln(" public unsafe extern static Int32 %s_%s (%s);", class.ClassName, method.MethodName, parameters) @@ -932,12 +940,12 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW w.Writeln("") } - w.Writeln(" public static void ThrowError(IntPtr Handle, Int32 errorCode)") + w.Writeln(" public static void ThrowError(%sHandle Handle, Int32 errorCode)", NameSpace) w.Writeln(" {") w.Writeln(" String sMessage = \"%s Error\";", NameSpace) if len(component.Global.ErrorMethod) > 0 { - w.Writeln(" if (Handle != IntPtr.Zero) {") + w.Writeln(" if (Handle.Handle != 0) {") w.Writeln(" UInt32 sizeMessage = 0;") w.Writeln(" UInt32 neededMessage = 0;") w.Writeln(" Byte hasLastError = 0;") @@ -959,6 +967,22 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW } w.Writeln(" throw new Exception(sMessage + \"(# \" + errorCode + \")\");") w.Writeln(" }") + + w.Writeln("") + w.Writeln(" public static T PolymorphicFactory<T>(%sHandle Handle) where T : class", NameSpace) + w.Writeln(" {") + w.Writeln(" T Object;") + w.Writeln(" switch (Handle.ClassTypeId) {") + for i := 0; i < len(component.Classes); i++ { + class := component.Classes[i] + classTypeId, chashHashString := class.classTypeId(NameSpace) + w.Writeln(" case 0x%016X: Object = new C%s(Handle) as T; break; // First 64 bits of SHA1 of a string: \"%s\"", classTypeId, class.ClassName, chashHashString) + } + w.Writeln(" default: Object = System.Activator.CreateInstance(typeof(T), Handle) as T; break;") + w.Writeln(" }") + w.Writeln(" return Object;") + w.Writeln(" }") + w.Writeln("") w.Writeln(" }") @@ -983,18 +1007,18 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW w.Writeln(" {") if component.isBaseClass(class) { - w.Writeln(" protected IntPtr Handle;") + w.Writeln(" protected Internal.%sHandle Handle;", NameSpace) w.Writeln("") - w.Writeln(" public C%s (IntPtr NewHandle)", class.ClassName) + w.Writeln(" public C%s (Internal.%sHandle NewHandle)", class.ClassName, NameSpace) w.Writeln(" {") w.Writeln(" Handle = NewHandle;") w.Writeln(" }") w.Writeln("") w.Writeln(" ~C%s ()", class.ClassName) w.Writeln(" {") - w.Writeln(" if (Handle != IntPtr.Zero) {") + w.Writeln(" if (Handle.Handle != 0) {") w.Writeln(" Internal.%sWrapper.%s (Handle);", NameSpace, component.Global.ReleaseMethod) - w.Writeln(" Handle = IntPtr.Zero;") + w.Writeln(" Handle.Handle = 0;") w.Writeln(" }") w.Writeln(" }") w.Writeln("") @@ -1007,14 +1031,14 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW w.Writeln(" }") w.Writeln("") - w.Writeln(" public IntPtr GetHandle ()") + w.Writeln(" public Internal.%sHandle GetHandle ()", NameSpace) w.Writeln(" {") w.Writeln(" return Handle;") w.Writeln(" }") w.Writeln("") } else { - w.Writeln(" public C%s (IntPtr NewHandle) : base (NewHandle)", class.ClassName) + w.Writeln(" public C%s (Internal.%sHandle NewHandle) : base (NewHandle)", class.ClassName, NameSpace) w.Writeln(" {") w.Writeln(" }") w.Writeln("") @@ -1047,7 +1071,7 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW w.Writeln(" private static void CheckError (Int32 errorCode)") w.Writeln(" {") w.Writeln(" if (errorCode != 0) {") - w.Writeln(" Internal.%sWrapper.ThrowError (IntPtr.Zero, errorCode);", NameSpace) + w.Writeln(" Internal.%sWrapper.ThrowError (new Internal.%sHandle{ Handle = 0, ClassTypeId = 0 }, errorCode);", NameSpace, NameSpace) w.Writeln(" }") w.Writeln(" }") w.Writeln("") From 7c9ca063ab0cc9897915f2b37b0943353a0e7e94 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Fri, 22 Oct 2021 13:57:45 -0700 Subject: [PATCH 046/143] Add Java bindings support and example --- Examples/RTTI/RTTI.xml | 1 + .../Bindings/Java9/build_jar.sh | 12 + .../Bindings/Java9/rtti/Animal.java | 52 +++ .../Bindings/Java9/rtti/AnimalIterator.java | 53 +++ .../Bindings/Java9/rtti/Base.java | 81 +++++ .../Bindings/Java9/rtti/Giraffe.java | 37 ++ .../Bindings/Java9/rtti/Mammal.java | 37 ++ .../Bindings/Java9/rtti/RTTIException.java | 76 +++++ .../Bindings/Java9/rtti/RTTIHandle.java | 33 ++ .../Bindings/Java9/rtti/RTTIWrapper.java | 322 ++++++++++++++++++ .../Bindings/Java9/rtti/Reptile.java | 37 ++ .../Bindings/Java9/rtti/Snake.java | 37 ++ .../Bindings/Java9/rtti/TestStruct.java | 43 +++ .../Bindings/Java9/rtti/Tiger.java | 46 +++ .../Bindings/Java9/rtti/Turtle.java | 37 ++ .../Bindings/Java9/rtti/Zoo.java | 54 +++ .../Examples/Java9/RTTI_Example.java | 45 +++ .../RTTI_component/Examples/Java9/build.sh | 32 ++ Source/buildbindingjava.go | 118 ++++++- 19 files changed, 1136 insertions(+), 17 deletions(-) create mode 100644 Examples/RTTI/RTTI_component/Bindings/Java9/build_jar.sh create mode 100644 Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Animal.java create mode 100644 Examples/RTTI/RTTI_component/Bindings/Java9/rtti/AnimalIterator.java create mode 100644 Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Base.java create mode 100644 Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Giraffe.java create mode 100644 Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Mammal.java create mode 100644 Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIException.java create mode 100644 Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIHandle.java create mode 100644 Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIWrapper.java create mode 100644 Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Reptile.java create mode 100644 Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Snake.java create mode 100644 Examples/RTTI/RTTI_component/Bindings/Java9/rtti/TestStruct.java create mode 100644 Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Tiger.java create mode 100644 Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Turtle.java create mode 100644 Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Zoo.java create mode 100644 Examples/RTTI/RTTI_component/Examples/Java9/RTTI_Example.java create mode 100644 Examples/RTTI/RTTI_component/Examples/Java9/build.sh diff --git a/Examples/RTTI/RTTI.xml b/Examples/RTTI/RTTI.xml index d3670010..565f1c2c 100644 --- a/Examples/RTTI/RTTI.xml +++ b/Examples/RTTI/RTTI.xml @@ -11,6 +11,7 @@ <binding language="CDynamic" indentation="tabs" /> <binding language="Go" indentation="tabs" /> <binding language="CSharp" indentation="tabs" /> + <binding language="Java" indentation="tabs" /> </bindings> <implementations> <implementation language="Cpp" indentation="tabs"/> diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/build_jar.sh b/Examples/RTTI/RTTI_component/Bindings/Java9/build_jar.sh new file mode 100644 index 00000000..1ccec293 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/build_jar.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -euxo pipefail + +cd "$(dirname "$0")" +echo "Download JNA" +[ -f jna-5.5.0.jar ] || wget https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar + +echo "Compile Java Bindings" +javac -classpath *.jar rtti/* + +echo "Create JAR" +jar cvf rtti-1.0.0.jar rtti diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Animal.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Animal.java new file mode 100644 index 00000000..641c5851 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Animal.java @@ -0,0 +1,52 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +package rtti; + +import com.sun.jna.Library; +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import java.lang.ref.Cleaner; + + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; + +public class Animal extends Base { + + public Animal(RTTIWrapper wrapper, RTTIHandle handle) { + super(wrapper, handle); + } + + /** + * Get the name of the animal + * + * @return + * @throws RTTIException + */ + public String name() throws RTTIException { + Pointer bytesNeededResult = new Memory(4); + mWrapper.checkError(this, mWrapper.rtti_animal_name.invokeInt(new java.lang.Object[]{mHandle.Value(), 0, bytesNeededResult, null})); + int sizeResult = bytesNeededResult.getInt(0); + Pointer bufferResult = new Memory(sizeResult); + mWrapper.checkError(this, mWrapper.rtti_animal_name.invokeInt(new java.lang.Object[]{mHandle.Value(), sizeResult, bytesNeededResult, bufferResult})); + return new String(bufferResult.getByteArray(0, sizeResult - 1), StandardCharsets.UTF_8); + } + + +} + diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/AnimalIterator.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/AnimalIterator.java new file mode 100644 index 00000000..83fa7e93 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/AnimalIterator.java @@ -0,0 +1,53 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +package rtti; + +import com.sun.jna.Library; +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import java.lang.ref.Cleaner; + + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; + +public class AnimalIterator extends Base { + + public AnimalIterator(RTTIWrapper wrapper, RTTIHandle handle) { + super(wrapper, handle); + } + + /** + * Return next animal + * + * @return + * @throws RTTIException + */ + public Animal getNextAnimal() throws RTTIException { + RTTIHandle handleAnimal = new RTTIHandle(); + mWrapper.checkError(this, mWrapper.rtti_animaliterator_getnextanimal.invokeInt(new java.lang.Object[]{mHandle.Value(), handleAnimal})); + Animal animal = null; + if (handleAnimal.Handle != Pointer.NULL) { + animal = mWrapper.PolymorphicFactory(handleAnimal, Animal.class); + } + return animal; + } + + +} + diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Base.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Base.java new file mode 100644 index 00000000..682911f1 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Base.java @@ -0,0 +1,81 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +package rtti; + +import com.sun.jna.Library; +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import java.lang.ref.Cleaner; + + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; + +public class Base { + + protected static final Cleaner mCleaner = Cleaner.create(); + + protected RTTIHandle mHandle; + + protected RTTIWrapper mWrapper; + + public Base(RTTIWrapper wrapper, RTTIHandle handle) { + mHandle = handle; + mWrapper = wrapper; + mCleaner.register(this, new InstanceReleaser(this)); + } + + public RTTIHandle getHandle() { + return mHandle; + } + + protected static class InstanceReleaser implements Runnable{ + + protected RTTIHandle mHandle; + + protected RTTIWrapper mWrapper; + + protected InstanceReleaser(Base instance) { + mHandle = instance.mHandle; + mWrapper = instance.mWrapper; + } + + @Override + public void run() { + try { + mWrapper.checkError(null, mWrapper.rtti_releaseinstance.invokeInt(new java.lang.Object[]{mHandle.Value()})); + } catch (RTTIException e) { + e.printStackTrace(); + } + } + } + /** + * Get Class Type Id + * + * @return Class type as a 64 bits integer + * @throws RTTIException + */ + public long classTypeId() throws RTTIException { + Pointer bufferClassTypeId = new Memory(8); + mWrapper.checkError(this, mWrapper.rtti_base_classtypeid.invokeInt(new java.lang.Object[]{mHandle.Value(), bufferClassTypeId})); + return bufferClassTypeId.getLong(0); + } + + +} + diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Giraffe.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Giraffe.java new file mode 100644 index 00000000..3ecd7153 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Giraffe.java @@ -0,0 +1,37 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +package rtti; + +import com.sun.jna.Library; +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import java.lang.ref.Cleaner; + + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; + +public class Giraffe extends Mammal { + + public Giraffe(RTTIWrapper wrapper, RTTIHandle handle) { + super(wrapper, handle); + } + + +} + diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Mammal.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Mammal.java new file mode 100644 index 00000000..004c0616 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Mammal.java @@ -0,0 +1,37 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +package rtti; + +import com.sun.jna.Library; +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import java.lang.ref.Cleaner; + + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; + +public class Mammal extends Animal { + + public Mammal(RTTIWrapper wrapper, RTTIHandle handle) { + super(wrapper, handle); + } + + +} + diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIException.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIException.java new file mode 100644 index 00000000..89d2c6d1 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIException.java @@ -0,0 +1,76 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +package rtti; + +import java.util.HashMap; +import java.util.Map; + +public class RTTIException extends Exception { + + // Error Constants for RTTI + public static final int RTTI_SUCCESS = 0; + public static final int RTTI_ERROR_NOTIMPLEMENTED = 1; + public static final int RTTI_ERROR_INVALIDPARAM = 2; + public static final int RTTI_ERROR_INVALIDCAST = 3; + public static final int RTTI_ERROR_BUFFERTOOSMALL = 4; + public static final int RTTI_ERROR_GENERICEXCEPTION = 5; + public static final int RTTI_ERROR_COULDNOTLOADLIBRARY = 6; + public static final int RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT = 7; + public static final int RTTI_ERROR_INCOMPATIBLEBINARYVERSION = 8; + + public static final Map<Integer, String> ErrorCodeMap = new HashMap<Integer, String>(); + public static final Map<Integer, String> ErrorDescriptionMap = new HashMap<Integer, String>(); + + static { + ErrorCodeMap.put(RTTI_ERROR_NOTIMPLEMENTED, "RTTI_ERROR_NOTIMPLEMENTED"); + ErrorDescriptionMap.put(RTTI_ERROR_NOTIMPLEMENTED, "functionality not implemented"); + ErrorCodeMap.put(RTTI_ERROR_INVALIDPARAM, "RTTI_ERROR_INVALIDPARAM"); + ErrorDescriptionMap.put(RTTI_ERROR_INVALIDPARAM, "an invalid parameter was passed"); + ErrorCodeMap.put(RTTI_ERROR_INVALIDCAST, "RTTI_ERROR_INVALIDCAST"); + ErrorDescriptionMap.put(RTTI_ERROR_INVALIDCAST, "a type cast failed"); + ErrorCodeMap.put(RTTI_ERROR_BUFFERTOOSMALL, "RTTI_ERROR_BUFFERTOOSMALL"); + ErrorDescriptionMap.put(RTTI_ERROR_BUFFERTOOSMALL, "a provided buffer is too small"); + ErrorCodeMap.put(RTTI_ERROR_GENERICEXCEPTION, "RTTI_ERROR_GENERICEXCEPTION"); + ErrorDescriptionMap.put(RTTI_ERROR_GENERICEXCEPTION, "a generic exception occurred"); + ErrorCodeMap.put(RTTI_ERROR_COULDNOTLOADLIBRARY, "RTTI_ERROR_COULDNOTLOADLIBRARY"); + ErrorDescriptionMap.put(RTTI_ERROR_COULDNOTLOADLIBRARY, "the library could not be loaded"); + ErrorCodeMap.put(RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT, "RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT"); + ErrorDescriptionMap.put(RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT, "a required exported symbol could not be found in the library"); + ErrorCodeMap.put(RTTI_ERROR_INCOMPATIBLEBINARYVERSION, "RTTI_ERROR_INCOMPATIBLEBINARYVERSION"); + ErrorDescriptionMap.put(RTTI_ERROR_INCOMPATIBLEBINARYVERSION, "the version of the binary interface does not match the bindings interface"); + } + + protected int mErrorCode; + + protected String mErrorString; + + protected String mErrorDescription; + + public RTTIException(int errorCode, String message){ + super(message); + mErrorCode = errorCode; + mErrorString = ErrorCodeMap.get(errorCode); + mErrorString = (mErrorString != null) ? mErrorString : "Unknown error code"; + mErrorDescription = ErrorDescriptionMap.get(errorCode); + mErrorDescription = (mErrorDescription != null) ? mErrorDescription : ""; + } + + @Override + public String toString() { + return mErrorCode + ": " + mErrorString + " (" + mErrorDescription + " - " + getMessage() + ")"; + } +} + diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIHandle.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIHandle.java new file mode 100644 index 00000000..ed992850 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIHandle.java @@ -0,0 +1,33 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +package rtti; + +import com.sun.jna.*; + + @Structure.FieldOrder({"Handle", "ClassTypeId"}) + public class RTTIHandle extends Structure { + public Pointer Handle; + public long ClassTypeId; + + public static class ByValue extends RTTIHandle implements Structure.ByValue { + public ByValue() { super(); read(); } + public ByValue(RTTIHandle h) { super(h); read(); } + } + public RTTIHandle() { Handle = Pointer.NULL; ClassTypeId = 0; } + public RTTIHandle(RTTIHandle h) { super(h.getPointer()); read(); } + public ByValue Value() { return new ByValue(this); } + } + diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIWrapper.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIWrapper.java new file mode 100644 index 00000000..c9a77120 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIWrapper.java @@ -0,0 +1,322 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +package rtti; + +import com.sun.jna.*; + +import java.nio.charset.StandardCharsets; + + +public class RTTIWrapper { + + public static class EnumConversion { + } + + protected Function rtti_getversion; + protected Function rtti_getlasterror; + protected Function rtti_releaseinstance; + protected Function rtti_acquireinstance; + protected Function rtti_injectcomponent; + protected Function rtti_getsymbollookupmethod; + protected Function rtti_createzoo; + protected Function rtti_base_classtypeid; + protected Function rtti_animal_name; + protected Function rtti_tiger_roar; + protected Function rtti_animaliterator_getnextanimal; + protected Function rtti_zoo_iterator; + + protected NativeLibrary mLibrary; + + public RTTIWrapper(String libraryPath) { + mLibrary = NativeLibrary.getInstance(libraryPath); + rtti_getversion = mLibrary.getFunction("rtti_getversion"); + rtti_getlasterror = mLibrary.getFunction("rtti_getlasterror"); + rtti_releaseinstance = mLibrary.getFunction("rtti_releaseinstance"); + rtti_acquireinstance = mLibrary.getFunction("rtti_acquireinstance"); + rtti_injectcomponent = mLibrary.getFunction("rtti_injectcomponent"); + rtti_getsymbollookupmethod = mLibrary.getFunction("rtti_getsymbollookupmethod"); + rtti_createzoo = mLibrary.getFunction("rtti_createzoo"); + rtti_base_classtypeid = mLibrary.getFunction("rtti_base_classtypeid"); + rtti_animal_name = mLibrary.getFunction("rtti_animal_name"); + rtti_tiger_roar = mLibrary.getFunction("rtti_tiger_roar"); + rtti_animaliterator_getnextanimal = mLibrary.getFunction("rtti_animaliterator_getnextanimal"); + rtti_zoo_iterator = mLibrary.getFunction("rtti_zoo_iterator"); + } + + public RTTIWrapper(Pointer lookupPointer) throws RTTIException { + Function lookupMethod = Function.getFunction(lookupPointer); + rtti_getversion = loadFunctionByLookup(lookupMethod, "rtti_getversion"); + rtti_getlasterror = loadFunctionByLookup(lookupMethod, "rtti_getlasterror"); + rtti_releaseinstance = loadFunctionByLookup(lookupMethod, "rtti_releaseinstance"); + rtti_acquireinstance = loadFunctionByLookup(lookupMethod, "rtti_acquireinstance"); + rtti_injectcomponent = loadFunctionByLookup(lookupMethod, "rtti_injectcomponent"); + rtti_getsymbollookupmethod = loadFunctionByLookup(lookupMethod, "rtti_getsymbollookupmethod"); + rtti_createzoo = loadFunctionByLookup(lookupMethod, "rtti_createzoo"); + rtti_base_classtypeid = loadFunctionByLookup(lookupMethod, "rtti_base_classtypeid"); + rtti_animal_name = loadFunctionByLookup(lookupMethod, "rtti_animal_name"); + rtti_tiger_roar = loadFunctionByLookup(lookupMethod, "rtti_tiger_roar"); + rtti_animaliterator_getnextanimal = loadFunctionByLookup(lookupMethod, "rtti_animaliterator_getnextanimal"); + rtti_zoo_iterator = loadFunctionByLookup(lookupMethod, "rtti_zoo_iterator"); + } + + protected void checkError(Base instance, int errorCode) throws RTTIException { + if (instance != null && instance.mWrapper != this) { + throw new RTTIException(RTTIException.RTTI_ERROR_INVALIDCAST, "invalid wrapper call"); + } + if (errorCode != RTTIException.RTTI_SUCCESS) { + if (instance != null) { + GetLastErrorResult result = getLastError(instance); + throw new RTTIException(errorCode, result.ErrorMessage); + } else { + throw new RTTIException(errorCode, ""); + } + } + } + + private Function loadFunctionByLookup(Function lookupMethod, String functionName) throws RTTIException { + byte[] bytes = functionName.getBytes(StandardCharsets.UTF_8); + Memory name = new Memory(bytes.length+1); + name.write(0, bytes, 0, bytes.length); + name.setByte(bytes.length, (byte)0); + Pointer address = new Memory(8); + java.lang.Object[] addressParam = new java.lang.Object[]{name, address}; + checkError(null, lookupMethod.invokeInt(addressParam)); + return Function.getFunction(address.getPointer(0)); + } + + /** + * retrieves the binary version of this library. + * + * @return GetVersion Result Tuple + * @throws RTTIException + */ + public GetVersionResult getVersion() throws RTTIException { + Pointer bufferMajor = new Memory(4); + Pointer bufferMinor = new Memory(4); + Pointer bufferMicro = new Memory(4); + checkError(null, rtti_getversion.invokeInt(new java.lang.Object[]{bufferMajor, bufferMinor, bufferMicro})); + GetVersionResult returnTuple = new GetVersionResult(); + returnTuple.Major = bufferMajor.getInt(0); + returnTuple.Minor = bufferMinor.getInt(0); + returnTuple.Micro = bufferMicro.getInt(0); + return returnTuple; + } + + public static class GetVersionResult { + /** + * returns the major version of this library + */ + public int Major; + + /** + * returns the minor version of this library + */ + public int Minor; + + /** + * returns the micro version of this library + */ + public int Micro; + + } + /** + * Returns the last error recorded on this object + * + * @param instance Instance Handle + * @return GetLastError Result Tuple + * @throws RTTIException + */ + public GetLastErrorResult getLastError(Base instance) throws RTTIException { + RTTIHandle.ByValue instanceHandle; + if (instance != null) { + instanceHandle = instance.getHandle().Value(); + } else { + throw new RTTIException(RTTIException.RTTI_ERROR_INVALIDPARAM, "Instance is a null value."); + } + Pointer bytesNeededErrorMessage = new Memory(4); + Pointer bufferHasError = new Memory(1); + checkError(null, rtti_getlasterror.invokeInt(new java.lang.Object[]{instanceHandle, 0, bytesNeededErrorMessage, null, bufferHasError})); + int sizeErrorMessage = bytesNeededErrorMessage.getInt(0); + Pointer bufferErrorMessage = new Memory(sizeErrorMessage); + checkError(null, rtti_getlasterror.invokeInt(new java.lang.Object[]{instanceHandle, sizeErrorMessage, bytesNeededErrorMessage, bufferErrorMessage, bufferHasError})); + GetLastErrorResult returnTuple = new GetLastErrorResult(); + returnTuple.ErrorMessage = new String(bufferErrorMessage.getByteArray(0, sizeErrorMessage - 1), StandardCharsets.UTF_8); + returnTuple.HasError = bufferHasError.getByte(0) != 0; + return returnTuple; + } + + public static class GetLastErrorResult { + /** + * Message of the last error + */ + public String ErrorMessage; + + /** + * Is there a last error to query + */ + public boolean HasError; + + } + /** + * Releases shared ownership of an Instance + * + * @param instance Instance Handle + * @throws RTTIException + */ + public void releaseInstance(Base instance) throws RTTIException { + RTTIHandle.ByValue instanceHandle; + if (instance != null) { + instanceHandle = instance.getHandle().Value(); + } else { + throw new RTTIException(RTTIException.RTTI_ERROR_INVALIDPARAM, "Instance is a null value."); + } + checkError(null, rtti_releaseinstance.invokeInt(new java.lang.Object[]{instanceHandle})); + } + + /** + * Acquires shared ownership of an Instance + * + * @param instance Instance Handle + * @throws RTTIException + */ + public void acquireInstance(Base instance) throws RTTIException { + RTTIHandle.ByValue instanceHandle; + if (instance != null) { + instanceHandle = instance.getHandle().Value(); + } else { + throw new RTTIException(RTTIException.RTTI_ERROR_INVALIDPARAM, "Instance is a null value."); + } + checkError(null, rtti_acquireinstance.invokeInt(new java.lang.Object[]{instanceHandle})); + } + + /** + * Injects an imported component for usage within this component + * + * @param nameSpace NameSpace of the injected component + * @param symbolAddressMethod Address of the SymbolAddressMethod of the injected component + * @throws RTTIException + */ + public void injectComponent(String nameSpace, Pointer symbolAddressMethod) throws RTTIException { + byte[] bytesNameSpace = nameSpace.getBytes(StandardCharsets.UTF_8); + Memory bufferNameSpace = new Memory(bytesNameSpace.length + 1); + bufferNameSpace.write(0, bytesNameSpace, 0, bytesNameSpace.length); + bufferNameSpace.setByte(bytesNameSpace.length, (byte)0); + checkError(null, rtti_injectcomponent.invokeInt(new java.lang.Object[]{bufferNameSpace, symbolAddressMethod})); + + boolean nameSpaceFound = false; + if (!nameSpaceFound) { + throw new RTTIException(RTTIException.RTTI_ERROR_COULDNOTLOADLIBRARY, "Unknown namespace " + nameSpace); + } + } + + /** + * Returns the address of the SymbolLookupMethod + * + * @return Address of the SymbolAddressMethod + * @throws RTTIException + */ + public Pointer getSymbolLookupMethod() throws RTTIException { + Pointer bufferSymbolLookupMethod = new Memory(8); + checkError(null, rtti_getsymbollookupmethod.invokeInt(new java.lang.Object[]{bufferSymbolLookupMethod})); + return bufferSymbolLookupMethod.getPointer(0); + } + + /** + * Create a new zoo with animals + * + * @return + * @throws RTTIException + */ + public Zoo createZoo() throws RTTIException { + RTTIHandle handleInstance = new RTTIHandle(); + checkError(null, rtti_createzoo.invokeInt(new java.lang.Object[]{handleInstance})); + Zoo instance = null; + if (handleInstance.Handle == Pointer.NULL) { + throw new RTTIException(RTTIException.RTTI_ERROR_INVALIDPARAM, "Instance was a null pointer"); + } + instance = this.PolymorphicFactory(handleInstance, Zoo.class); + return instance; + } + + public <T> T PolymorphicFactory(RTTIHandle handle, Class<T> cls) { + Class[] cArg = new Class[2]; + cArg[0] = RTTIWrapper.class; + cArg[1] = RTTIHandle.class; + + try { + int msbId = (int)(handle.ClassTypeId >> 32); + int lsbId = (int)handle.ClassTypeId; + T obj = null; + switch(msbId) { + case 0xBC9D5FA7: + switch(lsbId) { + case 0x750C1020: obj = (T)(new Mammal(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Mammal" + } + break; + case 0x6756AA8E: + switch(lsbId) { + case 0xA5802EC3: obj = (T)(new Reptile(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Reptile" + } + break; + case 0x08D007E7: + switch(lsbId) { + case 0xB5F7BAF4: obj = (T)(new Tiger(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Tiger" + } + break; + case 0x8E551B20: + switch(lsbId) { + case 0x8A2E8321: obj = (T)(new Turtle(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Turtle" + } + break; + case 0xF1917FE6: + switch(lsbId) { + case 0xBBE77831: obj = (T)(new AnimalIterator(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" + } + break; + case 0x1549AD28: + switch(lsbId) { + case 0x813DAE05: obj = (T)(new Base(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Base" + } + break; + case 0x9751971B: + switch(lsbId) { + case 0xD2C2D958: obj = (T)(new Giraffe(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Giraffe" + } + break; + case 0x5F6826EF: + switch(lsbId) { + case 0x909803B2: obj = (T)(new Snake(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Snake" + } + break; + case 0x2262ABE8: + switch(lsbId) { + case 0x0A5E7878: obj = (T)(new Zoo(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Zoo" + } + break; + case 0x8B40467D: + switch(lsbId) { + case 0xA6D327AF: obj = (T)(new Animal(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Animal" + } + break; + } + return obj; + } + catch(Exception e) { + return null; + } + } +} + diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Reptile.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Reptile.java new file mode 100644 index 00000000..623c83d1 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Reptile.java @@ -0,0 +1,37 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +package rtti; + +import com.sun.jna.Library; +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import java.lang.ref.Cleaner; + + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; + +public class Reptile extends Animal { + + public Reptile(RTTIWrapper wrapper, RTTIHandle handle) { + super(wrapper, handle); + } + + +} + diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Snake.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Snake.java new file mode 100644 index 00000000..45a1a4a1 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Snake.java @@ -0,0 +1,37 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +package rtti; + +import com.sun.jna.Library; +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import java.lang.ref.Cleaner; + + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; + +public class Snake extends Reptile { + + public Snake(RTTIWrapper wrapper, RTTIHandle handle) { + super(wrapper, handle); + } + + +} + diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/TestStruct.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/TestStruct.java new file mode 100644 index 00000000..5ec209c2 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/TestStruct.java @@ -0,0 +1,43 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +package rtti; + +import com.sun.jna.Memory; +import com.sun.jna.Pointer; + +import java.util.Arrays; +import java.util.List; + +public class TestStruct { + + public int X; + + public int Y; + + public static final int SIZE = 8; + + public void readFromPointer(Pointer p, long offset) { + X = p.getInt(offset + 0); + Y = p.getInt(offset + 4); + } + + public void writeToPointer(Pointer p, long offset) { + p.setInt(offset + 0, X); + p.setInt(offset + 4, Y); + } + +} + diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Tiger.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Tiger.java new file mode 100644 index 00000000..70077437 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Tiger.java @@ -0,0 +1,46 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +package rtti; + +import com.sun.jna.Library; +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import java.lang.ref.Cleaner; + + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; + +public class Tiger extends Mammal { + + public Tiger(RTTIWrapper wrapper, RTTIHandle handle) { + super(wrapper, handle); + } + + /** + * Roar like a tiger + * + * @throws RTTIException + */ + public void roar() throws RTTIException { + mWrapper.checkError(this, mWrapper.rtti_tiger_roar.invokeInt(new java.lang.Object[]{mHandle.Value()})); + } + + +} + diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Turtle.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Turtle.java new file mode 100644 index 00000000..f10117b8 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Turtle.java @@ -0,0 +1,37 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +package rtti; + +import com.sun.jna.Library; +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import java.lang.ref.Cleaner; + + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; + +public class Turtle extends Reptile { + + public Turtle(RTTIWrapper wrapper, RTTIHandle handle) { + super(wrapper, handle); + } + + +} + diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Zoo.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Zoo.java new file mode 100644 index 00000000..f01b465c --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Zoo.java @@ -0,0 +1,54 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of RTTI + +Interface version: 1.0.0 + +*/ + +package rtti; + +import com.sun.jna.Library; +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import java.lang.ref.Cleaner; + + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; + +public class Zoo extends Base { + + public Zoo(RTTIWrapper wrapper, RTTIHandle handle) { + super(wrapper, handle); + } + + /** + * Return an iterator over all zoo animals + * + * @return + * @throws RTTIException + */ + public AnimalIterator iterator() throws RTTIException { + RTTIHandle handleIterator = new RTTIHandle(); + mWrapper.checkError(this, mWrapper.rtti_zoo_iterator.invokeInt(new java.lang.Object[]{mHandle.Value(), handleIterator})); + AnimalIterator iterator = null; + if (handleIterator.Handle == Pointer.NULL) { + throw new RTTIException(RTTIException.RTTI_ERROR_INVALIDPARAM, "Iterator was a null pointer"); + } + iterator = mWrapper.PolymorphicFactory(handleIterator, AnimalIterator.class); + return iterator; + } + + +} + diff --git a/Examples/RTTI/RTTI_component/Examples/Java9/RTTI_Example.java b/Examples/RTTI/RTTI_component/Examples/Java9/RTTI_Example.java new file mode 100644 index 00000000..188bb100 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Java9/RTTI_Example.java @@ -0,0 +1,45 @@ +/*++ + +Copyright (C) 2021 ADSK + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java application that demonstrates the + usage of the Java bindings of RTTI + +Interface version: 1.0.0 + +*/ + + +import rtti.*; + +public class RTTI_Example { + + public static String libpath = "/Users/anpiloa/git/AutomaticComponentToolkit/Examples/RTTI/build-lib/rtti.dylib"; // TODO add the location of the shared library binary here + + public static void main(String[] args) throws RTTIException { + RTTIWrapper wrapper = new RTTIWrapper(libpath); + + RTTIWrapper.GetVersionResult version = wrapper.getVersion(); + System.out.print("RTTI version: " + version.Major + "." + version.Minor + "." + version.Micro); + System.out.println(); + + Zoo zoo = wrapper.createZoo(); + + AnimalIterator iterator = zoo.iterator(); + while (true) { + Animal animal = iterator.getNextAnimal(); + if (animal == null) break; + System.out.print("Animal name: " + animal.name()); + System.out.println(); + if (animal instanceof Tiger) { + System.out.println(" ^ is a real tiger!!!"); + ((Tiger)animal).roar(); + } + } + } +} + diff --git a/Examples/RTTI/RTTI_component/Examples/Java9/build.sh b/Examples/RTTI/RTTI_component/Examples/Java9/build.sh new file mode 100644 index 00000000..4bba3e9a --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Java9/build.sh @@ -0,0 +1,32 @@ +#!/bin/bash +set -euxo pipefail + +cd "$(dirname "$0")" + +JnaJar="jna-5.5.0.jar" +Classpath=".:${JnaJar}:../../Bindings/Java9/" +if [[ "$OSTYPE" == "linux-gnu" ]]; then + Classpath=".:${JnaJar}:../../Bindings/Java9/" +elif [[ "$OSTYPE" == "darwin"* ]]; then + Classpath=".:${JnaJar}:../../Bindings/Java9/" +elif [[ "$OSTYPE" == "cygwin" ]]; then + Classpath=".;${JnaJar};../../Bindings/Java9/" +elif [[ "$OSTYPE" == "msys" ]]; then + Classpath=".;${JnaJar};../../Bindings/Java9/" +elif [[ "$OSTYPE" == "win32" ]]; then + Classpath=".;${JnaJar};../../Bindings/Java9/" +else + echo "Unknown system: "$OSTYPE + exit 1 +fi + +echo "Download JNA" +[ -f jna-5.5.0.jar ] || wget https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar + +echo "Compile Java bindings" +javac -classpath "${JnaJar}" ../../Bindings/Java9/rtti/*.java +echo "Compile Java example" +javac -classpath $Classpath RTTI_Example.java + +echo "Execute example" +java -classpath $Classpath RTTI_Example diff --git a/Source/buildbindingjava.go b/Source/buildbindingjava.go index 89628acc..12dd3838 100644 --- a/Source/buildbindingjava.go +++ b/Source/buildbindingjava.go @@ -68,7 +68,24 @@ func BuildBindingJavaDynamic(component ComponentDefinition, outputFolder string, if err != nil { return err; } + + JavaHanldeName := namespace + "Handle"; + JavaHanldePath := path.Join(JavaFolder, JavaHanldeName + ".java"); + log.Printf("Creating \"%s\"", JavaHanldePath) + JavaHanldeFile, err := CreateLanguageFile (JavaHanldePath, indent) + if err != nil { + return err; + } + + JavaHanldeFile.WriteJavaLicenseHeader(component, + fmt.Sprintf("This is an autogenerated Java file in order to allow an easy\n use of %s", libraryname), + true) + err = buildJavaHandle(component, JavaHanldeFile, indent) + if err != nil { + return err; + } + JavaWrapperName := namespace + "Wrapper"; JavaWrapperPath := path.Join(JavaFolder, JavaWrapperName + ".java"); log.Printf("Creating \"%s\"", JavaWrapperPath) @@ -263,6 +280,9 @@ func buildJavaBuildExampleScript(component ComponentDefinition, w LanguageWriter } w.Writeln("#!/bin/bash") + w.Writeln("set -euxo pipefail") + w.Writeln("") + w.Writeln("cd \"$(dirname \"$0\")\"") w.Writeln("") w.Writeln("JnaJar=\"jna-5.5.0.jar\"") w.Writeln("Classpath=\".:${JnaJar}:../../Bindings/Java%d/\"", version) @@ -282,7 +302,7 @@ func buildJavaBuildExampleScript(component ComponentDefinition, w LanguageWriter w.Writeln("fi") w.Writeln("") w.Writeln("echo \"Download JNA\"") - w.Writeln("wget https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar") + w.Writeln("[ -f jna-5.5.0.jar ] || wget https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar") w.Writeln("") w.Writeln("echo \"Compile Java bindings\"") w.Writeln("javac -classpath \"${JnaJar}\" %s", imports) @@ -302,9 +322,11 @@ func buildJavaBuildScript(component ComponentDefinition, w LanguageWriter) error } w.Writeln("#!/bin/bash") + w.Writeln("set -euxo pipefail") w.Writeln("") + w.Writeln("cd \"$(dirname \"$0\")\"") w.Writeln("echo \"Download JNA\"") - w.Writeln("wget https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar") + w.Writeln("[ -f jna-5.5.0.jar ] || wget https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar") w.Writeln("") w.Writeln("echo \"Compile Java Bindings\"") w.Writeln("javac -classpath *.jar " + imports) @@ -404,13 +426,13 @@ func buildJavaClass(component ComponentDefinition, w LanguageWriter, indent stri w.Writeln(" protected static final Cleaner mCleaner = Cleaner.create();") w.Writeln("") } - w.Writeln(" protected Pointer mHandle;") + w.Writeln(" protected %sHandle mHandle;", component.NameSpace) w.Writeln("") w.Writeln(" protected %sWrapper mWrapper;", component.NameSpace) w.Writeln("") } - w.Writeln(" public %s(%sWrapper wrapper, Pointer handle) {", class.ClassName, component.NameSpace) + w.Writeln(" public %s(%sWrapper wrapper, %sHandle handle) {", class.ClassName, component.NameSpace, component.NameSpace) if component.isBaseClass(class) { w.Writeln(" mHandle = handle;") w.Writeln(" mWrapper = wrapper;") @@ -424,14 +446,14 @@ func buildJavaClass(component ComponentDefinition, w LanguageWriter, indent stri w.Writeln("") if component.isBaseClass(class) { - w.Writeln(" public Pointer getHandle() {") + w.Writeln(" public %sHandle getHandle() {", component.NameSpace) w.Writeln(" return mHandle;") w.Writeln(" }") w.Writeln(" ") if version >= 9 { w.Writeln(" protected static class InstanceReleaser implements Runnable{") w.Writeln(" ") - w.Writeln(" protected Pointer mHandle;") + w.Writeln(" protected %sHandle mHandle;", component.NameSpace) w.Writeln(" ") w.Writeln(" protected %sWrapper mWrapper;", NameSpace) w.Writeln(" ") @@ -443,7 +465,7 @@ func buildJavaClass(component ComponentDefinition, w LanguageWriter, indent stri w.Writeln(" @Override") w.Writeln(" public void run() {") w.Writeln(" try {") - w.Writeln(" mWrapper.checkError(null, mWrapper.%s_%s.invokeInt(new java.lang.Object[]{mHandle}));", strings.ToLower(NameSpace), strings.ToLower(component.Global.ReleaseMethod)) + w.Writeln(" mWrapper.checkError(null, mWrapper.%s_%s.invokeInt(new java.lang.Object[]{mHandle.Value()}));", strings.ToLower(NameSpace), strings.ToLower(component.Global.ReleaseMethod)) w.Writeln(" } catch (%sException e) {", NameSpace) w.Writeln(" e.printStackTrace();") w.Writeln(" }") @@ -517,7 +539,7 @@ func writeJavaClassMethodImplementation(method ComponentDefinitionMethod, w Lang wrapperInstanceName = "this" } else { callFunctionName = fmt.Sprintf("%s_%s_%s", strings.ToLower(NameSpace), strings.ToLower(ClassName), strings.ToLower(method.MethodName)) - callFunctionParameters = "mHandle" + callFunctionParameters = "mHandle.Value()" errorInstanceHandle = "this" wrapperCallPrefix = "mWrapper." wrapperInstanceName = "mWrapper" @@ -617,9 +639,9 @@ func writeJavaClassMethodImplementation(method ComponentDefinitionMethod, w Lang initCallParameters = initCallParameters + MakeFirstLowerCase(param.ParamName) case "class", "optionalclass": - initCommands = append(initCommands, "Pointer " + MakeFirstLowerCase(param.ParamName) + "Handle = null;") + initCommands = append(initCommands, fmt.Sprintf("%sHandle.ByValue ", NameSpace) + MakeFirstLowerCase(param.ParamName) + "Handle;") initCommands = append(initCommands, fmt.Sprintf("if (%s != null) {", MakeFirstLowerCase(param.ParamName))) - initCommands = append(initCommands, indent + MakeFirstLowerCase(param.ParamName) + "Handle = " + MakeFirstLowerCase(param.ParamName) + ".getHandle();") + initCommands = append(initCommands, indent + MakeFirstLowerCase(param.ParamName) + "Handle = " + MakeFirstLowerCase(param.ParamName) + ".getHandle().Value();") if (param.ParamType == "optionalclass") { } else { @@ -748,19 +770,18 @@ func writeJavaClassMethodImplementation(method ComponentDefinitionMethod, w Lang } else { theNameSpace = NameSpace } - initCommands = append(initCommands, "Pointer buffer" + param.ParamName + " = new Memory(8);") - callFunctionParameters = callFunctionParameters + "buffer" + param.ParamName - resultCommands = append(resultCommands, fmt.Sprintf("Pointer value%s = buffer%s.getPointer(0);", param.ParamName, param.ParamName)) + initCommands = append(initCommands, fmt.Sprintf("%sHandle handle%s = new %sHandle();", NameSpace, param.ParamName, NameSpace)) + callFunctionParameters = callFunctionParameters + "handle" + param.ParamName resultCommands = append(resultCommands, fmt.Sprintf("%s %s = null;", theParamClass, MakeFirstLowerCase(param.ParamName))) if param.ParamType == "class" { - resultCommands = append(resultCommands, fmt.Sprintf("if (value%s == Pointer.NULL) {", param.ParamName)) + resultCommands = append(resultCommands, fmt.Sprintf("if (handle%s.Handle == Pointer.NULL) {", param.ParamName)) resultCommands = append(resultCommands, fmt.Sprintf(" throw new %sException(%sException.%s_ERROR_INVALIDPARAM, \"%s was a null pointer\");", NameSpace, NameSpace, strings.ToUpper(NameSpace), param.ParamName)) resultCommands = append(resultCommands, "}") - resultCommands = append(resultCommands, fmt.Sprintf("%s = new %s(%s, value%s);", MakeFirstLowerCase(param.ParamName), theParamClass, theWrapperInstance, param.ParamName)) + resultCommands = append(resultCommands, fmt.Sprintf("%s = %s.PolymorphicFactory(handle%s, %s.class);", MakeFirstLowerCase(param.ParamName), theWrapperInstance, param.ParamName, theParamClass)) } else { - resultCommands = append(resultCommands, fmt.Sprintf("if (value%s != Pointer.NULL) {", param.ParamName)) - resultCommands = append(resultCommands, fmt.Sprintf(" %s = new %s(%s, value%s);", MakeFirstLowerCase(param.ParamName), theParamClass, theWrapperInstance, param.ParamName)) + resultCommands = append(resultCommands, fmt.Sprintf("if (handle%s.Handle != Pointer.NULL) {", param.ParamName)) + resultCommands = append(resultCommands, fmt.Sprintf(" %s = %s.PolymorphicFactory(handle%s, %s.class);", MakeFirstLowerCase(param.ParamName), theWrapperInstance, param.ParamName, theParamClass)) resultCommands = append(resultCommands, "}") } ReturnItem.ParamValue = fmt.Sprintf("%s;", MakeFirstLowerCase(param.ParamName)) @@ -954,6 +975,30 @@ func buildJavaStruct(component ComponentDefinition, w LanguageWriter, indent str w.Writeln("") return nil } +func buildJavaHandle(component ComponentDefinition, w LanguageWriter, indent string) error { + NameSpace := component.NameSpace + + w.Writeln("package %s;", strings.ToLower(NameSpace)) + w.Writeln("") + w.Writeln("import com.sun.jna.*;") + w.Writeln("") + + w.Writeln(" @Structure.FieldOrder({\"Handle\", \"ClassTypeId\"})") + w.Writeln(" public class %sHandle extends Structure {", NameSpace) + w.Writeln(" public Pointer Handle;") + w.Writeln(" public long ClassTypeId;") + w.Writeln(" ") + w.Writeln(" public static class ByValue extends %sHandle implements Structure.ByValue {", NameSpace) + w.Writeln(" public ByValue() { super(); read(); }") + w.Writeln(" public ByValue(%sHandle h) { super(h); read(); }", NameSpace) + w.Writeln(" }") + w.Writeln(" public %sHandle() { Handle = Pointer.NULL; ClassTypeId = 0; }", NameSpace) + w.Writeln(" public %sHandle(%sHandle h) { super(h.getPointer()); read(); }", NameSpace, NameSpace) + w.Writeln(" public ByValue Value() { return new ByValue(this); }") + w.Writeln(" }") + w.Writeln("") + return nil +} func buildJavaWrapper(component ComponentDefinition, w LanguageWriter, indent string) error { @@ -1181,6 +1226,45 @@ func buildJavaWrapper(component ComponentDefinition, w LanguageWriter, indent st } } + // Write PolymorphicFactory + w.Writeln(" public <T> T PolymorphicFactory(%sHandle handle, Class<T> cls) {", NameSpace) + w.Writeln(" Class[] cArg = new Class[2];") + w.Writeln(" cArg[0] = %sWrapper.class;", NameSpace) + w.Writeln(" cArg[1] = %sHandle.class;", NameSpace) + w.Writeln(" ") + w.Writeln(" try {") + w.Writeln(" T obj = null;") + w.Writeln(" int msbId = (int)(handle.ClassTypeId >> 32); ") + w.Writeln(" int lsbId = (int)handle.ClassTypeId; ") + + msbIds := make(map[uint32][]ComponentDefinitionClass) + for i := 0; i < len(component.Classes); i++ { + class := component.Classes[i] + classTypeId, _ := class.classTypeId(NameSpace) + msb := uint32((classTypeId >> 32) & 0xFFFFFFFF) + msbIds[msb] = append(msbIds[msb], class) + } + w.Writeln(" switch(msbId) {") + for id, classes := range msbIds { + w.Writeln(" case 0x%08X: ", id) + w.Writeln(" switch(lsbId) {") + for i := 0; i < len(classes); i++ { + class := classes[i] + ClassTypeId, chashHashString := class.classTypeId(NameSpace) + lsbId := uint32(ClassTypeId & 0xFFFFFFFF) + w.Writeln(" case 0x%08X: obj = (T)(new %s(this, handle)); break; // First 64 bits of SHA1 of a string: \"%s\"", lsbId, class.ClassName, chashHashString) + } + w.Writeln(" }") + w.Writeln(" break;") + } + w.Writeln(" }") + + w.Writeln(" return obj;") + w.Writeln(" }") + w.Writeln(" catch(Exception e) {") + w.Writeln(" return null;") + w.Writeln(" }") + w.Writeln(" }") w.Writeln("}") w.Writeln("") From 03f82ce7ca0b4853607dae2536ba6e6eb8b36e4b Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Fri, 22 Oct 2021 13:58:04 -0700 Subject: [PATCH 047/143] Missed changes in IDL file --- Examples/RTTI/RTTI.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Examples/RTTI/RTTI.xml b/Examples/RTTI/RTTI.xml index 565f1c2c..5320da63 100644 --- a/Examples/RTTI/RTTI.xml +++ b/Examples/RTTI/RTTI.xml @@ -9,10 +9,15 @@ <bindings> <binding language="CDynamic" indentation="tabs" /> - <binding language="Go" indentation="tabs" /> + <binding language="CppDynamic" indentation="tabs" /> + <binding language="Cpp" indentation="tabs" /> + <binding language="Pascal" indentation="2spaces" /> + <binding language="Python" indentation="tabs" /> <binding language="CSharp" indentation="tabs" /> + <binding language="Go" indentation="tabs" /> <binding language="Java" indentation="tabs" /> </bindings> + <implementations> <implementation language="Cpp" indentation="tabs"/> <implementation language="Pascal" indentation="tabs" stubidentifier="impl"/> From d08c4358c01d00b827f72b7972e977cdd1b0a457 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 21:47:05 -0700 Subject: [PATCH 048/143] Better filtet for build files --- .gitignore | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 3404bb66..a848edf5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,24 @@ -*.cpp -*.hpp -*.h *.exe *.linux *.darwin *.exe +*.dylib +*.so +*.dll *.arm -*.c -*.go *.orig +*.class +*.jar +*.log +*.o +*.ppu +__pycache__ + +Examples/**/build +Examples/**/build-* # Visual Studio Code debug .vscode -*_headers -*_component - -Examples/*.xml +.DS_Store \ No newline at end of file From 565820842f612ebad6187368c744a886611687db Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 21:47:28 -0700 Subject: [PATCH 049/143] Common build bash script --- Build/build.inc | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 Build/build.inc diff --git a/Build/build.inc b/Build/build.inc new file mode 100644 index 00000000..36f6dcba --- /dev/null +++ b/Build/build.inc @@ -0,0 +1,51 @@ +#!/bin/bash + +set -euxo pipefail + +RUN () { + CMD=$1 + OS="`uname`" + case $OS in + Linux*) + OSLD_LIBRARY_PATH="LD_LIBRARY_PATH=$2" + for i in "${@:3}" + do + OSLD_LIBRARY_PATH=$OSLD_LIBRARY_PATH:$i + done + eval $OSLD_LIBRARY_PATH $CMD + ;; + Darwin*) + OSLD_LIBRARY_PATH="DYLD_LIBRARY_PATH=$2" + for i in "${@:3}" + do + OSLD_LIBRARY_PATH=$OSLD_LIBRARY_PATH:$i + done + eval $OSLD_LIBRARY_PATH $CMD + ;; + Windows*) OSLD_LIBRARY_PATH='PATH=%PATH%;' ;; + *) ;; + esac +} + +# Common initialization +OS="`uname`" +case $OS in + Linux*) + OSEXT='.linux' + OSLIBEXT='.so' + OSEXEEXT= + ;; + Windows*) + OSEXT='.exe' + OSLIBEXT='.dll' + OSEXEEXT='.exe' + ;; + Darwin*) + OSEXT='.mac' + OSLIBEXT='.dylib' + OSEXEEXT= + ;; + *) ;; +esac + +export ACT=act$OSEXT From 7896c8596080dd6d65c44db5192288b5cda0c765 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 21:48:02 -0700 Subject: [PATCH 050/143] Add Docker image and helper scripts --- Build/Dockerfile | 80 +++++++++++++++++++++++++++++++++++++++++++++ Build/docker.sh | 8 +++++ Build/run-docker.sh | 8 +++++ 3 files changed, 96 insertions(+) create mode 100644 Build/Dockerfile create mode 100755 Build/docker.sh create mode 100755 Build/run-docker.sh diff --git a/Build/Dockerfile b/Build/Dockerfile new file mode 100644 index 00000000..b02442d7 --- /dev/null +++ b/Build/Dockerfile @@ -0,0 +1,80 @@ +FROM centos:centos8 + +LABEL maintainer="Andrii Anpilogov (andrii.anpilogov@autodesk.com)" + +ARG USER_ID +ARG GROUP_ID + +RUN : "${USER_ID:?Build argument needs to be set and non-empty.}" \ + : "${GROUP_ID:?Build argument needs to be set and non-empty.}" + +RUN [ -e /etc/yum.conf ] && sed -i '/tsflags=nodocs/d' /etc/yum.conf || true + +# RUN yum install -y icu + +RUN dnf -y install dnf-plugins-core +RUN dnf -y install dnf-plugin-config-manager +RUN dnf -y update + +RUN dnf -y install epel-release +RUN dnf -y config-manager --set-enabled powertools + +# GCC +RUN dnf -y install gcc-toolset-9-gcc +RUN dnf -y install gcc-toolset-9-gcc-c++ + +# CMake & Ninja +RUN dnf -y install cmake +RUN dnf -y install ninja-build + +# Free Pascal +RUN (cd /opt && curl -O -L 'http://downloads.sourceforge.net/project/freepascal/Linux/3.2.2/fpc-3.2.2-1.x86_64.rpm' \ + && rpm -i fpc-3.2.2-1.x86_64.rpm) + +# Golang +RUN (cd /opt && curl -O -L https://golang.org/dl/go1.17.2.linux-amd64.tar.gz \ + && tar zxvf go1.17.2.linux-amd64.tar.gz) + +# Java +RUN dnf -y install \ + java-11-openjdk-devel + +# Mono +RUN rpm --import https://download.mono-project.com/repo/xamarin.gpg \ + && dnf config-manager --add-repo https://download.mono-project.com/repo/centos8-stable.repo \ + && dnf -y install mono-complete + + +# General purpose tools +RUN dnf -y install \ + glibc-common \ + glibc-utils \ + less \ + passwd \ + tar \ + vim-minimal \ + vim-enhanced \ + which \ + sudo \ + bash-completion \ + mc \ + yum-utils \ + && yum clean all + +# Create user +RUN groupadd docker \ + && useradd -ms /bin/bash --uid $USER_ID -g docker -G wheel user \ + && printf "user:user" | chpasswd \ + && printf "user ALL= NOPASSWD: ALL\\n" >> /etc/sudoers + +# Initialize Toolkit +RUN echo "source /opt/rh/gcc-toolset-9/enable" >> /home/user/.bash_profile +RUN echo "export PATH=\$PATH:/opt/go/bin" >> /home/user/.bash_profile + +VOLUME /data + +# Run Container as nonroot +USER user +WORKDIR /data + +ENTRYPOINT [ "/bin/bash", "-l" ] diff --git a/Build/docker.sh b/Build/docker.sh new file mode 100755 index 00000000..2889cab3 --- /dev/null +++ b/Build/docker.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" + +echo "Build Docker image" +docker build -t act-build --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) . diff --git a/Build/run-docker.sh b/Build/run-docker.sh new file mode 100755 index 00000000..6300fc7b --- /dev/null +++ b/Build/run-docker.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" + +docker run -it --rm -v $PWD/..:/data act-build /data/Build/build.sh +docker run -it --rm -v $PWD/..:/data act-build /data/Examples/build.sh From 6e7fbcb1d5569584a038d6d3463bbdabc18ec0e3 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 21:57:57 -0700 Subject: [PATCH 051/143] Add build scripts --- .../Examples/Cpp/build.sh | 29 +++++++++++++++++++ .../Examples/CppDynamic/build.sh | 18 ++++++++++++ .../Examples/Pascal/build.sh | 29 +++++++++++++++++++ .../Examples/Python/build.sh | 12 ++++++++ .../Implementations/Cpp/build.sh | 11 +++++++ .../Implementations/Pascal/build.sh | 11 +++++++ .../Implementations/Cpp/build.sh | 11 +++++++ .../Implementations/Pascal/build.sh | 11 +++++++ Examples/Injection/build.sh | 27 +++++++++++++++++ .../RTTI_component/Examples/CDynamic/build.sh | 23 +++++++++++++++ .../RTTI_component/Examples/CSharp/build.sh | 26 +++++++++++++++++ .../RTTI/RTTI_component/Examples/Cpp/build.sh | 29 +++++++++++++++++++ .../Examples/CppDynamic/build.sh | 23 +++++++++++++++ .../RTTI/RTTI_component/Examples/Go/build.sh | 18 ++++++++++++ .../RTTI_component/Examples/Java9/build.sh | 12 +++++--- .../RTTI_component/Examples/Pascal/build.sh | 25 ++++++++++++++++ .../RTTI_component/Examples/Python/build.sh | 12 ++++++++ .../Implementations/Cpp/build.sh | 11 +++++++ .../Implementations/Pascal/build.sh | 11 +++++++ Examples/RTTI/build.sh | 24 +++++++++++++++ Examples/build.sh | 11 +++++++ 21 files changed, 380 insertions(+), 4 deletions(-) create mode 100755 Examples/Injection/Calculation_component/Examples/Cpp/build.sh create mode 100755 Examples/Injection/Calculation_component/Examples/CppDynamic/build.sh create mode 100755 Examples/Injection/Calculation_component/Examples/Pascal/build.sh create mode 100755 Examples/Injection/Calculation_component/Examples/Python/build.sh create mode 100755 Examples/Injection/Calculation_component/Implementations/Cpp/build.sh create mode 100755 Examples/Injection/Calculation_component/Implementations/Pascal/build.sh create mode 100755 Examples/Injection/Numbers_component/Implementations/Cpp/build.sh create mode 100755 Examples/Injection/Numbers_component/Implementations/Pascal/build.sh create mode 100755 Examples/Injection/build.sh create mode 100755 Examples/RTTI/RTTI_component/Examples/CDynamic/build.sh create mode 100755 Examples/RTTI/RTTI_component/Examples/CSharp/build.sh create mode 100755 Examples/RTTI/RTTI_component/Examples/Cpp/build.sh create mode 100755 Examples/RTTI/RTTI_component/Examples/CppDynamic/build.sh create mode 100755 Examples/RTTI/RTTI_component/Examples/Go/build.sh mode change 100644 => 100755 Examples/RTTI/RTTI_component/Examples/Java9/build.sh create mode 100755 Examples/RTTI/RTTI_component/Examples/Pascal/build.sh create mode 100755 Examples/RTTI/RTTI_component/Examples/Python/build.sh create mode 100755 Examples/RTTI/RTTI_component/Implementations/Cpp/build.sh create mode 100755 Examples/RTTI/RTTI_component/Implementations/Pascal/build.sh create mode 100755 Examples/RTTI/build.sh create mode 100755 Examples/build.sh diff --git a/Examples/Injection/Calculation_component/Examples/Cpp/build.sh b/Examples/Injection/Calculation_component/Examples/Cpp/build.sh new file mode 100755 index 00000000..635e9a57 --- /dev/null +++ b/Examples/Injection/Calculation_component/Examples/Cpp/build.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../../../../Build/build.inc + +echo "Build C++ Implicit example" +[ -d build-cpp ] && rm -rf build-cpp +mkdir build-cpp +pushd build-cpp +cmake -H.. -B. -DCMAKE_BUILD_TYPE=Debug -DCALCULATIONLOCATION=../../../../Calculation_component/Implementations/Cpp/build/calculation$OSLIBEXT -G Ninja +cmake --build . + +echo "Test C++ library" +RUN ./CalculationExample_CPPImplicit ../../../../Numbers_component/Implementations/Cpp/build +popd + + +echo "Build C++ Implicit example" +[ -d build-pascal ] && rm -rf build-pascal +mkdir build-pascal +pushd build-pascal +cmake -H.. -B. -DCMAKE_BUILD_TYPE=Debug -DCALCULATIONLOCATION=../../../../Calculation_component/Implementations/Pascal/build/calculation$OSLIBEXT -G Ninja +cmake --build . + +echo "Test Pascal library" +RUN ./CalculationExample_CPPImplicit ../../../../Numbers_component/Implementations/Pascal/build +popd diff --git a/Examples/Injection/Calculation_component/Examples/CppDynamic/build.sh b/Examples/Injection/Calculation_component/Examples/CppDynamic/build.sh new file mode 100755 index 00000000..29a4e4d4 --- /dev/null +++ b/Examples/Injection/Calculation_component/Examples/CppDynamic/build.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../../../../Build/build.inc + +echo "Build C++ implementation" +[ -d build ] && rm -rf build +mkdir build +cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Debug -G Ninja +cmake --build build + +echo "Test C++ library" +RUN ./build/CalculationExample_CPPDynamic ../../../Calculation_component/Implementations/Cpp/build ../../../Numbers_component/Implementations/Cpp/build + +echo "Test Pascal library" +RUN ./build/CalculationExample_CPPDynamic ../../../Calculation_component/Implementations/Pascal/build ../../../Numbers_component/Implementations/Pascal/build diff --git a/Examples/Injection/Calculation_component/Examples/Pascal/build.sh b/Examples/Injection/Calculation_component/Examples/Pascal/build.sh new file mode 100755 index 00000000..0b94a90d --- /dev/null +++ b/Examples/Injection/Calculation_component/Examples/Pascal/build.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../../../../Build/build.inc + +echo "Build Pascal example" +rm -rf build +mkdir build +fpc -Fu../../../Calculation_component/Bindings/Pascal -Fu../../../Numbers_component/Bindings/Pascal -FU./build -o./build/Calculation_Example$OSEXEEXT Calculation_Example.lpr + +pushd build + +echo "Test C++ library" +rm -f *.dll +ln -s ../../../../Calculation_component/Implementations/Cpp/build/calculation$OSLIBEXT calculation.dll +ln -s ../../../../Numbers_component/Implementations/Cpp/build/numbers$OSLIBEXT numbers.dll + +RUN ./Calculation_Example . + +echo "Test Pascal library" +rm -f *.dll +ln -s ../../../../Calculation_component/Implementations/Pascal/build/calculation$OSLIBEXT calculation.dll +ln -s ../../../../Numbers_component/Implementations/Pascal/build/numbers$OSLIBEXT numbers.dll + +RUN ./Calculation_Example . + +popd \ No newline at end of file diff --git a/Examples/Injection/Calculation_component/Examples/Python/build.sh b/Examples/Injection/Calculation_component/Examples/Python/build.sh new file mode 100755 index 00000000..b8a53614 --- /dev/null +++ b/Examples/Injection/Calculation_component/Examples/Python/build.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../../../../Build/build.inc + +echo "Test C++ library" +RUN "python3 Calculation_Example.py" ../../../Numbers_component/Implementations/Cpp/build ../../../Calculation_component/Implementations/Cpp/build + +echo "Test Pascal library" +RUN "python3 Calculation_Example.py" ../../../Numbers_component/Implementations/Pascal/build ../../../Calculation_component/Implementations/Pascal/build diff --git a/Examples/Injection/Calculation_component/Implementations/Cpp/build.sh b/Examples/Injection/Calculation_component/Implementations/Cpp/build.sh new file mode 100755 index 00000000..1a3f0e6c --- /dev/null +++ b/Examples/Injection/Calculation_component/Implementations/Cpp/build.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" + +echo "Build C++ implementation" +[ -d build ] && rm -rf build +mkdir build +cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Debug -G Ninja +cmake --build build diff --git a/Examples/Injection/Calculation_component/Implementations/Pascal/build.sh b/Examples/Injection/Calculation_component/Implementations/Pascal/build.sh new file mode 100755 index 00000000..d7b63da6 --- /dev/null +++ b/Examples/Injection/Calculation_component/Implementations/Pascal/build.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../../../../Build/build.inc + +echo "Build Pascal implementation" +[ -d build ] && rm -rf build +mkdir build +fpc -Fu../../Bindings/Pascal -Fu../../../Numbers_component/Bindings/Pascal -FuInterfaces -FuStub -FU./build -o./build/calculation$OSLIBEXT Interfaces/calculation.lpr diff --git a/Examples/Injection/Numbers_component/Implementations/Cpp/build.sh b/Examples/Injection/Numbers_component/Implementations/Cpp/build.sh new file mode 100755 index 00000000..1a3f0e6c --- /dev/null +++ b/Examples/Injection/Numbers_component/Implementations/Cpp/build.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" + +echo "Build C++ implementation" +[ -d build ] && rm -rf build +mkdir build +cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Debug -G Ninja +cmake --build build diff --git a/Examples/Injection/Numbers_component/Implementations/Pascal/build.sh b/Examples/Injection/Numbers_component/Implementations/Pascal/build.sh new file mode 100755 index 00000000..ac2e58d0 --- /dev/null +++ b/Examples/Injection/Numbers_component/Implementations/Pascal/build.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../../../../Build/build.inc + +echo "Build Pascal implementation" +[ -d build ] && rm -rf build +mkdir build +fpc -Fu../../Bindings/Pascal -FuInterfaces -FuStub -FU./build -o./build/numbers$OSLIBEXT Interfaces/numbers.lpr diff --git a/Examples/Injection/build.sh b/Examples/Injection/build.sh new file mode 100755 index 00000000..ea37dc45 --- /dev/null +++ b/Examples/Injection/build.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../Build/build.inc + +echo "Generate IDL" +../../$ACT Numbers.xml +../../$ACT Calculation.xml + +echo "Build C++ libraries" +./Numbers_component/Implementations/Cpp/build.sh +./Calculation_component/Implementations/Cpp/build.sh + +echo "Build C++ libraries" +./Numbers_component/Implementations/Pascal/build.sh +./Calculation_component/Implementations/Pascal/build.sh + + +echo "Build and test bindings examples with C++ library" +./Calculation_component/Examples/Cpp/build.sh +./Calculation_component/Examples/CppDynamic/build.sh +./Calculation_component/Examples/Python/build.sh +./Calculation_component/Examples/Pascal/build.sh + +echo "Build and test are done and successful" \ No newline at end of file diff --git a/Examples/RTTI/RTTI_component/Examples/CDynamic/build.sh b/Examples/RTTI/RTTI_component/Examples/CDynamic/build.sh new file mode 100755 index 00000000..9666fe4f --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/CDynamic/build.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" + +source ../../../../../Build/build.inc + +echo "Build C++ Implicit example" + +[ -d build ] && rm -rf build +mkdir build +pushd build +cmake -H.. -B. -DCMAKE_BUILD_TYPE=Debug -G Ninja +cmake --build . + +echo "Test C++ library" +RUN ./RTTIExample_CDynamic ../../../Implementations/Cpp/build + +echo "Test Pascal library" +RUN ./RTTIExample_CDynamic ../../../Implementations/Pascal/build + +popd diff --git a/Examples/RTTI/RTTI_component/Examples/CSharp/build.sh b/Examples/RTTI/RTTI_component/Examples/CSharp/build.sh new file mode 100755 index 00000000..e1b070d0 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/CSharp/build.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../../../../Build/build.inc + +echo "Build Go example" + +[ -d bin ] && rm -rf bin +[ -d obj ] && rm -rf ob +msbuild /p:Configuration=Debug /t:Restore RTTI_Example.csproj +msbuild /p:Configuration=Debug /p:AllowUnsafeBlocks=true RTTI_Example.csproj + +pushd bin/Debug/netstandard2.0 +echo "Test C++ library" +rm -f rtti.dll +ln -s ../../../../../Implementations/Cpp/build/rtti$OSLIBEXT rtti.dll +RUN "mono RTTI_Example.dll" . + +echo "Test Pascal library" +rm -f rtti.dll +ln -s ../../../../../Implementations/Pascal/build/rtti$OSLIBEXT rtti.dll +RUN "mono RTTI_Example.dll" . + +popd \ No newline at end of file diff --git a/Examples/RTTI/RTTI_component/Examples/Cpp/build.sh b/Examples/RTTI/RTTI_component/Examples/Cpp/build.sh new file mode 100755 index 00000000..4aa5e1e4 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Cpp/build.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../../../../Build/build.inc + +echo "Build C++ Implicit example" +[ -d build-cpp ] && rm -rf build-cpp +mkdir build-cpp +pushd build-cpp +cmake -H.. -B. -DCMAKE_BUILD_TYPE=Debug -DRTTI_LIB_LOCATION=../../../Implementations/Cpp/build/rtti$OSLIBEXT -G Ninja +cmake --build . + +echo "Test C++ library" +./RTTIExample_CPPImplicit +popd + + +echo "Build C++ Implicit example" +[ -d build-pascal ] && rm -rf build-pascal +mkdir build-pascal +pushd build-pascal +cmake -H.. -B. -DCMAKE_BUILD_TYPE=Debug -DRTTI_LIB_LOCATION=../../../Implementations/Pascal/build/rtti$OSLIBEXT -G Ninja +cmake --build . + +echo "Test C++ library" +./RTTIExample_CPPImplicit +popd diff --git a/Examples/RTTI/RTTI_component/Examples/CppDynamic/build.sh b/Examples/RTTI/RTTI_component/Examples/CppDynamic/build.sh new file mode 100755 index 00000000..9d68b88f --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/CppDynamic/build.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../../../../Build/build.inc + +echo "Build C++ Dynamic example" + +[ -d build ] && rm -rf build +mkdir build +pushd build +cmake -H.. -B. -DCMAKE_BUILD_TYPE=Debug -G Ninja +cmake --build . + +echo "Test C++ library" +RUN ./RTTIExample_CPPDynamic ../../../Implementations/Cpp/build + +echo "Test Pascal library" +RUN ./RTTIExample_CPPDynamic ../../../Implementations/Pascal/build + +popd + diff --git a/Examples/RTTI/RTTI_component/Examples/Go/build.sh b/Examples/RTTI/RTTI_component/Examples/Go/build.sh new file mode 100755 index 00000000..4c0df563 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Go/build.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../../../../Build/build.inc + +echo "Build Go example" + +[ -d build ] && rm -rf build +mkdir build +GO111MODULE=off go build -o build/RTTI_example RTTI_example.go + +echo "Test C++ library" +./build/RTTI_example $PWD/../../Implementations/Cpp/build/rtti$OSLIBEXT + +echo "Test Pascal library" +./build/RTTI_example $PWD/../../Implementations/Pascal/build/rtti$OSLIBEXT diff --git a/Examples/RTTI/RTTI_component/Examples/Java9/build.sh b/Examples/RTTI/RTTI_component/Examples/Java9/build.sh old mode 100644 new mode 100755 index 4bba3e9a..a5486745 --- a/Examples/RTTI/RTTI_component/Examples/Java9/build.sh +++ b/Examples/RTTI/RTTI_component/Examples/Java9/build.sh @@ -2,6 +2,7 @@ set -euxo pipefail cd "$(dirname "$0")" +source ../../../../../Build/build.inc JnaJar="jna-5.5.0.jar" Classpath=".:${JnaJar}:../../Bindings/Java9/" @@ -24,9 +25,12 @@ echo "Download JNA" [ -f jna-5.5.0.jar ] || wget https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar echo "Compile Java bindings" -javac -classpath "${JnaJar}" ../../Bindings/Java9/rtti/*.java +javac -encoding UTF8 -classpath "${JnaJar}" ../../Bindings/Java9/rtti/*.java echo "Compile Java example" -javac -classpath $Classpath RTTI_Example.java +javac -encoding UTF8 -classpath $Classpath RTTI_Example.java -echo "Execute example" -java -classpath $Classpath RTTI_Example +echo "Test C++ library" +java -ea -classpath $Classpath RTTI_Example $PWD/../../Implementations/Cpp/build/rtti$OSLIBEXT + +echo "Test Pascal library" +java -ea -classpath $Classpath RTTI_Example $PWD/../../Implementations/Pascal/build/rtti$OSLIBEXT diff --git a/Examples/RTTI/RTTI_component/Examples/Pascal/build.sh b/Examples/RTTI/RTTI_component/Examples/Pascal/build.sh new file mode 100755 index 00000000..ed3879e9 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Pascal/build.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../../../../Build/build.inc + +echo "Build Pascal example" +rm -rf build +mkdir build +fpc -Fu../../Bindings/Pascal -FU./build -o./build/RTTI_Example$OSEXEEXT RTTI_Example.lpr + +pushd build + +echo "Test C++ library" +rm -f rtti.dll +ln -s ../../Implementations/Cpp/build/rtti$OSLIBEXT rtti.dll +RUN ./RTTI_Example . + +echo "Test Pascal library" +rm -f rtti.dll +ln -s ../../Implementations/Pascal/build/rtti$OSLIBEXT rtti.dll +RUN ./RTTI_Example . + +popd diff --git a/Examples/RTTI/RTTI_component/Examples/Python/build.sh b/Examples/RTTI/RTTI_component/Examples/Python/build.sh new file mode 100755 index 00000000..4a1b501d --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Python/build.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../../../../Build/build.inc + +echo "Test C++ library" +RUN "python3 RTTI_Example.py" $PWD/../../Implementations/Cpp/build + +echo "Test Pascal library" +RUN "python3 RTTI_Example.py" $PWD/../../Implementations/Pascal/build diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/build.sh b/Examples/RTTI/RTTI_component/Implementations/Cpp/build.sh new file mode 100755 index 00000000..1a3f0e6c --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/build.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" + +echo "Build C++ implementation" +[ -d build ] && rm -rf build +mkdir build +cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Debug -G Ninja +cmake --build build diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/build.sh b/Examples/RTTI/RTTI_component/Implementations/Pascal/build.sh new file mode 100755 index 00000000..68ed1450 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/build.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../../../../Build/build.inc + +echo "Build Pascal implementation" +[ -d build ] && rm -rf build +mkdir build +fpc -Fu../../Bindings/Pascal -FuInterfaces -FuStub -FU./build -o./build/rtti$OSLIBEXT Interfaces/rtti.lpr diff --git a/Examples/RTTI/build.sh b/Examples/RTTI/build.sh new file mode 100755 index 00000000..cc14d1dd --- /dev/null +++ b/Examples/RTTI/build.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../Build/build.inc + +echo "Generate IDL" +../../$ACT RTTI.xml + +echo "Build libraries" +./RTTI_component/Implementations/Cpp/build.sh +./RTTI_component/Implementations/Pascal/build.sh + +echo "Build and test bindings examples with C++ library" +./RTTI_component/Examples/CDynamic/build.sh +./RTTI_component/Examples/Cpp/build.sh +./RTTI_component/Examples/CppDynamic/build.sh +./RTTI_component/Examples/CSharp/build.sh +./RTTI_component/Examples/Go/build.sh +./RTTI_component/Examples/Java9/build.sh +./RTTI_component/Examples/Pascal/build.sh +./RTTI_component/Examples/Python/build.sh +echo "Build and test are done and successful" \ No newline at end of file diff --git a/Examples/build.sh b/Examples/build.sh new file mode 100755 index 00000000..a23089c9 --- /dev/null +++ b/Examples/build.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" + +echo "Build and test example" +./RTTI/build.sh +./Injection/build.sh + +echo "Examples: build and test are done and successful" \ No newline at end of file From 43f0a560fb3f378739988d2071030496016db074 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 21:58:40 -0700 Subject: [PATCH 052/143] Update exmaple IDL files with ClassTypeId definition --- Examples/Injection/Calculation.xml | 5 ++++- Examples/Injection/Numbers.xml | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Examples/Injection/Calculation.xml b/Examples/Injection/Calculation.xml index 6c8eedce..02e20152 100644 --- a/Examples/Injection/Calculation.xml +++ b/Examples/Injection/Calculation.xml @@ -33,6 +33,9 @@ </errors> <class name="Base"> + <method name="ClassTypeId" description="Get Class Type Id"> + <param name="ClassTypeId" type="uint64" pass="return" description="Class type as a 64 bits integer" /> + </method> </class> <class name="Calculator" parent="Base" description="Sums up or multiplies a list of variables"> @@ -62,7 +65,7 @@ versionmethod="GetVersion" errormethod="GetLastError" injectionmethod="InjectComponent" symbollookupmethod="GetSymbolLookupMethod" - > + classtypeidmethod="ClassTypeId"> <method name="CreateCalculator" description="Creates a new Calculator instance"> <param name="Instance" type="class" class="Calculator" pass="return" description="New Calculator instance" /> </method> diff --git a/Examples/Injection/Numbers.xml b/Examples/Injection/Numbers.xml index dc186540..0c49fcf4 100644 --- a/Examples/Injection/Numbers.xml +++ b/Examples/Injection/Numbers.xml @@ -28,6 +28,9 @@ </errors> <class name="Base"> + <method name="ClassTypeId" description="Get Class Type Id"> + <param name="ClassTypeId" type="uint64" pass="return" description="Class type as a 64 bits integer" /> + </method> </class> <class name="Variable" parent="Base" description="A variable number"> @@ -42,7 +45,8 @@ <global baseclassname="Base" releasemethod="ReleaseInstance" acquiremethod="AcquireInstance" versionmethod="GetVersion" errormethod="GetLastError" - symbollookupmethod="GetSymbolLookupMethod"> + symbollookupmethod="GetSymbolLookupMethod" + classtypeidmethod="ClassTypeId"> <method name="CreateVariable" description="Creates a new Variable instance"> <param name="InitialValue" type="double" pass="in" description="Initial value of the new Variable" /> From f09f06fd6302a860f0ac7ac3a31b3d723da97d11 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:00:08 -0700 Subject: [PATCH 053/143] cgo on Linux required linking with dl library --- Source/buildbindinggo.go | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/buildbindinggo.go b/Source/buildbindinggo.go index 8ad1a131..edebd095 100644 --- a/Source/buildbindinggo.go +++ b/Source/buildbindinggo.go @@ -533,6 +533,7 @@ func buildGoWrapper(component ComponentDefinition, w LanguageWriter) error { w.Writeln("package %s", packageName) w.Writeln("") w.Writeln("/*") + w.Writeln("#cgo linux LDFLAGS: -ldl") w.Writeln("#include \"%s_dynamic.cc\"", packageName) w.Writeln("") w.Writeln("%s_pvoid load%sLibrary (const char * pFileName)", component.NameSpace, component.NameSpace) From 1217b84e4f94a401871a8cb2912d4acafeadc95c Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:00:40 -0700 Subject: [PATCH 054/143] Don't overwrite build scripts --- Source/buildbindingjava.go | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Source/buildbindingjava.go b/Source/buildbindingjava.go index 12dd3838..a5441141 100644 --- a/Source/buildbindingjava.go +++ b/Source/buildbindingjava.go @@ -190,15 +190,7 @@ func BuildBindingJavaDynamic(component ComponentDefinition, outputFolder string, JavaBuildName := "build.sh"; JavaBuildPath := path.Join(outputFolderExample, JavaBuildName); - log.Printf("Creating \"%s\"", JavaBuildPath) - JavaWrapperFile, err2 := CreateLanguageFile (JavaBuildPath, indent) - if err2 != nil { - return err2; - } - err = buildJavaBuildExampleScript(component, JavaWrapperFile, version) - if err != nil { - return err; - } + } } return nil; From 97c43eb9fbda26dd2455a0ce9f9fddde06cc4c58 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:06:00 -0700 Subject: [PATCH 055/143] Don't overwrite build scripts --- Source/buildbindingjava.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Source/buildbindingjava.go b/Source/buildbindingjava.go index a5441141..1da6cd77 100644 --- a/Source/buildbindingjava.go +++ b/Source/buildbindingjava.go @@ -190,7 +190,20 @@ func BuildBindingJavaDynamic(component ComponentDefinition, outputFolder string, JavaBuildName := "build.sh"; JavaBuildPath := path.Join(outputFolderExample, JavaBuildName); + if (forceRecreation || !FileExists(JavaBuildPath)) { + log.Printf("Creating \"%s\"", JavaBuildPath) + JavaWrapperFile, err2 := CreateLanguageFile (JavaBuildPath, indent) + if err2 != nil { + return err2; } + err = buildJavaBuildExampleScript(component, JavaWrapperFile, version) + if err != nil { + return err; + } + } else { + log.Printf("Omitting recreation of Java example build file\"%s\"", JavaBuildPath) + } + } return nil; From 230d18ff6c0acf427ac95457622c6fc14d8b095e Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:07:28 -0700 Subject: [PATCH 056/143] Force Jave use UTF8 encoding and enable asserts --- Source/buildbindingjava.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/buildbindingjava.go b/Source/buildbindingjava.go index 1da6cd77..cdba6975 100644 --- a/Source/buildbindingjava.go +++ b/Source/buildbindingjava.go @@ -310,12 +310,12 @@ func buildJavaBuildExampleScript(component ComponentDefinition, w LanguageWriter w.Writeln("[ -f jna-5.5.0.jar ] || wget https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar") w.Writeln("") w.Writeln("echo \"Compile Java bindings\"") - w.Writeln("javac -classpath \"${JnaJar}\" %s", imports) + w.Writeln("javac -encoding UTF8 -classpath \"${JnaJar}\" %s", imports) w.Writeln("echo \"Compile Java example\"") - w.Writeln("javac -classpath $Classpath %s_Example.java", component.NameSpace) + w.Writeln("javac -encoding UTF8 -classpath $Classpath %s_Example.java", component.NameSpace) w.Writeln("") w.Writeln("echo \"Execute example\"") - w.Writeln("java -classpath $Classpath %s_Example", component.NameSpace) + w.Writeln("java -ea -classpath $Classpath %s_Example", component.NameSpace) return nil; } From 7b260dfe5a970e4ae8a9db31cd3462ee28168fea Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:09:08 -0700 Subject: [PATCH 057/143] Go: fix compilation error due to wrong type convertion --- Source/buildbindinggo.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/buildbindinggo.go b/Source/buildbindinggo.go index edebd095..ecdc57fc 100644 --- a/Source/buildbindinggo.go +++ b/Source/buildbindinggo.go @@ -730,8 +730,8 @@ func getGoType(paramType, namespace, paramClass, paramName string, isPtr bool) ( tp.GoToC = fmt.Sprintf("(%s)(unsafe.Pointer(&[]byte(%s)[0]))", tp.CType, paramName) tp.Empty = "\"\"" case "pointer": - tp.Type = "uint64" - tp.CType = fmt.Sprintf("C.uint64_t") + tp.Type = "uintptr" + tp.CType = fmt.Sprintf("C.RTTI_pvoid") tp.CToGo = fmt.Sprintf("%s(%s)", tp.Type, paramName) tp.GoToC = fmt.Sprintf("(%s)(%s)", tp.CType, paramName) tp.Empty = "0" From a58483f71855b6777ef204231e0a7268e8d6a2bb Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:10:55 -0700 Subject: [PATCH 058/143] Use correct handle type for injected components Covers only binding used in Injection example --- Source/buildbindingccpp.go | 12 ++++++------ Source/buildbindingpascal.go | 18 +++++++++++------- Source/buildbindingpython.go | 2 +- Source/buildimplementationcpp.go | 6 +++--- Source/languagepascal.go | 8 ++++++-- 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index 91dc21ff..dbcec722 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -769,7 +769,7 @@ func writeDynamicCPPMethod(method ComponentDefinitionMethod, w LanguageWriter, N makeSharedParameter = makeSharedParameter + "->m_p" + paramNameSpace + "Wrapper.get()" } - definitionCodeLines = append(definitionCodeLines, fmt.Sprintf("%sHandle h%s = nullptr;", NameSpace, param.ParamName)) + definitionCodeLines = append(definitionCodeLines, fmt.Sprintf("%sHandle h%s = nullptr;", paramNameSpace, param.ParamName)) callParameter = fmt.Sprintf("&h%s", param.ParamName) initCallParameter = callParameter @@ -1045,7 +1045,7 @@ func getBindingCppParamType(paramType string, paramClass string, NameSpace strin return fmt.Sprintf(paramNameSpace + "s"+paramClassName) case "class", "optionalclass": if isInput { - return fmt.Sprintf("classParam<%s%s%s%s>", paramNameSpace, cppClassPrefix, ClassIdentifier, paramClassName) + return fmt.Sprintf("%sclassParam<%s%s%s%s>", paramNameSpace, paramNameSpace, cppClassPrefix, ClassIdentifier, paramClassName) } return fmt.Sprintf("%sP%s%s", paramNameSpace, ClassIdentifier, paramClassName) case "functiontype": @@ -1333,6 +1333,9 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s return err } } + w.Writeln("") + w.Writeln(" template<class U>") + w.Writeln(" std::shared_ptr<U> polymorphicFactory(%sHandle);", NameSpace) w.Writeln("") w.Writeln("private:") @@ -1371,9 +1374,6 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln(" %sResult loadWrapperTable(s%sDynamicWrapperTable * pWrapperTable, const char * pLibraryFileName);", NameSpace, NameSpace) w.Writeln(" %sResult loadWrapperTableFromSymbolLookupMethod(s%sDynamicWrapperTable * pWrapperTable, void* pSymbolLookupMethod);", NameSpace, NameSpace) } - w.Writeln("") - w.Writeln(" template<class U>") - w.Writeln(" std::shared_ptr<U> polymorphicFactory(%sHandle);", NameSpace) w.Writeln("") @@ -1444,7 +1444,7 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln("") w.Writeln("template <class T>") - w.Writeln("std::shared_ptr<T> %s%sWrapper::polymorphicFactory(%sHandle pHandle)", cppClassPrefix, ClassIdentifier, strings.ToUpper(NameSpace)) + w.Writeln("std::shared_ptr<T> %s%sWrapper::polymorphicFactory(%sHandle pHandle)", cppClassPrefix, ClassIdentifier, NameSpace) w.Writeln("{") w.Writeln(" %s_uint64 resultClassTypeId = 0;", strings.ToUpper(NameSpace)) w.Writeln(" CheckError(nullptr, m_WrapperTable.m_Base_ClassTypeId(pHandle, &resultClassTypeId));") diff --git a/Source/buildbindingpascal.go b/Source/buildbindingpascal.go index 15a42b86..c3442365 100644 --- a/Source/buildbindingpascal.go +++ b/Source/buildbindingpascal.go @@ -413,8 +413,8 @@ func buildDynamicPascalImplementation(component ComponentDefinition, w LanguageW writeEnumConversionInterface(component, w, NameSpace) - w.Writeln(" TPolymorphicFactory<_T:class; _B> = record") - w.Writeln(" class function Make(Wrapper: T%sWrapper; Handle: T%sHandle): _T; static;", strings.ToUpper(NameSpace), strings.ToUpper(NameSpace)) + w.Writeln(" T%sPolymorphicFactory<_T:class; _B> = record", NameSpace) + w.Writeln(" class function Make(Wrapper: T%sWrapper; Handle: T%sHandle): _T; static;", NameSpace, NameSpace) w.Writeln(" end;") w.Writeln("") @@ -428,13 +428,13 @@ func buildDynamicPascalImplementation(component ComponentDefinition, w LanguageW w.Writeln("**************************************************************************************************************************)") w.Writeln("") - w.Writeln(" class function TPolymorphicFactory<_T, _B>.Make(Wrapper: T%sWrapper; Handle: T%sHandle): _T;", strings.ToUpper(NameSpace), strings.ToUpper(NameSpace)) + w.Writeln(" class function T%sPolymorphicFactory<_T, _B>.Make(Wrapper: T%sWrapper; Handle: T%sHandle): _T;", NameSpace, NameSpace, NameSpace) w.Writeln(" var") w.Writeln(" ClassTypeId: QWord;") - w.Writeln(" Obj: TRTTIBase;") + w.Writeln(" Obj: T%sBase;", strings.ToUpper(NameSpace)) w.Writeln(" begin") w.Writeln(" Result := nil;") - w.Writeln(" Wrapper.CheckError(nil, Wrapper.%sBase_ClassTypeIdFunc(handle, ClassTypeId));", strings.ToUpper(NameSpace)) + w.Writeln(" Wrapper.CheckError(nil, Wrapper.%sBase_ClassTypeIdFunc(handle, ClassTypeId));", NameSpace) w.Writeln(" case (ClassTypeId) of") for i := 0; i < len(component.Classes); i++ { classTypeId, chashHashString := component.Classes[i].classTypeId(NameSpace) @@ -891,7 +891,11 @@ func writePascalClassMethodImplementation(method ComponentDefinitionMethod, w La initCallParameters = initCallParameters + "A" + param.ParamName case "class", "optionalclass": - defineCommands = append(defineCommands, "A"+param.ParamName+"Handle: T"+NameSpace+"Handle;") + paramNameSpace, _, _ := decomposeParamClassName(param.ParamClass) + if len(paramNameSpace) == 0 { + paramNameSpace = NameSpace + } + defineCommands = append(defineCommands, "A"+param.ParamName+"Handle: T"+paramNameSpace+"Handle;") initCommands = append(initCommands, fmt.Sprintf("if Assigned(A%s) then", param.ParamName)) initCommands = append(initCommands, "A"+param.ParamName+"Handle := A" + param.ParamName + ".TheHandle") initCommands = append(initCommands, fmt.Sprintf("else")) @@ -1057,7 +1061,7 @@ func writePascalClassMethodImplementation(method ComponentDefinitionMethod, w La initCommands = append(initCommands, "H"+param.ParamName+" := nil;") callFunctionParameters = callFunctionParameters + "H" + param.ParamName resultCommands = append(resultCommands, fmt.Sprintf(" if Assigned(H%s) then", param.ParamName)) - resultCommands = append(resultCommands, fmt.Sprintf(" Result := TPolymorphicFactory<T%s%s, T%s%s>.Make(%s, H%s);", theNameSpace, theParamClass, theNameSpace, theParamClass, theWrapperInstance, param.ParamName)) + resultCommands = append(resultCommands, fmt.Sprintf(" Result := T%sPolymorphicFactory<T%s%s, T%s%s>.Make(%s, H%s);", theNameSpace, theNameSpace, theParamClass, theNameSpace, theParamClass, theWrapperInstance, param.ParamName)) default: return fmt.Errorf("invalid method parameter type \"%s\" for %s.%s (%s)", param.ParamType, ClassName, method.MethodName, param.ParamName) diff --git a/Source/buildbindingpython.go b/Source/buildbindingpython.go index 10737f7b..89cb4089 100644 --- a/Source/buildbindingpython.go +++ b/Source/buildbindingpython.go @@ -838,7 +838,7 @@ func writeMethod(method ComponentDefinitionMethod, w LanguageWriter, NameSpace s postCallLines = append(postCallLines, fmt.Sprintf("if %sHandle:", param.ParamName)) postCallLines = append(postCallLines, fmt.Sprintf(" %sObject = %s._polymorphicFactory(%sHandle)", - param.ParamName, wrapperReference, param.ParamName)) + param.ParamName, theWrapperReference, param.ParamName)) postCallLines = append(postCallLines, fmt.Sprintf("else:")) if (param.ParamType == "optionalclass") { postCallLines = append(postCallLines, fmt.Sprintf(" %sObject = None", param.ParamName)) diff --git a/Source/buildimplementationcpp.go b/Source/buildimplementationcpp.go index f8d6d32a..d16bf26a 100644 --- a/Source/buildimplementationcpp.go +++ b/Source/buildimplementationcpp.go @@ -431,7 +431,7 @@ func writeCPPClassInterface(component ComponentDefinition, class ComponentDefini w.Writeln("%s", methodstring) w.Writeln(" {") w.Writeln(" // First 64 bits of SHA1 of a string: \"%s\"", chashHashString) - w.Writeln(" static const %s_uint64 s_%sTypeId = 0x%XUL;", strings.ToUpper(NameSpace), class.ClassName, classTypeId) + w.Writeln(" static const %s_uint64 s_%sTypeId = 0x%XUL;", NameSpace, class.ClassName, classTypeId) w.Writeln(" return s_%sTypeId;", class.ClassName) w.Writeln(" }") w.Writeln("") @@ -1723,7 +1723,7 @@ func generatePrePostCallCPPFunctionCode(component ComponentDefinition, method Co theWrapper := "C" + ClassIdentifier + "Wrapper::sP" + paramNameSpace + "Wrapper" acqurireMethod := component.ImportedComponentDefinitions[paramNameSpace].Global.AcquireMethod postCallCode = append(postCallCode, fmt.Sprintf("%s->%s(%s.get());", theWrapper, acqurireMethod, outVarName)) - postCallCode = append(postCallCode, fmt.Sprintf("*%s = %s->GetHandle();", variableName, outVarName)); + postCallCode = append(postCallCode, fmt.Sprintf("*%s = %s->handle();", variableName, outVarName)); callParameters = callParameters + outVarName outCallParameters = outCallParameters + outVarName } else { @@ -1789,7 +1789,7 @@ func generatePrePostCallCPPFunctionCode(component ComponentDefinition, method Co acqurireMethod := component.ImportedComponentDefinitions[paramNameSpace].Global.AcquireMethod returnVariable = fmt.Sprintf("p%s%s", paramNameSpace, param.ParamName) postCallCode = append(postCallCode, fmt.Sprintf("%s->%s(p%s%s.get());", theWrapper, acqurireMethod, paramNameSpace, param.ParamName)) - postCallCode = append(postCallCode, fmt.Sprintf("*%s = p%s%s->GetHandle();", variableName, paramNameSpace, param.ParamName)); + postCallCode = append(postCallCode, fmt.Sprintf("*%s = p%s%s->handle();", variableName, paramNameSpace, param.ParamName)); } else { preCallCode = append(preCallCode, fmt.Sprintf("%s* pBase%s(nullptr);", IBaseClassName, param.ParamName)) returnVariable = fmt.Sprintf("pBase%s", param.ParamName) diff --git a/Source/languagepascal.go b/Source/languagepascal.go index a61cbc14..4d1e5e7c 100644 --- a/Source/languagepascal.go +++ b/Source/languagepascal.go @@ -314,10 +314,14 @@ func getPascalParameterType(ParamTypeName string, NameSpace string, ParamClass s } case "class", "optionalclass": + SubNameSpace, SubClassName, _ := decomposeParamClassName(ParamClass) if isPlain { - PascalParamTypeName = fmt.Sprintf("T%sHandle", NameSpace) + if len(SubNameSpace) > 0 && SubNameSpace != NameSpace { + PascalParamTypeName = fmt.Sprintf("T%sHandle", SubNameSpace) + } else { + PascalParamTypeName = fmt.Sprintf("T%sHandle", NameSpace) + } } else { - SubNameSpace, SubClassName, _ := decomposeParamClassName(ParamClass) if isImplementation { if len(SubNameSpace) > 0 { PascalParamTypeName = fmt.Sprintf("T%s%s", SubNameSpace, SubClassName) From f9ae6b33a37a3f8ab2904164e217e439ce544bb0 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:11:44 -0700 Subject: [PATCH 059/143] Don't remove rtti_dynamic.cc and keep git happy --- .../RTTI/RTTI_component/Examples/CDynamic/CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Examples/CDynamic/CMakeLists.txt b/Examples/RTTI/RTTI_component/Examples/CDynamic/CMakeLists.txt index f5bdd5c1..1ad3cb14 100644 --- a/Examples/RTTI/RTTI_component/Examples/CDynamic/CMakeLists.txt +++ b/Examples/RTTI/RTTI_component/Examples/CDynamic/CMakeLists.txt @@ -19,9 +19,10 @@ cmake_minimum_required(VERSION 3.5) set(CMAKE_CURRENT_BINDING_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../Bindings/CDynamic) project(RTTIExample_CDynamic C) -if (EXISTS ${CMAKE_CURRENT_BINDING_DIR}/rtti_dynamic.cc) - file(RENAME "${CMAKE_CURRENT_BINDING_DIR}/rtti_dynamic.cc" "${CMAKE_CURRENT_BINDING_DIR}/rtti_dynamic.c") -endif() + +file(COPY "${CMAKE_CURRENT_BINDING_DIR}/rtti_dynamic.cc" DESTINATION "${CMAKE_CURRENT_BINDING_DIR}") +file(RENAME "${CMAKE_CURRENT_BINDING_DIR}/rtti_dynamic.cc" "${CMAKE_CURRENT_BINDING_DIR}/rtti_dynamic.c") + add_executable(RTTIExample_CDynamic "${CMAKE_CURRENT_SOURCE_DIR}/RTTI_example.c" "${CMAKE_CURRENT_BINDING_DIR}/rtti_dynamic.c" From 0ae3b8abe4752789f31dc6427422e716525fb640 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:12:16 -0700 Subject: [PATCH 060/143] Use printf and correct library name --- .../Examples/CDynamic/RTTI_example.c | 143 ++++++++++++------ 1 file changed, 98 insertions(+), 45 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Examples/CDynamic/RTTI_example.c b/Examples/RTTI/RTTI_component/Examples/CDynamic/RTTI_example.c index 219eaab2..ef746f8c 100644 --- a/Examples/RTTI/RTTI_component/Examples/CDynamic/RTTI_example.c +++ b/Examples/RTTI/RTTI_component/Examples/CDynamic/RTTI_example.c @@ -15,88 +15,141 @@ Interface version: 1.0.0 #include <stdio.h> #include <stdlib.h> +#include <string.h> +#include <assert.h> #include "rtti_dynamic.h" -#define printf_s printf - void releaseWrapper(sRTTIDynamicWrapperTable* pWrapperTable) { RTTIResult eResult = ReleaseRTTIWrapperTable(pWrapperTable); if (RTTI_SUCCESS != eResult) { - printf_s("Failed to release wrapper table\n"); + printf("Failed to release wrapper table\n"); } } int main() { // TODO: put a path to RTTI binary file here: - const char* libpath = "./rtti.dylib"; + const char* libpath = "rtti." +#if defined _WIN32 + "dll" +#elif defined __APPLE__ + "dylib" +#elif defined __linux__ + "so" +#endif + ; + sRTTIDynamicWrapperTable sWrapperTable; RTTIResult eResult = RTTI_SUCCESS; eResult = InitRTTIWrapperTable(&sWrapperTable); if (RTTI_SUCCESS != eResult) { - printf_s("Failed to initialize wrapper table\n"); + printf("Failed to initialize wrapper table\n"); return eResult; } eResult = LoadRTTIWrapperTable(&sWrapperTable, libpath); if (RTTI_SUCCESS != eResult) { - printf_s("Failed to load rtti-binary\n"); + printf("Failed to load rtti-binary\n"); return eResult; } RTTI_uint32 nMajor, nMinor, nMicro; eResult = sWrapperTable.m_GetVersion(&nMajor, &nMinor, &nMicro); if (RTTI_SUCCESS != eResult) { - printf_s("Failed to get version\n"); + printf("Failed to get version\n"); releaseWrapper(&sWrapperTable); return eResult; } - printf_s("RTTI.Version = %d.%d.%d", nMajor, nMinor, nMicro); + printf("RTTI.Version = %d.%d.%d", nMajor, nMinor, nMicro); - printf_s("\n"); + printf("\n"); RTTI_Zoo Zoo; - eResult = sWrapperTable.m_CreateZoo(&Zoo); - if (RTTI_SUCCESS != eResult) { - printf_s("Failed to get Zoo\n"); - releaseWrapper(&sWrapperTable); - return eResult; - } + assert(RTTI_SUCCESS == sWrapperTable.m_CreateZoo(&Zoo)); RTTI_AnimalIterator Iterator; - eResult = sWrapperTable.m_Zoo_Iterator(Zoo, &Iterator); - if (RTTI_SUCCESS != eResult) { - printf_s("Failed to get Iterator\n"); - releaseWrapper(&sWrapperTable); - return eResult; - } - - while (1) { - RTTI_Animal Animal; - eResult = sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal); - if (RTTI_SUCCESS != eResult) { - printf_s("Failed to get Iterator\n"); - releaseWrapper(&sWrapperTable); - return eResult; - } - - if (!Animal.Handle) - break; - - RTTI_uint32 CharsRead = 0; - char Name[255]; - if (RTTI_SUCCESS != sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) - || RTTI_SUCCESS != sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])) { - printf_s("Failed to call Animal name\n"); - releaseWrapper(&sWrapperTable); - return eResult; - } - printf_s("Animal name: %s\n", Name); - } + assert(RTTI_SUCCESS == sWrapperTable.m_Zoo_Iterator(Zoo, &Iterator)); + + RTTI_uint32 CharsRead = 0; + char Name[256] = { 0 }; + RTTI_Animal Animal; + + assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); + assert(Animal.Handle != NULL); + assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) + && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); + assert(!strcmp(Name, "Gerald Giraffe")); + // assert(RTTI_SUCCESS != sWrapperTable.m_Tiger_Roar(Animal)); + + assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); + assert(Animal.Handle != NULL); + assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) + && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); + assert(!strcmp(Name, "Timmy Tiger")); + assert(RTTI_SUCCESS == sWrapperTable.m_Tiger_Roar(Animal)); + + assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); + assert(Animal.Handle != NULL); + assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) + && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); + assert(!strcmp(Name, "Tony Tiger")); + assert(RTTI_SUCCESS == sWrapperTable.m_Tiger_Roar(Animal)); + + assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); + assert(Animal.Handle != NULL); + assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) + && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); + assert(!strcmp(Name, "Sebastian Snake")); + // assert(RTTI_SUCCESS != sWrapperTable.m_Tiger_Roar(Animal)); + + assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); + assert(Animal.Handle != NULL); + assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) + && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); + assert(!strcmp(Name, "Tobias Turtle")); + // assert(RTTI_SUCCESS != sWrapperTable.m_Tiger_Roar(Animal)); + + assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); + assert(Animal.Handle != NULL); + assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) + && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); + assert(!strcmp(Name, "Theo Turtle")); + // assert(RTTI_SUCCESS != sWrapperTable.m_Tiger_Roar(Animal)); + + assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); + assert(Animal.Handle != NULL); + assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) + && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); + assert(!strcmp(Name, "Tomás Turtle")); + // assert(RTTI_SUCCESS != sWrapperTable.m_Tiger_Roar(Animal)); + + assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); + assert(Animal.Handle != NULL); + assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) + && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); + assert(!strcmp(Name, "Slytherin Snake")); + // assert(RTTI_SUCCESS != sWrapperTable.m_Tiger_Roar(Animal)); + + assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); + assert(Animal.Handle != NULL); + assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) + && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); + assert(!strcmp(Name, "Travis Tiger")); + assert(RTTI_SUCCESS == sWrapperTable.m_Tiger_Roar(Animal)); + + assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); + assert(Animal.Handle != NULL); + assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) + && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); + assert(!strcmp(Name, "Gary Giraffe")); + // assert(RTTI_SUCCESS != sWrapperTable.m_Tiger_Roar(Animal)); + + assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); + assert(Animal.Handle == NULL); eResult = ReleaseRTTIWrapperTable(&sWrapperTable); if (RTTI_SUCCESS != eResult) { - printf_s("Failed to release wrapper table\n"); + printf("Failed to release wrapper table\n"); return eResult; } From f1cefb79e3306a0a082f0bbb231e849dcd6c1158 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:14:34 -0700 Subject: [PATCH 061/143] Fix wrong file name --- .../RTTI/RTTI_component/Examples/CDynamic/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Examples/CDynamic/CMakeLists.txt b/Examples/RTTI/RTTI_component/Examples/CDynamic/CMakeLists.txt index 1ad3cb14..0acb961f 100644 --- a/Examples/RTTI/RTTI_component/Examples/CDynamic/CMakeLists.txt +++ b/Examples/RTTI/RTTI_component/Examples/CDynamic/CMakeLists.txt @@ -20,12 +20,12 @@ set(CMAKE_CURRENT_BINDING_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../Bindings/CDynami project(RTTIExample_CDynamic C) -file(COPY "${CMAKE_CURRENT_BINDING_DIR}/rtti_dynamic.cc" DESTINATION "${CMAKE_CURRENT_BINDING_DIR}") -file(RENAME "${CMAKE_CURRENT_BINDING_DIR}/rtti_dynamic.cc" "${CMAKE_CURRENT_BINDING_DIR}/rtti_dynamic.c") +file(COPY "${CMAKE_CURRENT_BINDING_DIR}/rtti_dynamic.cc" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") +file(RENAME "${CMAKE_CURRENT_BINARY_DIR}/rtti_dynamic.cc" "${CMAKE_CURRENT_BINARY_DIR}/rtti_dynamic.c") add_executable(RTTIExample_CDynamic "${CMAKE_CURRENT_SOURCE_DIR}/RTTI_example.c" - "${CMAKE_CURRENT_BINDING_DIR}/rtti_dynamic.c" + "${CMAKE_CURRENT_BINARY_DIR}/rtti_dynamic.c" ) set_property(TARGET RTTIExample_CDynamic PROPERTY C_STANDARD 99) From 7dabdceacf7b22d7450a05a11dcce0eb0731d784 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:19:13 -0700 Subject: [PATCH 062/143] RTTI Cpp and CppDynamic with validation --- .../Examples/Cpp/CMakeLists.txt | 4 +- .../Examples/Cpp/RTTI_example.cpp | 79 ++++++++++++++++-- .../Examples/CppDynamic/RTTI_example.cpp | 83 +++++++++++++++++-- 3 files changed, 146 insertions(+), 20 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Examples/Cpp/CMakeLists.txt b/Examples/RTTI/RTTI_component/Examples/Cpp/CMakeLists.txt index a0eb221b..a1108c3c 100644 --- a/Examples/RTTI/RTTI_component/Examples/Cpp/CMakeLists.txt +++ b/Examples/RTTI/RTTI_component/Examples/Cpp/CMakeLists.txt @@ -20,6 +20,6 @@ set(CMAKE_CURRENT_BINDING_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../Bindings/Cpp) project(RTTIExample_CPPImplicit) set(CMAKE_CXX_STANDARD 11) add_executable(RTTIExample_CPPImplicit "${CMAKE_CURRENT_SOURCE_DIR}/RTTI_example.cpp") -find_library(RTTILOCATION rtti PATHS "/Users/anpiloa/git/AutomaticComponentToolkit/Examples/build-lib") -target_link_libraries(RTTIExample_CPPImplicit ${RTTILOCATION}) +find_library(RTTI_LIB_LOCATION rtti PATHS "../../../Implementations/Cpp/build") +target_link_libraries(RTTIExample_CPPImplicit ${RTTI_LIB_LOCATION}) target_include_directories(RTTIExample_CPPImplicit PRIVATE "${CMAKE_CURRENT_BINDING_DIR}") diff --git a/Examples/RTTI/RTTI_component/Examples/Cpp/RTTI_example.cpp b/Examples/RTTI/RTTI_component/Examples/Cpp/RTTI_example.cpp index b93aeb2a..dec8b000 100644 --- a/Examples/RTTI/RTTI_component/Examples/Cpp/RTTI_example.cpp +++ b/Examples/RTTI/RTTI_component/Examples/Cpp/RTTI_example.cpp @@ -1,19 +1,20 @@ /*++ -Copyright (C) 2021 ADSK +Copyright (C) 2020 ADSK All rights reserved. This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++ application that demonstrates the - usage of the C++ bindings of RTTI + usage of the Dynamic C++ bindings of RTTI Interface version: 1.0.0 */ #include <iostream> +#include <cassert> #include "rtti_implicit.hpp" @@ -31,13 +32,73 @@ int main() auto iter = zoo->Iterator(); using namespace RTTI; - while (auto animal = iter->GetNextAnimal()) { - std::cout << "Animal name: " << animal->Name() << std::endl; - if (auto tiger = std::dynamic_pointer_cast<CTiger>(animal)) { - std::cout << " ^ is a real tiger!!!" << std::endl; - tiger->Roar(); - } - } + + PAnimal animal; + // Animal name: Gerald Giraffe + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Gerald Giraffe"); + assert(std::dynamic_pointer_cast<CGiraffe>(animal) != nullptr); + + // Animal name: Timmy Tiger + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Timmy Tiger"); + assert(std::dynamic_pointer_cast<CTiger>(animal) != nullptr); + std::dynamic_pointer_cast<CTiger>(animal)->Roar(); + + // Animal name: Tony Tiger + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Tony Tiger"); + assert(std::dynamic_pointer_cast<CTiger>(animal) != nullptr); + std::dynamic_pointer_cast<CTiger>(animal)->Roar(); + + // Animal name: Sebastian Snake + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Sebastian Snake"); + assert(std::dynamic_pointer_cast<CSnake>(animal) != nullptr); + + // Animal name: Tobias Turtle + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Tobias Turtle"); + assert(std::dynamic_pointer_cast<CTurtle>(animal) != nullptr); + + // Animal name: Theo Turtle + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Theo Turtle"); + assert(std::dynamic_pointer_cast<CTurtle>(animal) != nullptr); + + // Animal name: Tomás Turtle + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Tomás Turtle"); + assert(std::dynamic_pointer_cast<CTurtle>(animal) != nullptr); + + // Animal name: Slytherin Snake + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Slytherin Snake"); + assert(std::dynamic_pointer_cast<CSnake>(animal) != nullptr); + + // Animal name: Travis Tiger + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Travis Tiger"); + assert(std::dynamic_pointer_cast<CTiger>(animal) != nullptr); + std::dynamic_pointer_cast<CTiger>(animal)->Roar(); + + // Animal name: Gary Giraffe + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Gary Giraffe"); + assert(std::dynamic_pointer_cast<CGiraffe>(animal) != nullptr); + + animal = iter->GetNextAnimal(); + assert(animal == nullptr); } catch (std::exception &e) { diff --git a/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp b/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp index 7b244d5e..3ee5e73f 100644 --- a/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp +++ b/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp @@ -14,6 +14,7 @@ Interface version: 1.0.0 */ #include <iostream> +#include <cassert> #include "rtti_dynamic.hpp" @@ -21,8 +22,8 @@ int main() { try { - std::string libpath = ("."); // TODO: put the location of the RTTI-library file here. - auto wrapper = RTTI::CWrapper::loadLibrary(libpath + "/rtti." + std::string libpath = (""); // TODO: put the location of the RTTI-library file here. + auto wrapper = RTTI::CWrapper::loadLibrary(libpath + "rtti." #if defined _WIN32 "dll" #elif defined __APPLE__ @@ -40,13 +41,77 @@ int main() auto iter = zoo->Iterator(); using namespace RTTI; - while (auto animal = iter->GetNextAnimal()) { - std::cout << "Animal name: " << animal->Name() << std::endl; - if (auto tiger = std::dynamic_pointer_cast<CTiger>(animal)) { - std::cout << " ^ is a real tiger!!!" << std::endl; - tiger->Roar(); - } - } + + PAnimal animal; + // Animal name: Gerald Giraffe + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Gerald Giraffe"); + assert(std::dynamic_pointer_cast<CGiraffe>(animal) != nullptr); + + // Animal name: Timmy Tiger + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Timmy Tiger"); + assert(std::dynamic_pointer_cast<CTiger>(animal) != nullptr); + std::dynamic_pointer_cast<CTiger>(animal)->Roar(); + + // Animal name: Tony Tiger + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Tony Tiger"); + assert(std::dynamic_pointer_cast<CTiger>(animal) != nullptr); + std::dynamic_pointer_cast<CTiger>(animal)->Roar(); + + // Animal name: Sebastian Snake + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Sebastian Snake"); + assert(std::dynamic_pointer_cast<CSnake>(animal) != nullptr); + + // Animal name: Tobias Turtle + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Tobias Turtle"); + assert(std::dynamic_pointer_cast<CTurtle>(animal) != nullptr); + + // Animal name: Theo Turtle + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Theo Turtle"); + assert(std::dynamic_pointer_cast<CTurtle>(animal) != nullptr); + + // Animal name: Tomás Turtle + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Tomás Turtle"); + assert(std::dynamic_pointer_cast<CTurtle>(animal) != nullptr); + + // Animal name: Slytherin Snake + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Slytherin Snake"); + assert(std::dynamic_pointer_cast<CSnake>(animal) != nullptr); + + // Animal name: Travis Tiger + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Travis Tiger"); + assert(std::dynamic_pointer_cast<CTiger>(animal) != nullptr); + std::dynamic_pointer_cast<CTiger>(animal)->Roar(); + + // Animal name: Gary Giraffe + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Gary Giraffe"); + assert(std::dynamic_pointer_cast<CGiraffe>(animal) != nullptr); + + std::cout << "Trace 0" << std::endl; + + animal = iter->GetNextAnimal(); + assert(animal == nullptr); + + std::cout << "Trace 1" << std::endl; } catch (std::exception &e) { From c3c7a85f578611401ffb7020d8038ee081f67366 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:19:44 -0700 Subject: [PATCH 063/143] RTTI Python example with validation --- .../Examples/Python/RTTI_Example.py | 74 +++++++++++++++++-- 1 file changed, 66 insertions(+), 8 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py b/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py index b735c184..98ebaabf 100644 --- a/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py +++ b/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py @@ -28,14 +28,72 @@ def main(): print("RTTI version: {:d}.{:d}.{:d}".format(major, minor, micro), end="") print("") - zoo = wrapper.CreateZoo() - iter = zoo.Iterator() - - while animal := iter.GetNextAnimal(): - if isinstance(animal, RTTI.Tiger): - print(" ^ is a real tiger!!!") - animal.Roar() - print("Animal name: " + animal.Name()) + zoo = wrapper.CreateZoo(); assert zoo + iter = zoo.Iterator(); assert iter + + # Animal name: Gerald Giraffe + animal = iter.GetNextAnimal(); assert animal + assert animal.Name() == "Gerald Giraffe" + assert isinstance(animal, RTTI.Giraffe) + + # Animal name: Timmy Tiger + animal = iter.GetNextAnimal(); assert animal + + assert animal.Name() == "Timmy Tiger" + assert isinstance(animal, RTTI.Tiger) + animal.Roar() + + # Animal name: Tony Tiger + animal = iter.GetNextAnimal(); assert animal + + assert animal.Name() == "Tony Tiger" + assert isinstance(animal, RTTI.Tiger) + animal.Roar() + + # Animal name: Sebastian Snake + animal = iter.GetNextAnimal(); assert animal + + assert animal.Name() == "Sebastian Snake" + assert isinstance(animal, RTTI.Snake) + + # Animal name: Tobias Turtle + animal = iter.GetNextAnimal(); assert animal + + assert animal.Name() == "Tobias Turtle" + assert isinstance(animal, RTTI.Turtle) + + # Animal name: Theo Turtle + animal = iter.GetNextAnimal(); assert animal + + assert animal.Name() == "Theo Turtle" + assert isinstance(animal, RTTI.Turtle) + + # Animal name: Tomás Turtle + animal = iter.GetNextAnimal(); assert animal + + assert animal.Name() == "Tomás Turtle" + assert isinstance(animal, RTTI.Turtle) + + # Animal name: Slytherin Snake + animal = iter.GetNextAnimal(); assert animal + + assert animal.Name() == "Slytherin Snake" + assert isinstance(animal, RTTI.Snake) + + # Animal name: Travis Tiger + animal = iter.GetNextAnimal(); assert animal + + assert animal.Name() == "Travis Tiger" + assert isinstance(animal, RTTI.Tiger) + animal.Roar() + + # Animal name: Gary Giraffe + animal = iter.GetNextAnimal(); assert animal + + assert animal.Name() == "Gary Giraffe" + assert isinstance(animal, RTTI.Giraffe) + + animal = iter.GetNextAnimal(); assert not animal if __name__ == "__main__": try: From aa0c90dd5972e67d0f38b0ae826a9931ac1ae6f4 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:22:22 -0700 Subject: [PATCH 064/143] RTTI Go: get library path from command line Main issue is that go ifdef compile time statement is not reliable on MacOS --- Examples/RTTI/RTTI_component/Examples/Go/RTTI_example.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Examples/RTTI/RTTI_component/Examples/Go/RTTI_example.go b/Examples/RTTI/RTTI_component/Examples/Go/RTTI_example.go index 32cc0eb8..a2e8df81 100644 --- a/Examples/RTTI/RTTI_component/Examples/Go/RTTI_example.go +++ b/Examples/RTTI/RTTI_component/Examples/Go/RTTI_example.go @@ -17,6 +17,7 @@ Interface version: 1.0.0 package main import ( + "os" "fmt" "log" "../../Bindings/Go" @@ -24,7 +25,7 @@ import ( func main() { fmt.Println("Start") - wrapper, err := rtti.LoadLibrary("rtti.dylib") + wrapper, err := rtti.LoadLibrary(os.Args[1:][0]) if err != nil { fmt.Println(err) } From 0c7d091cf4b5cafe2f48d26036ef0a587790f0fd Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:23:45 -0700 Subject: [PATCH 065/143] Tune path so it could be defined by env --- Examples/RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpr b/Examples/RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpr index c282b039..1220abf7 100644 --- a/Examples/RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpr +++ b/Examples/RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpr @@ -48,7 +48,7 @@ procedure TRTTI_Example.TestRTTI(); begin writeln('loading DLL'); ALibPath := '.'; // TODO add the location of the shared library binary here - ARTTIWrapper := TRTTIWrapper.Create(ALibPath + '/' + 'rtti.'); // TODO add the extension of the shared library file here + ARTTIWrapper := TRTTIWrapper.Create(ALibPath + '/' + 'rtti.dll'); // TODO add the extension of the shared library file here try writeln('loading DLL Done'); From 9123b77baeed9ae23022d69697f6ac09e5dbb573 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:24:03 -0700 Subject: [PATCH 066/143] RTTI Java eexample with validation --- .../Examples/Java9/RTTI_Example.java | 81 ++++++++++++++++--- 1 file changed, 69 insertions(+), 12 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Examples/Java9/RTTI_Example.java b/Examples/RTTI/RTTI_component/Examples/Java9/RTTI_Example.java index 188bb100..bdf526ec 100644 --- a/Examples/RTTI/RTTI_component/Examples/Java9/RTTI_Example.java +++ b/Examples/RTTI/RTTI_component/Examples/Java9/RTTI_Example.java @@ -18,9 +18,8 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. public class RTTI_Example { - public static String libpath = "/Users/anpiloa/git/AutomaticComponentToolkit/Examples/RTTI/build-lib/rtti.dylib"; // TODO add the location of the shared library binary here - public static void main(String[] args) throws RTTIException { + String libpath = args[0]; RTTIWrapper wrapper = new RTTIWrapper(libpath); RTTIWrapper.GetVersionResult version = wrapper.getVersion(); @@ -30,16 +29,74 @@ public static void main(String[] args) throws RTTIException { Zoo zoo = wrapper.createZoo(); AnimalIterator iterator = zoo.iterator(); - while (true) { - Animal animal = iterator.getNextAnimal(); - if (animal == null) break; - System.out.print("Animal name: " + animal.name()); - System.out.println(); - if (animal instanceof Tiger) { - System.out.println(" ^ is a real tiger!!!"); - ((Tiger)animal).roar(); - } - } + + Animal animal; + // Animal name: Gerald Giraffe + animal = iterator.getNextAnimal(); + assert(animal != null); + assert(animal.name().equals("Gerald Giraffe")); + assert(animal instanceof Giraffe); + + // Animal name: Timmy Tiger + animal = iterator.getNextAnimal(); + assert(animal != null); + assert(animal.name().equals("Timmy Tiger")); + assert(animal instanceof Tiger); + ((Tiger)animal).roar(); + + // Animal name: Tony Tiger + animal = iterator.getNextAnimal(); + assert(animal != null); + assert(animal.name().equals("Tony Tiger")); + assert(animal instanceof Tiger); + ((Tiger)animal).roar(); + + // Animal name: Sebastian Snake + animal = iterator.getNextAnimal(); + assert(animal != null); + assert(animal.name().equals("Sebastian Snake")); + assert(animal instanceof Snake); + + // Animal name: Tobias Turtle + animal = iterator.getNextAnimal(); + assert(animal != null); + assert(animal.name().equals("Tobias Turtle")); + assert(animal instanceof Turtle); + + // Animal name: Theo Turtle + animal = iterator.getNextAnimal(); + assert(animal != null); + assert(animal.name().equals("Theo Turtle")); + assert(animal instanceof Turtle); + + // Animal name: Tomás Turtle + animal = iterator.getNextAnimal(); + assert(animal != null); + assert(animal.name().equals("Tomás Turtle")); + assert(animal instanceof Turtle); + + // Animal name: Slytherin Snake + animal = iterator.getNextAnimal(); + assert(animal != null); + assert(animal.name().equals("Slytherin Snake")); + assert(animal instanceof Snake); + + // Animal name: Travis Tiger + animal = iterator.getNextAnimal(); + assert(animal != null); + assert(animal.name().equals("Travis Tiger")); + assert(animal instanceof Tiger); + ((Tiger)animal).roar(); + + // Animal name: Gary Giraffe + animal = iterator.getNextAnimal(); + assert(animal != null); + assert(animal.name().equals("Gary Giraffe")); + assert(animal instanceof Giraffe); + + animal = iterator.getNextAnimal(); + assert(animal == null); + } } From 35bba35fdfeb3caf4003a65da8d8408a4d5f272d Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:24:29 -0700 Subject: [PATCH 067/143] RTTI C# with validation --- .../Examples/CSharp/RTTI_Example.cs | 81 ++++++++++++++++--- 1 file changed, 68 insertions(+), 13 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.cs b/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.cs index 05446c09..15dbc362 100644 --- a/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.cs +++ b/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.cs @@ -30,25 +30,80 @@ static void Main() RTTI.CZoo Zoo = RTTI.Wrapper.CreateZoo(); RTTI.CAnimalIterator Iterator = Zoo.Iterator(); - - while (true) { - RTTI.CAnimal Animal = Iterator.GetNextAnimal(); - if (Animal.GetHandle().Handle == 0) - break; - Console.WriteLine("Animal name: " + Animal.Name()); - if (Animal is RTTI.CTiger) { - Console.WriteLine(" ^ is a real tiger!!!"); - (Animal as RTTI.CTiger).Roar(); - } - } + RTTI.CAnimal Animal; + + // Animal name: Gerald Giraffe + Animal = Iterator.GetNextAnimal(); + if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.Name().Equals("Gerald Giraffe"))) throw new Exception("Wrong data"); + if (!(Animal is RTTI.CGiraffe)) throw new Exception("Wrong data"); + + // Animal name: Timmy Tiger + Animal = Iterator.GetNextAnimal(); + if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.Name().Equals("Timmy Tiger"))) throw new Exception("Wrong data"); + if (!(Animal is RTTI.CTiger)) throw new Exception("Wrong data"); + (Animal as RTTI.CTiger).Roar(); + + // Animal name: Tony Tiger + Animal = Iterator.GetNextAnimal(); + if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.Name().Equals("Tony Tiger"))) throw new Exception("Wrong data"); + if (!(Animal is RTTI.CTiger)) throw new Exception("Wrong data"); + (Animal as RTTI.CTiger).Roar(); + + // Animal name: Sebastian Snake + Animal = Iterator.GetNextAnimal(); + if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.Name().Equals("Sebastian Snake"))) throw new Exception("Wrong data"); + if (!(Animal is RTTI.CSnake)) throw new Exception("Wrong data"); + + // Animal name: Tobias Turtle + Animal = Iterator.GetNextAnimal(); + if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.Name().Equals("Tobias Turtle"))) throw new Exception("Wrong data"); + if (!(Animal is RTTI.CTurtle)) throw new Exception("Wrong data"); + + // Animal name: Theo Turtle + Animal = Iterator.GetNextAnimal(); + if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.Name().Equals("Theo Turtle"))) throw new Exception("Wrong data"); + if (!(Animal is RTTI.CTurtle)) throw new Exception("Wrong data"); + + // Animal name: Tomás Turtle + Animal = Iterator.GetNextAnimal(); + if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.Name().Equals("Tomás Turtle"))) throw new Exception("Wrong data"); + if (!(Animal is RTTI.CTurtle)) throw new Exception("Wrong data"); + + // Animal name: Slytherin Snake + Animal = Iterator.GetNextAnimal(); + if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.Name().Equals("Slytherin Snake"))) throw new Exception("Wrong data"); + if (!(Animal is RTTI.CSnake)) throw new Exception("Wrong data"); + + // Animal name: Travis Tiger + Animal = Iterator.GetNextAnimal(); + if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.Name().Equals("Travis Tiger"))) throw new Exception("Wrong data"); + if (!(Animal is RTTI.CTiger)) throw new Exception("Wrong data"); + (Animal as RTTI.CTiger).Roar(); + + // Animal name: Gary Giraffe + Animal = Iterator.GetNextAnimal(); + if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.Name().Equals("Gary Giraffe"))) throw new Exception("Wrong data"); + if (!(Animal is RTTI.CGiraffe)) throw new Exception("Wrong data"); + + Animal = Iterator.GetNextAnimal(); + if (!(Animal.GetHandle().Handle == 0)) throw new Exception("Wrong data"); } catch (Exception e) { Console.WriteLine("Exception: \"" + e.Message + "\""); + System.Environment.Exit(1); } - Console.WriteLine("Press any key to exit."); - Console.ReadKey(); } } } From 56aa2f94bfbcae473c102e1e60896f86788e0a4c Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:24:44 -0700 Subject: [PATCH 068/143] Ignore C# specific subfolders --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index a848edf5..b9ebb9c2 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,8 @@ __pycache__ Examples/**/build Examples/**/build-* +Examples/**/bin +Examples/**/obj # Visual Studio Code debug From 39c1a2d3f1bca922c98d34f5096017e3f35dbbbf Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:29:37 -0700 Subject: [PATCH 069/143] Use OS independent path to libraries --- .../Examples/Cpp/Calculation_example.cpp | 10 +++++++++- .../CppDynamic/Calculation_example.cpp | 20 +++++++++++++++++-- .../Examples/Pascal/Calculation_Example.lpr | 6 +++--- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/Examples/Injection/Calculation_component/Examples/Cpp/Calculation_example.cpp b/Examples/Injection/Calculation_component/Examples/Cpp/Calculation_example.cpp index 8dce8446..7ee11844 100644 --- a/Examples/Injection/Calculation_component/Examples/Cpp/Calculation_example.cpp +++ b/Examples/Injection/Calculation_component/Examples/Cpp/Calculation_example.cpp @@ -28,7 +28,15 @@ int main() std::cout << std::endl; std::string libpath = ""; - auto numbers = Numbers::CWrapper::loadLibrary(libpath + "/numbers."); + auto numbers = Numbers::CWrapper::loadLibrary(libpath + "numbers." +#if defined _WIN32 + "dll" +#elif defined __APPLE__ + "dylib" +#elif defined __linux__ + "so" +#endif + ); numbers->GetVersion(nMajor, nMinor, nMicro); std::cout << "Numbers.Version = " << nMajor << "." << nMinor << "." << nMicro; std::cout << std::endl; diff --git a/Examples/Injection/Calculation_component/Examples/CppDynamic/Calculation_example.cpp b/Examples/Injection/Calculation_component/Examples/CppDynamic/Calculation_example.cpp index 31258a82..94a2ec9d 100644 --- a/Examples/Injection/Calculation_component/Examples/CppDynamic/Calculation_example.cpp +++ b/Examples/Injection/Calculation_component/Examples/CppDynamic/Calculation_example.cpp @@ -22,10 +22,26 @@ int main() try { std::string libpath = ""; // TODO: put the location of the Calculation-library file here. - auto wrapper = Calculation::CWrapper::loadLibrary(libpath + "/calculation."); // TODO: add correct suffix of the library + auto wrapper = Calculation::CWrapper::loadLibrary(libpath + "calculation." +#if defined _WIN32 + "dll" +#elif defined __APPLE__ + "dylib" +#elif defined __linux__ + "so" +#endif + ); // TODO: add correct suffix of the library libpath = ""; - auto numbers = Numbers::CWrapper::loadLibrary(libpath + "/numbers."); + auto numbers = Numbers::CWrapper::loadLibrary(libpath + "numbers." +#if defined _WIN32 + "dll" +#elif defined __APPLE__ + "dylib" +#elif defined __linux__ + "so" +#endif + ); Calculation_uint32 nMajor, nMinor, nMicro; wrapper->GetVersion(nMajor, nMinor, nMicro); diff --git a/Examples/Injection/Calculation_component/Examples/Pascal/Calculation_Example.lpr b/Examples/Injection/Calculation_component/Examples/Pascal/Calculation_Example.lpr index 7d890fc5..b60e22c0 100644 --- a/Examples/Injection/Calculation_component/Examples/Pascal/Calculation_Example.lpr +++ b/Examples/Injection/Calculation_component/Examples/Pascal/Calculation_Example.lpr @@ -14,7 +14,7 @@ *) program CalculationPascalTest; - +{$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, @@ -48,7 +48,7 @@ procedure TCalculation_Example.TestCalculation (); begin writeln ('loading DLL'); ALibPath := ''; // TODO add the location of the shared library binary here - ACalculationWrapper := TCalculationWrapper.Create (ALibPath + '/' + 'calculation.dll'); // TODO add the extension of the shared library file here + ACalculationWrapper := TCalculationWrapper.Create (ALibPath + 'calculation.dll'); // TODO add the extension of the shared library file here try writeln ('loading DLL Done'); ACalculationWrapper.GetVersion(AMajor, AMinor, AMicro); @@ -56,7 +56,7 @@ procedure TCalculation_Example.TestCalculation (); writeln(AVersionString); ALibPath := ''; - ANumbersWrapper := TNumbersWrapper.Create (ALibPath + '/' + 'numbers.'); // TODO add the extension of the shared library file here + ANumbersWrapper := TNumbersWrapper.Create (ALibPath + 'numbers.dll'); // TODO add the extension of the shared library file here ANumbersWrapper.GetVersion(AMajor, AMinor, AMicro); AVersionString := Format('Numbers.version = %d.%d.%d', [AMajor, AMinor, AMicro]); writeln(AVersionString); From c7ca136fb3ffeba120afb58514717acfad4243b8 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:30:08 -0700 Subject: [PATCH 070/143] Update Injection exmaple implementation --- .../Implementations/Pascal/Stub/calculation_impl.pas | 2 +- .../Pascal/Stub/calculation_impl_base.pas | 9 +++++---- .../Pascal/Stub/calculation_impl_calculator.pas | 5 +++++ .../Implementations/Pascal/calculation.def | 1 + Examples/Injection/Calculation_component/license.txt | 5 +++++ .../Implementations/Pascal/Stub/numbers_impl.pas | 2 +- .../Implementations/Pascal/Stub/numbers_impl_base.pas | 9 +++++---- .../Pascal/Stub/numbers_impl_variable.pas | 8 +++++++- .../Numbers_component/Implementations/Pascal/numbers.def | 1 + Examples/Injection/Numbers_component/license.txt | 5 +++++ 10 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 Examples/Injection/Calculation_component/license.txt create mode 100644 Examples/Injection/Numbers_component/license.txt diff --git a/Examples/Injection/Calculation_component/Implementations/Pascal/Stub/calculation_impl.pas b/Examples/Injection/Calculation_component/Implementations/Pascal/Stub/calculation_impl.pas index 6f59adbe..c16247cd 100644 --- a/Examples/Injection/Calculation_component/Implementations/Pascal/Stub/calculation_impl.pas +++ b/Examples/Injection/Calculation_component/Implementations/Pascal/Stub/calculation_impl.pas @@ -4,7 +4,7 @@ All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated Pascal implementation file in order to allow easy development of Calculation library. It needs to be generated only once. diff --git a/Examples/Injection/Calculation_component/Implementations/Pascal/Stub/calculation_impl_base.pas b/Examples/Injection/Calculation_component/Implementations/Pascal/Stub/calculation_impl_base.pas index ac906aac..47d341f7 100644 --- a/Examples/Injection/Calculation_component/Implementations/Pascal/Stub/calculation_impl_base.pas +++ b/Examples/Injection/Calculation_component/Implementations/Pascal/Stub/calculation_impl_base.pas @@ -37,6 +37,7 @@ TCalculationBase = class(TObject, ICalculationBase) procedure RegisterErrorMessage(const AErrorMessage: String); procedure IncRefCount(); function DecRefCount(): Boolean; + function ClassTypeId(): QWord; Virtual; Abstract; end; implementation @@ -68,7 +69,6 @@ procedure TCalculationBase.ClearErrorMessages(); procedure TCalculationBase.RegisterErrorMessage(const AErrorMessage: String); begin - FMessages.Clear(); FMessages.Add(AErrorMessage); end; @@ -81,10 +81,11 @@ function TCalculationBase.DecRefCount(): Boolean; begin dec(FReferenceCount); if (FReferenceCount = 0) then begin - result := true; self.Destroy(); - end; - result := false; + result := true; + end + else + result := false; end; end. diff --git a/Examples/Injection/Calculation_component/Implementations/Pascal/Stub/calculation_impl_calculator.pas b/Examples/Injection/Calculation_component/Implementations/Pascal/Stub/calculation_impl_calculator.pas index 07d09915..5828f548 100644 --- a/Examples/Injection/Calculation_component/Implementations/Pascal/Stub/calculation_impl_calculator.pas +++ b/Examples/Injection/Calculation_component/Implementations/Pascal/Stub/calculation_impl_calculator.pas @@ -32,6 +32,7 @@ TCalculationCalculator = class(TCalculationBase, ICalculationCalculator) public constructor Create(); destructor Destroy(); override; + function ClassTypeId(): QWord; Override; procedure EnlistVariable(AVariable: TNumbersVariable); function GetEnlistedVariable(const AIndex: Cardinal): TNumbersVariable; procedure ClearVariables(); @@ -42,6 +43,10 @@ TCalculationCalculator = class(TCalculationBase, ICalculationCalculator) implementation uses calculation_impl; +function TCalculationCalculator.ClassTypeId(): QWord; +begin + Result := QWord($B23F514353D0C606); // First 64 bits of SHA1 of a string: "Calculation::Calculator" +end; constructor TCalculationCalculator.Create(); begin diff --git a/Examples/Injection/Calculation_component/Implementations/Pascal/calculation.def b/Examples/Injection/Calculation_component/Implementations/Pascal/calculation.def index fa02d256..b55bdb98 100644 --- a/Examples/Injection/Calculation_component/Implementations/Pascal/calculation.def +++ b/Examples/Injection/Calculation_component/Implementations/Pascal/calculation.def @@ -6,6 +6,7 @@ calculation_releaseinstance calculation_acquireinstance calculation_injectcomponent calculation_getsymbollookupmethod +calculation_base_classtypeid calculation_calculator_enlistvariable calculation_calculator_getenlistedvariable calculation_calculator_clearvariables diff --git a/Examples/Injection/Calculation_component/license.txt b/Examples/Injection/Calculation_component/license.txt new file mode 100644 index 00000000..9b485a9b --- /dev/null +++ b/Examples/Injection/Calculation_component/license.txt @@ -0,0 +1,5 @@ +Copyright (C) 2019 Calculation developers + +All rights reserved. + + diff --git a/Examples/Injection/Numbers_component/Implementations/Pascal/Stub/numbers_impl.pas b/Examples/Injection/Numbers_component/Implementations/Pascal/Stub/numbers_impl.pas index 941df853..b7f54a2d 100644 --- a/Examples/Injection/Numbers_component/Implementations/Pascal/Stub/numbers_impl.pas +++ b/Examples/Injection/Numbers_component/Implementations/Pascal/Stub/numbers_impl.pas @@ -4,7 +4,7 @@ All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated Pascal implementation file in order to allow easy development of Numbers library. It needs to be generated only once. diff --git a/Examples/Injection/Numbers_component/Implementations/Pascal/Stub/numbers_impl_base.pas b/Examples/Injection/Numbers_component/Implementations/Pascal/Stub/numbers_impl_base.pas index ac16757d..83338c01 100644 --- a/Examples/Injection/Numbers_component/Implementations/Pascal/Stub/numbers_impl_base.pas +++ b/Examples/Injection/Numbers_component/Implementations/Pascal/Stub/numbers_impl_base.pas @@ -36,6 +36,7 @@ TNumbersBase = class(TObject, INumbersBase) procedure RegisterErrorMessage(const AErrorMessage: String); procedure IncRefCount(); function DecRefCount(): Boolean; + function ClassTypeId(): QWord; Virtual; Abstract; end; implementation @@ -67,7 +68,6 @@ procedure TNumbersBase.ClearErrorMessages(); procedure TNumbersBase.RegisterErrorMessage(const AErrorMessage: String); begin - FMessages.Clear(); FMessages.Add(AErrorMessage); end; @@ -80,10 +80,11 @@ function TNumbersBase.DecRefCount(): Boolean; begin dec(FReferenceCount); if (FReferenceCount = 0) then begin - result := true; self.Destroy(); - end; - result := false; + result := true; + end + else + result := false; end; end. diff --git a/Examples/Injection/Numbers_component/Implementations/Pascal/Stub/numbers_impl_variable.pas b/Examples/Injection/Numbers_component/Implementations/Pascal/Stub/numbers_impl_variable.pas index 99897cf5..de57e529 100644 --- a/Examples/Injection/Numbers_component/Implementations/Pascal/Stub/numbers_impl_variable.pas +++ b/Examples/Injection/Numbers_component/Implementations/Pascal/Stub/numbers_impl_variable.pas @@ -28,13 +28,19 @@ TNumbersVariable = class(TNumbersBase, INumbersVariable) protected public - constructor Create(AInitialValue: double); + function ClassTypeId(): QWord; Override; + constructor Create(AInitialValue: double); function GetValue(): Double; procedure SetValue(const AValue: Double); end; implementation +function TNumbersVariable.ClassTypeId(): QWord; +begin + Result := QWord($23934EDF762423EA); // First 64 bits of SHA1 of a string: "Numbers::Variable" +end; + constructor TNumbersVariable.Create(AInitialValue: double); begin inherited Create(); diff --git a/Examples/Injection/Numbers_component/Implementations/Pascal/numbers.def b/Examples/Injection/Numbers_component/Implementations/Pascal/numbers.def index e3a97f4a..3a305814 100644 --- a/Examples/Injection/Numbers_component/Implementations/Pascal/numbers.def +++ b/Examples/Injection/Numbers_component/Implementations/Pascal/numbers.def @@ -5,5 +5,6 @@ numbers_getlasterror numbers_releaseinstance numbers_acquireinstance numbers_getsymbollookupmethod +numbers_base_classtypeid numbers_variable_getvalue numbers_variable_setvalue diff --git a/Examples/Injection/Numbers_component/license.txt b/Examples/Injection/Numbers_component/license.txt new file mode 100644 index 00000000..4a9d6301 --- /dev/null +++ b/Examples/Injection/Numbers_component/license.txt @@ -0,0 +1,5 @@ +Copyright (C) 2019 Numbers developers + +All rights reserved. + + From 9f80a6a7e5d9e19dfe6259481a6a2d1f2d6d9520 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 10:52:10 -0700 Subject: [PATCH 071/143] Fix MacOS vuild script --- Build/build.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Build/build.inc b/Build/build.inc index 36f6dcba..54da1599 100644 --- a/Build/build.inc +++ b/Build/build.inc @@ -41,7 +41,7 @@ case $OS in OSEXEEXT='.exe' ;; Darwin*) - OSEXT='.mac' + OSEXT='.darwin' OSLIBEXT='.dylib' OSEXEEXT= ;; From c54dffc23dc066bf7376f0533f66c73faf6929ca Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 11:18:51 -0700 Subject: [PATCH 072/143] PolymorphicFactory should return object of default class --- Source/buildbindingjava.go | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/buildbindingjava.go b/Source/buildbindingjava.go index cdba6975..e1f8e403 100644 --- a/Source/buildbindingjava.go +++ b/Source/buildbindingjava.go @@ -1262,6 +1262,7 @@ func buildJavaWrapper(component ComponentDefinition, w LanguageWriter, indent st w.Writeln(" }") w.Writeln(" break;") } + w.Writeln(" default: obj = cls.getDeclaredConstructor(cArg).newInstance(this, handle); break;") w.Writeln(" }") w.Writeln(" return obj;") From e75868ec0011677d690154012c22f87c1d682da3 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 11:19:47 -0700 Subject: [PATCH 073/143] Sort classes to have consistent changes in bindings --- Source/buildbindingjava.go | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/Source/buildbindingjava.go b/Source/buildbindingjava.go index e1f8e403..f653b6f3 100644 --- a/Source/buildbindingjava.go +++ b/Source/buildbindingjava.go @@ -41,6 +41,7 @@ import ( "bytes" "os" "strconv" + "sort" ) type JavaParameter struct { @@ -1249,8 +1250,26 @@ func buildJavaWrapper(component ComponentDefinition, w LanguageWriter, indent st msb := uint32((classTypeId >> 32) & 0xFFFFFFFF) msbIds[msb] = append(msbIds[msb], class) } + + // Sork Ids so change to binding file is always human readable + msbKeys := make([]uint32, len(msbIds)) + i := 0 + for k := range msbIds { + msbKeys[i] = k + i++ + } + sort.Slice(msbKeys, func(i, j int) bool { return msbKeys[i] < msbKeys[j] }) + w.Writeln(" switch(msbId) {") - for id, classes := range msbIds { + // for id, classes := range msbIds { + for _, id := range msbKeys { + classes := msbIds[id] + // Sork Ids so change to binding file is always human readable + sort.Slice(classes, func(i, j int) bool { + iId, _ := classes[i].classTypeId(NameSpace) + jId, _ := classes[j].classTypeId(NameSpace) + return uint32(iId & 0xFFFFFFFF) < uint32(jId & 0xFFFFFFFF) + }) w.Writeln(" case 0x%08X: ", id) w.Writeln(" switch(lsbId) {") for i := 0; i < len(classes); i++ { From d48c69869fb224e7735f1fd11da81172c603f1ef Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 11:50:56 -0700 Subject: [PATCH 074/143] Add a warning comment to PolymorphicFactory method --- Source/buildbindingccpp.go | 7 +++++++ Source/buildbindingcsharp.go | 7 +++++++ Source/buildbindingjava.go | 7 +++++++ Source/buildbindingpascal.go | 8 +++++++- Source/buildbindingpython.go | 7 +++++++ 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index dbcec722..54f74ff3 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -1443,6 +1443,13 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln("**************************************************************************************************************************/") w.Writeln("") + w.Writeln("/**") + w.Writeln("* IMPORTANT: PolymorphicFactory method should not be used by application directly.") + w.Writeln("* It's designed to be used on %sHandle object only once.", NameSpace) + w.Writeln("* If it's used on any existing object as a form of dynamic cast then") + w.Writeln("* %s%sWrapper::AcquireInstance(C%s object) must be called after instantiating new object.", cppClassPrefix, ClassIdentifier, component.Global.BaseClassName) + w.Writeln("* This is important to keep reference count matching between application and library sides.") + w.Writeln("*/") w.Writeln("template <class T>") w.Writeln("std::shared_ptr<T> %s%sWrapper::polymorphicFactory(%sHandle pHandle)", cppClassPrefix, ClassIdentifier, NameSpace) w.Writeln("{") diff --git a/Source/buildbindingcsharp.go b/Source/buildbindingcsharp.go index 040cd005..9f0856a6 100644 --- a/Source/buildbindingcsharp.go +++ b/Source/buildbindingcsharp.go @@ -969,6 +969,13 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW w.Writeln(" }") w.Writeln("") + w.Writeln(" /**") + w.Writeln(" * IMPORTANT: PolymorphicFactory method should not be used by application directly.") + w.Writeln(" * It's designed to be used on %sHandle object only once.", NameSpace) + w.Writeln(" * If it's used on any existing object as a form of dynamic cast then") + w.Writeln(" * %sWrapper::AcquireInstance(C%s object) must be called after instantiating new object.", NameSpace, component.Global.BaseClassName) + w.Writeln(" * This is important to keep reference count matching between application and library sides.") + w.Writeln(" */") w.Writeln(" public static T PolymorphicFactory<T>(%sHandle Handle) where T : class", NameSpace) w.Writeln(" {") w.Writeln(" T Object;") diff --git a/Source/buildbindingjava.go b/Source/buildbindingjava.go index f653b6f3..0321e020 100644 --- a/Source/buildbindingjava.go +++ b/Source/buildbindingjava.go @@ -1233,6 +1233,13 @@ func buildJavaWrapper(component ComponentDefinition, w LanguageWriter, indent st } // Write PolymorphicFactory + w.Writeln(" /**") + w.Writeln(" * IMPORTANT: PolymorphicFactory method should not be used by application directly.") + w.Writeln(" * It's designed to be used on %sHandle object only once.", NameSpace) + w.Writeln(" * If it's used on any existing object as a form of dynamic cast then") + w.Writeln(" * %sWrapper::acquireInstance(%s object) must be called after instantiating new object.", NameSpace, component.Global.BaseClassName) + w.Writeln(" * This is important to keep reference count matching between application and library sides.") + w.Writeln(" */") w.Writeln(" public <T> T PolymorphicFactory(%sHandle handle, Class<T> cls) {", NameSpace) w.Writeln(" Class[] cArg = new Class[2];") w.Writeln(" cArg[0] = %sWrapper.class;", NameSpace) diff --git a/Source/buildbindingpascal.go b/Source/buildbindingpascal.go index c3442365..5fa01b9c 100644 --- a/Source/buildbindingpascal.go +++ b/Source/buildbindingpascal.go @@ -427,7 +427,13 @@ func buildDynamicPascalImplementation(component ComponentDefinition, w LanguageW w.Writeln(" PolymorficFactory implementation") w.Writeln("**************************************************************************************************************************)") w.Writeln("") - + w.Writeln(" (**") + w.Writeln(" * IMPORTANT: PolymorphicFactory method should not be used by application directly.") + w.Writeln(" * It's designed to be used on %sHandle object only once.", NameSpace) + w.Writeln(" * If it's used on any existing object as a form of dynamic cast then") + w.Writeln(" * T%sWrapper::AcquireInstance(object: T%s%s) must be called after instantiating new object.", strings.ToUpper(NameSpace), strings.ToUpper(NameSpace), component.Global.BaseClassName) + w.Writeln(" * This is important to keep reference count matching between application and library sides.") + w.Writeln(" *)") w.Writeln(" class function T%sPolymorphicFactory<_T, _B>.Make(Wrapper: T%sWrapper; Handle: T%sHandle): _T;", NameSpace, NameSpace, NameSpace) w.Writeln(" var") w.Writeln(" ClassTypeId: QWord;") diff --git a/Source/buildbindingpython.go b/Source/buildbindingpython.go index 89cb4089..6f168552 100644 --- a/Source/buildbindingpython.go +++ b/Source/buildbindingpython.go @@ -365,6 +365,13 @@ func buildDynamicPythonImplementation(componentdefinition ComponentDefinition, w } } + w.Writeln(" '''IMPORTANT: PolymorphicFactory method should not be used by application directly.") + w.Writeln(" It's designed to be used on %sHandle object only once.", NameSpace) + w.Writeln(" If it's used on any existing object as a form of dynamic cast then") + w.Writeln(" Wrapper.AcquireInstance(object) must be called after instantiating new object.") + w.Writeln(" This is important to keep reference count matching between application and library sides.") + w.Writeln(" '''") + w.Writeln(" def _polymorphicFactory(self, handle):") w.Writeln(" class PolymorphicFactory():") w.Writeln(" def getObjectById(self, classtypeid, handle, wrapper):") From e55dffdf5528ef3f152edee6ab5fafeecc091183 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 13:41:40 -0700 Subject: [PATCH 075/143] Revert Go binding generator --- Source/buildbindinggo.go | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/Source/buildbindinggo.go b/Source/buildbindinggo.go index ecdc57fc..030fba7e 100644 --- a/Source/buildbindinggo.go +++ b/Source/buildbindinggo.go @@ -423,7 +423,7 @@ func buildGoClass(component ComponentDefinition, class ComponentDefinitionClass, w.Writeln("// Release releases the C pointer.") w.Writeln("func (inst %s) Release() error {", class.ClassName) w.Writeln(" err := inst.wrapperRef.%s(inst)", component.Global.ReleaseMethod) - w.Writeln(" (*inst.gcPtr).Handle = nil") + w.Writeln(" *inst.gcPtr = nil") w.Writeln(" return err") w.Writeln("}") w.Writeln("") @@ -478,7 +478,7 @@ func WriteCGoAbiMethod(method ComponentDefinitionMethod, w LanguageWriter, NameS } w.Writeln("") - w.Writeln("%sResult CCall_%s(%s_pvoid libraryHandle, %s)", NameSpace, CMethodName, NameSpace, strings.Join(parameters, ", ")) + w.Writeln("%sResult CCall_%s(%sHandle libraryHandle, %s)", NameSpace, CMethodName, NameSpace, strings.Join(parameters, ", ")) w.Writeln("{") w.Writeln(" if (libraryHandle == 0) ") w.Writeln(" return %s_ERROR_INVALIDCAST;", strings.ToUpper(NameSpace)) @@ -533,10 +533,9 @@ func buildGoWrapper(component ComponentDefinition, w LanguageWriter) error { w.Writeln("package %s", packageName) w.Writeln("") w.Writeln("/*") - w.Writeln("#cgo linux LDFLAGS: -ldl") w.Writeln("#include \"%s_dynamic.cc\"", packageName) w.Writeln("") - w.Writeln("%s_pvoid load%sLibrary (const char * pFileName)", component.NameSpace, component.NameSpace) + w.Writeln("%sHandle load%sLibrary (const char * pFileName)", component.NameSpace, component.NameSpace) w.Writeln("{") w.Writeln(" %sResult nResult;", component.NameSpace) w.Writeln(" s%sDynamicWrapperTable * pWrapperTable = (s%sDynamicWrapperTable *) malloc (sizeof (s%sDynamicWrapperTable));", component.NameSpace, component.NameSpace, component.NameSpace) @@ -553,12 +552,11 @@ func buildGoWrapper(component ComponentDefinition, w LanguageWriter) error { w.Writeln(" return 0;") w.Writeln(" }") w.Writeln("") - w.Writeln(" return (%s_pvoid) pWrapperTable;", component.NameSpace) + w.Writeln(" return (%sHandle) pWrapperTable;", component.NameSpace) w.Writeln(" }") - w.Writeln(" return 0;") w.Writeln("}") w.Writeln("") - w.Writeln("void unload%sLibrary (%s_pvoid nLibraryHandle)", component.NameSpace, component.NameSpace) + w.Writeln("void unload%sLibrary (%sHandle nLibraryHandle)", component.NameSpace, component.NameSpace) w.Writeln("{") w.Writeln(" s%sDynamicWrapperTable * pWrapperTable = (s%sDynamicWrapperTable *) malloc (sizeof (s%sDynamicWrapperTable));", component.NameSpace, component.NameSpace, component.NameSpace) w.Writeln(" if (pWrapperTable != NULL) {") @@ -591,7 +589,6 @@ func buildGoWrapper(component ComponentDefinition, w LanguageWriter) error { w.Writeln(")") w.Writeln("") w.Writeln("type ref = C.%sHandle", component.NameSpace) - w.Writeln("type refVoid = C.%s_pvoid", component.NameSpace) w.Writeln("") buildGoEnums(component, w) @@ -611,7 +608,7 @@ func buildGoWrapper(component ComponentDefinition, w LanguageWriter) error { w.Writeln("// Wrapper represents the number wrapper") w.Writeln("type Wrapper struct {") w.Writeln(" _ [0]func() // uncomparable; to make == not compile") - w.Writeln(" LibraryHandle refVoid") + w.Writeln(" LibraryHandle ref") w.Writeln("}") for _, class := range component.Classes { @@ -631,7 +628,7 @@ func buildGoWrapper(component ComponentDefinition, w LanguageWriter) error { } w.Writeln("func (wrapper Wrapper) releaseC(r *ref) error {") - w.Writeln(" if r == nil || (*r).Handle == nil {") + w.Writeln(" if r == nil || *r == nil {") w.Writeln(" return nil") w.Writeln(" }") w.Writeln(" return wrapper.%s(%s{Ref: *r})", component.Global.ReleaseMethod, component.Global.BaseClassName) @@ -730,8 +727,8 @@ func getGoType(paramType, namespace, paramClass, paramName string, isPtr bool) ( tp.GoToC = fmt.Sprintf("(%s)(unsafe.Pointer(&[]byte(%s)[0]))", tp.CType, paramName) tp.Empty = "\"\"" case "pointer": - tp.Type = "uintptr" - tp.CType = fmt.Sprintf("C.RTTI_pvoid") + tp.Type = "uint64" + tp.CType = fmt.Sprintf("C.uint64_t") tp.CToGo = fmt.Sprintf("%s(%s)", tp.Type, paramName) tp.GoToC = fmt.Sprintf("(%s)(%s)", tp.CType, paramName) tp.Empty = "0" @@ -906,7 +903,7 @@ func writeGoMethod(method ComponentDefinitionMethod, w LanguageWriter, NameSpace initCallParameters = append(initCallParameters, callParam) if param.ParamType == "optionalclass" { preOKReturn = append(preOKReturn, fmt.Sprintf("var _%sPtr %s", param.ParamName, tp.Type)) - preOKReturn = append(preOKReturn, fmt.Sprintf("if %s.Handle != nil {", param.ParamName)) + preOKReturn = append(preOKReturn, fmt.Sprintf("if %s == nil {", param.ParamName)) if isGlobal { preOKReturn = append(preOKReturn, fmt.Sprintf(" _%sPtrVal := wrapper.New%s(%s)", param.ParamName, param.ParamClass, param.ParamName)) From b766ae3e1f9f5957378cb20f9e21d56c806fcccb Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 13:42:02 -0700 Subject: [PATCH 076/143] cgo on Linux required linking with dl library --- Source/buildbindinggo.go | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/buildbindinggo.go b/Source/buildbindinggo.go index 030fba7e..1cd2d2ea 100644 --- a/Source/buildbindinggo.go +++ b/Source/buildbindinggo.go @@ -533,6 +533,7 @@ func buildGoWrapper(component ComponentDefinition, w LanguageWriter) error { w.Writeln("package %s", packageName) w.Writeln("") w.Writeln("/*") + w.Writeln("#cgo linux LDFLAGS: -ldl") w.Writeln("#include \"%s_dynamic.cc\"", packageName) w.Writeln("") w.Writeln("%sHandle load%sLibrary (const char * pFileName)", component.NameSpace, component.NameSpace) From dca72ea62169ac10a435e39bfde7458f039a8136 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 13:43:15 -0700 Subject: [PATCH 077/143] Fix condition for not null object --- Source/buildbindinggo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/buildbindinggo.go b/Source/buildbindinggo.go index 1cd2d2ea..209e2471 100644 --- a/Source/buildbindinggo.go +++ b/Source/buildbindinggo.go @@ -904,7 +904,7 @@ func writeGoMethod(method ComponentDefinitionMethod, w LanguageWriter, NameSpace initCallParameters = append(initCallParameters, callParam) if param.ParamType == "optionalclass" { preOKReturn = append(preOKReturn, fmt.Sprintf("var _%sPtr %s", param.ParamName, tp.Type)) - preOKReturn = append(preOKReturn, fmt.Sprintf("if %s == nil {", param.ParamName)) + preOKReturn = append(preOKReturn, fmt.Sprintf("if %s != nil {", param.ParamName)) if isGlobal { preOKReturn = append(preOKReturn, fmt.Sprintf(" _%sPtrVal := wrapper.New%s(%s)", param.ParamName, param.ParamClass, param.ParamName)) From 9f791221ef3f6d7f17498252eedb71c6c3159464 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Mon, 25 Oct 2021 22:09:08 -0700 Subject: [PATCH 078/143] Go: fix compilation error due to wrong type convertion --- Source/buildbindinggo.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/buildbindinggo.go b/Source/buildbindinggo.go index 209e2471..a978aa45 100644 --- a/Source/buildbindinggo.go +++ b/Source/buildbindinggo.go @@ -728,8 +728,8 @@ func getGoType(paramType, namespace, paramClass, paramName string, isPtr bool) ( tp.GoToC = fmt.Sprintf("(%s)(unsafe.Pointer(&[]byte(%s)[0]))", tp.CType, paramName) tp.Empty = "\"\"" case "pointer": - tp.Type = "uint64" - tp.CType = fmt.Sprintf("C.uint64_t") + tp.Type = "uintptr" + tp.CType = fmt.Sprintf("C.RTTI_pvoid") tp.CToGo = fmt.Sprintf("%s(%s)", tp.Type, paramName) tp.GoToC = fmt.Sprintf("(%s)(%s)", tp.CType, paramName) tp.Empty = "0" From edd231944600be4661d7970a40b10d6666e87f0c Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 17:55:34 -0700 Subject: [PATCH 079/143] Explicitely return empty object for empty handle --- Source/buildbindingpython.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/buildbindingpython.go b/Source/buildbindingpython.go index 6f168552..ef5e5898 100644 --- a/Source/buildbindingpython.go +++ b/Source/buildbindingpython.go @@ -384,6 +384,8 @@ func buildDynamicPythonImplementation(componentdefinition ComponentDefinition, w w.Writeln(" return %s(handle, wrapper)", componentdefinition.Classes[i].ClassName) } w.Writeln(" ") + w.Writeln(" if not handle:") + w.Writeln(" return None") w.Writeln(" pClassTypeId = ctypes.c_uint64()") w.Writeln(" self.checkError(None, self.lib.%s_%s_%s(handle, pClassTypeId))", strings.ToLower(NameSpace), strings.ToLower(componentdefinition.Global.BaseClassName), strings.ToLower(componentdefinition.Global.ClassTypeIdMethod)) w.Writeln(" factory = PolymorphicFactory()") From ae31bbcab99a793fe8d2aa82d1380a42ccaad893 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 17:56:49 -0700 Subject: [PATCH 080/143] CSharp: revert typed handle --- Source/buildbindingcsharp.go | 51 ++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/Source/buildbindingcsharp.go b/Source/buildbindingcsharp.go index 9f0856a6..3717079d 100644 --- a/Source/buildbindingcsharp.go +++ b/Source/buildbindingcsharp.go @@ -200,11 +200,11 @@ func getCSharpParameterType(ParamTypeName string, NameSpace string, ParamClass s case "class", "optionalclass": if isPlain { - CSharpParamTypeName = fmt.Sprintf("%sHandle", NameSpace) + CSharpParamTypeName = "IntPtr" } else { paramNameSpace, _, _ := decomposeParamClassName(ParamClass) if len(paramNameSpace) > 0 { - CSharpParamTypeName = fmt.Sprintf("%sHandle", NameSpace) + CSharpParamTypeName = "IntPtr" } else { CSharpParamTypeName = "C" + ParamClass } @@ -518,7 +518,7 @@ func writeCSharpClassMethodImplementation(method ComponentDefinitionMethod, w La doInitCall = true case "class", "optionalclass": - defineCommands = append(defineCommands, fmt.Sprintf(" Internal.%sHandle new%s = Internal.%sHandle{ Handle = 0, ClassTypeId = 0};", NameSpace, NameSpace, param.ParamName)) + defineCommands = append(defineCommands, fmt.Sprintf(" IntPtr new%s = IntPtr.Zero;", param.ParamName)) callFunctionParameter = "out new" + param.ParamName initCallParameter = callFunctionParameter resultCommands = append(resultCommands, fmt.Sprintf(" A%s = Internal.RTTIWrapper.PolymorphicFactory<C%s>(new%s);", param.ParamName, param.ParamClass, param.ParamName)) @@ -574,7 +574,7 @@ func writeCSharpClassMethodImplementation(method ComponentDefinitionMethod, w La returnCodeLines = append(returnCodeLines, fmt.Sprintf(" return Internal.%sWrapper.convertInternalToStruct_%s (intresult%s);", NameSpace, param.ParamClass, param.ParamName)) case "class", "optionalclass": - defineCommands = append(defineCommands, fmt.Sprintf(" Internal.%sHandle new%s = new Internal.%sHandle{ Handle = 0, ClassTypeId = 0};", NameSpace, param.ParamName, NameSpace)) + defineCommands = append(defineCommands, fmt.Sprintf(" IntPtr new%s = IntPtr.Zero;", param.ParamName)) callFunctionParameter = "out new" + param.ParamName initCallParameter = callFunctionParameter if (ParamTypeName == "IntPtr") { @@ -719,14 +719,6 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW w.Writeln(" namespace Internal {") w.Writeln("") - - w.Writeln(" [StructLayout(LayoutKind.Explicit, Size=16)]") - w.Writeln(" public unsafe struct %sHandle", NameSpace) - w.Writeln(" {") - w.Writeln(" [FieldOffset(0)] public UInt64 Handle;") - w.Writeln(" [FieldOffset(8)] public UInt64 ClassTypeId;") - w.Writeln(" }") - w.Writeln("") for i := 0; i < len(component.Structs); i++ { structinfo := component.Structs[i] @@ -824,9 +816,9 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW w.Writeln(" [DllImport(\"%s.dll\", EntryPoint = \"%s_%s_%s\", CallingConvention=CallingConvention.Cdecl)]", baseName, strings.ToLower(NameSpace), strings.ToLower(class.ClassName), strings.ToLower(method.MethodName)) if parameters == "" { - parameters = "RTTIHandle Handle" + parameters = "IntPtr Handle" } else { - parameters = "RTTIHandle Handle, " + parameters + parameters = "IntPtr Handle, " + parameters } w.Writeln(" public unsafe extern static Int32 %s_%s (%s);", class.ClassName, method.MethodName, parameters) @@ -940,12 +932,12 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW w.Writeln("") } - w.Writeln(" public static void ThrowError(%sHandle Handle, Int32 errorCode)", NameSpace) + w.Writeln(" public static void ThrowError(IntPtr Handle, Int32 errorCode)") w.Writeln(" {") w.Writeln(" String sMessage = \"%s Error\";", NameSpace) if len(component.Global.ErrorMethod) > 0 { - w.Writeln(" if (Handle.Handle != 0) {") + w.Writeln(" if (Handle != IntPtr.Zero) {") w.Writeln(" UInt32 sizeMessage = 0;") w.Writeln(" UInt32 neededMessage = 0;") w.Writeln(" Byte hasLastError = 0;") @@ -971,15 +963,22 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW w.Writeln("") w.Writeln(" /**") w.Writeln(" * IMPORTANT: PolymorphicFactory method should not be used by application directly.") - w.Writeln(" * It's designed to be used on %sHandle object only once.", NameSpace) + w.Writeln(" * It's designed to be used on Handle object only once.") w.Writeln(" * If it's used on any existing object as a form of dynamic cast then") w.Writeln(" * %sWrapper::AcquireInstance(C%s object) must be called after instantiating new object.", NameSpace, component.Global.BaseClassName) w.Writeln(" * This is important to keep reference count matching between application and library sides.") w.Writeln(" */") - w.Writeln(" public static T PolymorphicFactory<T>(%sHandle Handle) where T : class", NameSpace) + w.Writeln(" public static T PolymorphicFactory<T>(IntPtr Handle) where T : class") w.Writeln(" {") w.Writeln(" T Object;") - w.Writeln(" switch (Handle.ClassTypeId) {") + w.Writeln(" if (Handle == IntPtr.Zero)") + w.Writeln(" return System.Activator.CreateInstance(typeof(T), Handle) as T;") + w.Writeln(" ") + w.Writeln(" UInt64 resultClassTypeId = 0;") + w.Writeln(" Int32 errorCode = %s_%s (Handle, out resultClassTypeId);", component.Global.BaseClassName, component.Global.ClassTypeIdMethod) + w.Writeln(" if (errorCode != 0)") + w.Writeln(" ThrowError (IntPtr.Zero, errorCode);") + w.Writeln(" switch (resultClassTypeId) {") for i := 0; i < len(component.Classes); i++ { class := component.Classes[i] classTypeId, chashHashString := class.classTypeId(NameSpace) @@ -1014,18 +1013,18 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW w.Writeln(" {") if component.isBaseClass(class) { - w.Writeln(" protected Internal.%sHandle Handle;", NameSpace) + w.Writeln(" protected IntPtr Handle;") w.Writeln("") - w.Writeln(" public C%s (Internal.%sHandle NewHandle)", class.ClassName, NameSpace) + w.Writeln(" public C%s (IntPtr NewHandle)", class.ClassName) w.Writeln(" {") w.Writeln(" Handle = NewHandle;") w.Writeln(" }") w.Writeln("") w.Writeln(" ~C%s ()", class.ClassName) w.Writeln(" {") - w.Writeln(" if (Handle.Handle != 0) {") + w.Writeln(" if (Handle != IntPtr.Zero) {") w.Writeln(" Internal.%sWrapper.%s (Handle);", NameSpace, component.Global.ReleaseMethod) - w.Writeln(" Handle.Handle = 0;") + w.Writeln(" Handle = IntPtr.Zero;") w.Writeln(" }") w.Writeln(" }") w.Writeln("") @@ -1038,14 +1037,14 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW w.Writeln(" }") w.Writeln("") - w.Writeln(" public Internal.%sHandle GetHandle ()", NameSpace) + w.Writeln(" public IntPtr GetHandle ()") w.Writeln(" {") w.Writeln(" return Handle;") w.Writeln(" }") w.Writeln("") } else { - w.Writeln(" public C%s (Internal.%sHandle NewHandle) : base (NewHandle)", class.ClassName, NameSpace) + w.Writeln(" public C%s (IntPtr NewHandle) : base (NewHandle)", class.ClassName) w.Writeln(" {") w.Writeln(" }") w.Writeln("") @@ -1078,7 +1077,7 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW w.Writeln(" private static void CheckError (Int32 errorCode)") w.Writeln(" {") w.Writeln(" if (errorCode != 0) {") - w.Writeln(" Internal.%sWrapper.ThrowError (new Internal.%sHandle{ Handle = 0, ClassTypeId = 0 }, errorCode);", NameSpace, NameSpace) + w.Writeln(" Internal.%sWrapper.ThrowError (IntPtr.Zero, errorCode);", NameSpace) w.Writeln(" }") w.Writeln(" }") w.Writeln("") From 597ccfab3eb82ca4c16765ef6e88eea1f702c966 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 17:58:26 -0700 Subject: [PATCH 081/143] Java: revert typed handle --- Source/buildbindingjava.go | 96 +++++++++++++------------------------- 1 file changed, 32 insertions(+), 64 deletions(-) diff --git a/Source/buildbindingjava.go b/Source/buildbindingjava.go index 0321e020..fbc841a2 100644 --- a/Source/buildbindingjava.go +++ b/Source/buildbindingjava.go @@ -70,23 +70,6 @@ func BuildBindingJavaDynamic(component ComponentDefinition, outputFolder string, return err; } - JavaHanldeName := namespace + "Handle"; - JavaHanldePath := path.Join(JavaFolder, JavaHanldeName + ".java"); - log.Printf("Creating \"%s\"", JavaHanldePath) - JavaHanldeFile, err := CreateLanguageFile (JavaHanldePath, indent) - if err != nil { - return err; - } - - JavaHanldeFile.WriteJavaLicenseHeader(component, - fmt.Sprintf("This is an autogenerated Java file in order to allow an easy\n use of %s", libraryname), - true) - - err = buildJavaHandle(component, JavaHanldeFile, indent) - if err != nil { - return err; - } - JavaWrapperName := namespace + "Wrapper"; JavaWrapperPath := path.Join(JavaFolder, JavaWrapperName + ".java"); log.Printf("Creating \"%s\"", JavaWrapperPath) @@ -432,13 +415,13 @@ func buildJavaClass(component ComponentDefinition, w LanguageWriter, indent stri w.Writeln(" protected static final Cleaner mCleaner = Cleaner.create();") w.Writeln("") } - w.Writeln(" protected %sHandle mHandle;", component.NameSpace) + w.Writeln(" protected Pointer mHandle;") w.Writeln("") w.Writeln(" protected %sWrapper mWrapper;", component.NameSpace) w.Writeln("") } - w.Writeln(" public %s(%sWrapper wrapper, %sHandle handle) {", class.ClassName, component.NameSpace, component.NameSpace) + w.Writeln(" public %s(%sWrapper wrapper, Pointer handle) {", class.ClassName, component.NameSpace) if component.isBaseClass(class) { w.Writeln(" mHandle = handle;") w.Writeln(" mWrapper = wrapper;") @@ -452,14 +435,14 @@ func buildJavaClass(component ComponentDefinition, w LanguageWriter, indent stri w.Writeln("") if component.isBaseClass(class) { - w.Writeln(" public %sHandle getHandle() {", component.NameSpace) + w.Writeln(" public Pointer getHandle() {") w.Writeln(" return mHandle;") w.Writeln(" }") w.Writeln(" ") if version >= 9 { w.Writeln(" protected static class InstanceReleaser implements Runnable{") w.Writeln(" ") - w.Writeln(" protected %sHandle mHandle;", component.NameSpace) + w.Writeln(" protected Pointer mHandle;") w.Writeln(" ") w.Writeln(" protected %sWrapper mWrapper;", NameSpace) w.Writeln(" ") @@ -471,7 +454,7 @@ func buildJavaClass(component ComponentDefinition, w LanguageWriter, indent stri w.Writeln(" @Override") w.Writeln(" public void run() {") w.Writeln(" try {") - w.Writeln(" mWrapper.checkError(null, mWrapper.%s_%s.invokeInt(new java.lang.Object[]{mHandle.Value()}));", strings.ToLower(NameSpace), strings.ToLower(component.Global.ReleaseMethod)) + w.Writeln(" mWrapper.checkError(null, mWrapper.%s_%s.invokeInt(new java.lang.Object[]{mHandle}));", strings.ToLower(NameSpace), strings.ToLower(component.Global.ReleaseMethod)) w.Writeln(" } catch (%sException e) {", NameSpace) w.Writeln(" e.printStackTrace();") w.Writeln(" }") @@ -545,7 +528,7 @@ func writeJavaClassMethodImplementation(method ComponentDefinitionMethod, w Lang wrapperInstanceName = "this" } else { callFunctionName = fmt.Sprintf("%s_%s_%s", strings.ToLower(NameSpace), strings.ToLower(ClassName), strings.ToLower(method.MethodName)) - callFunctionParameters = "mHandle.Value()" + callFunctionParameters = "mHandle" errorInstanceHandle = "this" wrapperCallPrefix = "mWrapper." wrapperInstanceName = "mWrapper" @@ -645,9 +628,9 @@ func writeJavaClassMethodImplementation(method ComponentDefinitionMethod, w Lang initCallParameters = initCallParameters + MakeFirstLowerCase(param.ParamName) case "class", "optionalclass": - initCommands = append(initCommands, fmt.Sprintf("%sHandle.ByValue ", NameSpace) + MakeFirstLowerCase(param.ParamName) + "Handle;") + initCommands = append(initCommands, "Pointer " + MakeFirstLowerCase(param.ParamName) + "Handle = null;") initCommands = append(initCommands, fmt.Sprintf("if (%s != null) {", MakeFirstLowerCase(param.ParamName))) - initCommands = append(initCommands, indent + MakeFirstLowerCase(param.ParamName) + "Handle = " + MakeFirstLowerCase(param.ParamName) + ".getHandle().Value();") + initCommands = append(initCommands, indent + MakeFirstLowerCase(param.ParamName) + "Handle = " + MakeFirstLowerCase(param.ParamName) + ".getHandle();") if (param.ParamType == "optionalclass") { } else { @@ -776,18 +759,19 @@ func writeJavaClassMethodImplementation(method ComponentDefinitionMethod, w Lang } else { theNameSpace = NameSpace } - initCommands = append(initCommands, fmt.Sprintf("%sHandle handle%s = new %sHandle();", NameSpace, param.ParamName, NameSpace)) - callFunctionParameters = callFunctionParameters + "handle" + param.ParamName + initCommands = append(initCommands, "Pointer buffer" + param.ParamName + " = new Memory(8);") + callFunctionParameters = callFunctionParameters + "buffer" + param.ParamName + resultCommands = append(resultCommands, fmt.Sprintf("Pointer value%s = buffer%s.getPointer(0);", param.ParamName, param.ParamName)) resultCommands = append(resultCommands, fmt.Sprintf("%s %s = null;", theParamClass, MakeFirstLowerCase(param.ParamName))) if param.ParamType == "class" { - resultCommands = append(resultCommands, fmt.Sprintf("if (handle%s.Handle == Pointer.NULL) {", param.ParamName)) + resultCommands = append(resultCommands, fmt.Sprintf("if (value%s == Pointer.NULL) {", param.ParamName)) resultCommands = append(resultCommands, fmt.Sprintf(" throw new %sException(%sException.%s_ERROR_INVALIDPARAM, \"%s was a null pointer\");", NameSpace, NameSpace, strings.ToUpper(NameSpace), param.ParamName)) resultCommands = append(resultCommands, "}") - resultCommands = append(resultCommands, fmt.Sprintf("%s = %s.PolymorphicFactory(handle%s, %s.class);", MakeFirstLowerCase(param.ParamName), theWrapperInstance, param.ParamName, theParamClass)) + resultCommands = append(resultCommands, fmt.Sprintf("%s = %s.PolymorphicFactory(value%s, %s.class);", MakeFirstLowerCase(param.ParamName), theWrapperInstance, param.ParamName, theParamClass)) } else { - resultCommands = append(resultCommands, fmt.Sprintf("if (handle%s.Handle != Pointer.NULL) {", param.ParamName)) - resultCommands = append(resultCommands, fmt.Sprintf(" %s = %s.PolymorphicFactory(handle%s, %s.class);", MakeFirstLowerCase(param.ParamName), theWrapperInstance, param.ParamName, theParamClass)) + resultCommands = append(resultCommands, fmt.Sprintf("if (value%s != Pointer.NULL) {", param.ParamName)) + resultCommands = append(resultCommands, fmt.Sprintf(" %s = %s.PolymorphicFactory(value%s, %s.class);", MakeFirstLowerCase(param.ParamName), theWrapperInstance, param.ParamName, theParamClass)) resultCommands = append(resultCommands, "}") } ReturnItem.ParamValue = fmt.Sprintf("%s;", MakeFirstLowerCase(param.ParamName)) @@ -981,30 +965,6 @@ func buildJavaStruct(component ComponentDefinition, w LanguageWriter, indent str w.Writeln("") return nil } -func buildJavaHandle(component ComponentDefinition, w LanguageWriter, indent string) error { - NameSpace := component.NameSpace - - w.Writeln("package %s;", strings.ToLower(NameSpace)) - w.Writeln("") - w.Writeln("import com.sun.jna.*;") - w.Writeln("") - - w.Writeln(" @Structure.FieldOrder({\"Handle\", \"ClassTypeId\"})") - w.Writeln(" public class %sHandle extends Structure {", NameSpace) - w.Writeln(" public Pointer Handle;") - w.Writeln(" public long ClassTypeId;") - w.Writeln(" ") - w.Writeln(" public static class ByValue extends %sHandle implements Structure.ByValue {", NameSpace) - w.Writeln(" public ByValue() { super(); read(); }") - w.Writeln(" public ByValue(%sHandle h) { super(h); read(); }", NameSpace) - w.Writeln(" }") - w.Writeln(" public %sHandle() { Handle = Pointer.NULL; ClassTypeId = 0; }", NameSpace) - w.Writeln(" public %sHandle(%sHandle h) { super(h.getPointer()); read(); }", NameSpace, NameSpace) - w.Writeln(" public ByValue Value() { return new ByValue(this); }") - w.Writeln(" }") - w.Writeln("") - return nil -} func buildJavaWrapper(component ComponentDefinition, w LanguageWriter, indent string) error { @@ -1240,15 +1200,23 @@ func buildJavaWrapper(component ComponentDefinition, w LanguageWriter, indent st w.Writeln(" * %sWrapper::acquireInstance(%s object) must be called after instantiating new object.", NameSpace, component.Global.BaseClassName) w.Writeln(" * This is important to keep reference count matching between application and library sides.") w.Writeln(" */") - w.Writeln(" public <T> T PolymorphicFactory(%sHandle handle, Class<T> cls) {", NameSpace) - w.Writeln(" Class[] cArg = new Class[2];") - w.Writeln(" cArg[0] = %sWrapper.class;", NameSpace) - w.Writeln(" cArg[1] = %sHandle.class;", NameSpace) - w.Writeln(" ") - w.Writeln(" try {") - w.Writeln(" T obj = null;") - w.Writeln(" int msbId = (int)(handle.ClassTypeId >> 32); ") - w.Writeln(" int lsbId = (int)handle.ClassTypeId; ") + w.Writeln(" public <T> T PolymorphicFactory(Pointer handle, Class<T> cls) {") + w.Writeln(" if (handle == Pointer.NULL)") + w.Writeln(" return null;") + + w.Writeln(" Class[] cArg = new Class[2];") + w.Writeln(" cArg[0] = %sWrapper.class;", NameSpace) + w.Writeln(" cArg[1] = Pointer.class;") + w.Writeln(" ") + w.Writeln(" try {") + w.Writeln(" T obj = null;") + w.Writeln(" Pointer bufferClassTypeId = new Memory(8);"); + w.Writeln(" checkError(null, %s_%s_%s.invokeInt(new java.lang.Object[]{handle, bufferClassTypeId}));", strings.ToLower(NameSpace), strings.ToLower(component.Global.BaseClassName), strings.ToLower(component.Global.ClassTypeIdMethod)); + w.Writeln(" long classTypeId = bufferClassTypeId.getLong(0);") + + w.Writeln(" ") + w.Writeln(" int msbId = (int)(classTypeId >> 32); ") + w.Writeln(" int lsbId = (int)classTypeId; ") msbIds := make(map[uint32][]ComponentDefinitionClass) for i := 0; i < len(component.Classes); i++ { From f645fef5f47cf7bcefc95db2fa19e5c765677c0a Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 17:58:40 -0700 Subject: [PATCH 082/143] Use curl instead of wget --- Source/buildbindingjava.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/buildbindingjava.go b/Source/buildbindingjava.go index fbc841a2..0d018cc9 100644 --- a/Source/buildbindingjava.go +++ b/Source/buildbindingjava.go @@ -291,7 +291,7 @@ func buildJavaBuildExampleScript(component ComponentDefinition, w LanguageWriter w.Writeln("fi") w.Writeln("") w.Writeln("echo \"Download JNA\"") - w.Writeln("[ -f jna-5.5.0.jar ] || wget https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar") + w.Writeln("[ -f jna-5.5.0.jar ] || curl -O https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar") w.Writeln("") w.Writeln("echo \"Compile Java bindings\"") w.Writeln("javac -encoding UTF8 -classpath \"${JnaJar}\" %s", imports) @@ -315,7 +315,7 @@ func buildJavaBuildScript(component ComponentDefinition, w LanguageWriter) error w.Writeln("") w.Writeln("cd \"$(dirname \"$0\")\"") w.Writeln("echo \"Download JNA\"") - w.Writeln("[ -f jna-5.5.0.jar ] || wget https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar") + w.Writeln("[ -f jna-5.5.0.jar ] || curl -O https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar") w.Writeln("") w.Writeln("echo \"Compile Java Bindings\"") w.Writeln("javac -classpath *.jar " + imports) From 92d2de76efb50f03b5f917e661dce8b2e160a252 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 18:00:44 -0700 Subject: [PATCH 083/143] Implement missed case for statically linked lib --- Source/buildbindingccpp.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index 54f74ff3..4c7f53ce 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -1453,8 +1453,12 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln("template <class T>") w.Writeln("std::shared_ptr<T> %s%sWrapper::polymorphicFactory(%sHandle pHandle)", cppClassPrefix, ClassIdentifier, NameSpace) w.Writeln("{") - w.Writeln(" %s_uint64 resultClassTypeId = 0;", strings.ToUpper(NameSpace)) - w.Writeln(" CheckError(nullptr, m_WrapperTable.m_Base_ClassTypeId(pHandle, &resultClassTypeId));") + w.Writeln(" %s_uint64 resultClassTypeId = 0;", NameSpace) + if ExplicitLinking { + w.Writeln(" CheckError(nullptr, m_WrapperTable.m_%s_%s(pHandle, &resultClassTypeId));", component.Global.BaseClassName, component.Global.ClassTypeIdMethod) + } else { + w.Writeln(" CheckError(nullptr, %s_%s_%s(pHandle, &resultClassTypeId));", strings.ToLower(NameSpace), strings.ToLower(component.Global.BaseClassName), strings.ToLower(component.Global.ClassTypeIdMethod)) + } w.Writeln(" switch(resultClassTypeId) {") for i := 0; i < len(component.Classes); i++ { class := component.Classes[i] From e5daba7e4f7fb1325102d2edfe1c2443d296c321 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 18:01:10 -0700 Subject: [PATCH 084/143] Fix build scripts --- Examples/RTTI/RTTI_component/Examples/Java9/build.sh | 2 +- Examples/RTTI/RTTI_component/Examples/Pascal/build.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Examples/Java9/build.sh b/Examples/RTTI/RTTI_component/Examples/Java9/build.sh index a5486745..5c21c106 100755 --- a/Examples/RTTI/RTTI_component/Examples/Java9/build.sh +++ b/Examples/RTTI/RTTI_component/Examples/Java9/build.sh @@ -22,7 +22,7 @@ else fi echo "Download JNA" -[ -f jna-5.5.0.jar ] || wget https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar +[ -f jna-5.5.0.jar ] || curl -O https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar echo "Compile Java bindings" javac -encoding UTF8 -classpath "${JnaJar}" ../../Bindings/Java9/rtti/*.java diff --git a/Examples/RTTI/RTTI_component/Examples/Pascal/build.sh b/Examples/RTTI/RTTI_component/Examples/Pascal/build.sh index ed3879e9..03d0983a 100755 --- a/Examples/RTTI/RTTI_component/Examples/Pascal/build.sh +++ b/Examples/RTTI/RTTI_component/Examples/Pascal/build.sh @@ -14,12 +14,12 @@ pushd build echo "Test C++ library" rm -f rtti.dll -ln -s ../../Implementations/Cpp/build/rtti$OSLIBEXT rtti.dll +ln -s ../../../Implementations/Cpp/build/rtti$OSLIBEXT rtti.dll RUN ./RTTI_Example . echo "Test Pascal library" rm -f rtti.dll -ln -s ../../Implementations/Pascal/build/rtti$OSLIBEXT rtti.dll +ln -s ../../../Implementations/Pascal/build/rtti$OSLIBEXT rtti.dll RUN ./RTTI_Example . popd From 44ee463196c8df27728cb4c8850232e727840350 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 18:03:07 -0700 Subject: [PATCH 085/143] Fix RTTI Examples --- .../Examples/CDynamic/RTTI_example.c | 22 +++++++++--------- .../Examples/CSharp/RTTI_Example.cs | 23 ++++++++++--------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Examples/CDynamic/RTTI_example.c b/Examples/RTTI/RTTI_component/Examples/CDynamic/RTTI_example.c index ef746f8c..edfb5486 100644 --- a/Examples/RTTI/RTTI_component/Examples/CDynamic/RTTI_example.c +++ b/Examples/RTTI/RTTI_component/Examples/CDynamic/RTTI_example.c @@ -75,77 +75,77 @@ int main() RTTI_Animal Animal; assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); - assert(Animal.Handle != NULL); + assert(Animal != NULL); assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); assert(!strcmp(Name, "Gerald Giraffe")); // assert(RTTI_SUCCESS != sWrapperTable.m_Tiger_Roar(Animal)); assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); - assert(Animal.Handle != NULL); + assert(Animal != NULL); assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); assert(!strcmp(Name, "Timmy Tiger")); assert(RTTI_SUCCESS == sWrapperTable.m_Tiger_Roar(Animal)); assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); - assert(Animal.Handle != NULL); + assert(Animal != NULL); assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); assert(!strcmp(Name, "Tony Tiger")); assert(RTTI_SUCCESS == sWrapperTable.m_Tiger_Roar(Animal)); assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); - assert(Animal.Handle != NULL); + assert(Animal != NULL); assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); assert(!strcmp(Name, "Sebastian Snake")); // assert(RTTI_SUCCESS != sWrapperTable.m_Tiger_Roar(Animal)); assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); - assert(Animal.Handle != NULL); + assert(Animal != NULL); assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); assert(!strcmp(Name, "Tobias Turtle")); // assert(RTTI_SUCCESS != sWrapperTable.m_Tiger_Roar(Animal)); assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); - assert(Animal.Handle != NULL); + assert(Animal != NULL); assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); assert(!strcmp(Name, "Theo Turtle")); // assert(RTTI_SUCCESS != sWrapperTable.m_Tiger_Roar(Animal)); assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); - assert(Animal.Handle != NULL); + assert(Animal != NULL); assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); assert(!strcmp(Name, "Tomás Turtle")); // assert(RTTI_SUCCESS != sWrapperTable.m_Tiger_Roar(Animal)); assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); - assert(Animal.Handle != NULL); + assert(Animal != NULL); assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); assert(!strcmp(Name, "Slytherin Snake")); // assert(RTTI_SUCCESS != sWrapperTable.m_Tiger_Roar(Animal)); assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); - assert(Animal.Handle != NULL); + assert(Animal != NULL); assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); assert(!strcmp(Name, "Travis Tiger")); assert(RTTI_SUCCESS == sWrapperTable.m_Tiger_Roar(Animal)); assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); - assert(Animal.Handle != NULL); + assert(Animal != NULL); assert(RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, 0, &CharsRead, 0) && RTTI_SUCCESS == sWrapperTable.m_Animal_Name(Animal, CharsRead, &CharsRead, &Name[0])); assert(!strcmp(Name, "Gary Giraffe")); // assert(RTTI_SUCCESS != sWrapperTable.m_Tiger_Roar(Animal)); assert(RTTI_SUCCESS == sWrapperTable.m_AnimalIterator_GetNextAnimal(Iterator, &Animal)); - assert(Animal.Handle == NULL); + assert(Animal == NULL); eResult = ReleaseRTTIWrapperTable(&sWrapperTable); if (RTTI_SUCCESS != eResult) { diff --git a/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.cs b/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.cs index 15dbc362..0d941855 100644 --- a/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.cs +++ b/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.cs @@ -35,69 +35,70 @@ static void Main() // Animal name: Gerald Giraffe Animal = Iterator.GetNextAnimal(); - if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.GetHandle() != IntPtr.Zero)) throw new Exception("Wrong data"); if (!(Animal.Name().Equals("Gerald Giraffe"))) throw new Exception("Wrong data"); if (!(Animal is RTTI.CGiraffe)) throw new Exception("Wrong data"); // Animal name: Timmy Tiger Animal = Iterator.GetNextAnimal(); - if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.GetHandle() != IntPtr.Zero)) throw new Exception("Wrong data"); if (!(Animal.Name().Equals("Timmy Tiger"))) throw new Exception("Wrong data"); if (!(Animal is RTTI.CTiger)) throw new Exception("Wrong data"); (Animal as RTTI.CTiger).Roar(); // Animal name: Tony Tiger Animal = Iterator.GetNextAnimal(); - if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.GetHandle() != IntPtr.Zero)) throw new Exception("Wrong data"); if (!(Animal.Name().Equals("Tony Tiger"))) throw new Exception("Wrong data"); if (!(Animal is RTTI.CTiger)) throw new Exception("Wrong data"); (Animal as RTTI.CTiger).Roar(); // Animal name: Sebastian Snake Animal = Iterator.GetNextAnimal(); - if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.GetHandle() != IntPtr.Zero)) throw new Exception("Wrong data"); if (!(Animal.Name().Equals("Sebastian Snake"))) throw new Exception("Wrong data"); if (!(Animal is RTTI.CSnake)) throw new Exception("Wrong data"); // Animal name: Tobias Turtle Animal = Iterator.GetNextAnimal(); - if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.GetHandle() != IntPtr.Zero)) throw new Exception("Wrong data"); if (!(Animal.Name().Equals("Tobias Turtle"))) throw new Exception("Wrong data"); if (!(Animal is RTTI.CTurtle)) throw new Exception("Wrong data"); // Animal name: Theo Turtle Animal = Iterator.GetNextAnimal(); - if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.GetHandle() != IntPtr.Zero)) throw new Exception("Wrong data"); if (!(Animal.Name().Equals("Theo Turtle"))) throw new Exception("Wrong data"); if (!(Animal is RTTI.CTurtle)) throw new Exception("Wrong data"); // Animal name: Tomás Turtle Animal = Iterator.GetNextAnimal(); - if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.GetHandle() != IntPtr.Zero)) throw new Exception("Wrong data"); if (!(Animal.Name().Equals("Tomás Turtle"))) throw new Exception("Wrong data"); if (!(Animal is RTTI.CTurtle)) throw new Exception("Wrong data"); // Animal name: Slytherin Snake Animal = Iterator.GetNextAnimal(); - if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.GetHandle() != IntPtr.Zero)) throw new Exception("Wrong data"); if (!(Animal.Name().Equals("Slytherin Snake"))) throw new Exception("Wrong data"); if (!(Animal is RTTI.CSnake)) throw new Exception("Wrong data"); // Animal name: Travis Tiger Animal = Iterator.GetNextAnimal(); - if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.GetHandle() != IntPtr.Zero)) throw new Exception("Wrong data"); if (!(Animal.Name().Equals("Travis Tiger"))) throw new Exception("Wrong data"); if (!(Animal is RTTI.CTiger)) throw new Exception("Wrong data"); (Animal as RTTI.CTiger).Roar(); + Console.WriteLine("Trace - 4"); // Animal name: Gary Giraffe Animal = Iterator.GetNextAnimal(); - if (!(Animal.GetHandle().Handle != 0)) throw new Exception("Wrong data"); + if (!(Animal.GetHandle() != IntPtr.Zero)) throw new Exception("Wrong data"); if (!(Animal.Name().Equals("Gary Giraffe"))) throw new Exception("Wrong data"); if (!(Animal is RTTI.CGiraffe)) throw new Exception("Wrong data"); Animal = Iterator.GetNextAnimal(); - if (!(Animal.GetHandle().Handle == 0)) throw new Exception("Wrong data"); + if (!(Animal.GetHandle() == IntPtr.Zero)) throw new Exception("Wrong data"); } catch (Exception e) { From 6d49be6fe94480b443c8050e3a8b270f0850c2fe Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 18:03:44 -0700 Subject: [PATCH 086/143] Update RTTI bindings --- .../Bindings/CDynamic/rtti_types.h | 21 +- .../RTTI_component/Bindings/CSharp/RTTI.cs | 112 +- .../Bindings/Cpp/rtti_implicit.hpp | 31 +- .../Bindings/Cpp/rtti_types.hpp | 22 +- .../Bindings/CppDynamic/rtti_dynamic.hpp | 13 +- .../RTTI/RTTI_component/Bindings/Go/rtti.go | 57 +- .../RTTI_component/Bindings/Go/rtti_types.h | 21 +- .../Bindings/Java9/build_jar.sh | 2 +- .../Bindings/Java9/rtti/Animal.java | 6 +- .../Bindings/Java9/rtti/AnimalIterator.java | 11 +- .../Bindings/Java9/rtti/Base.java | 12 +- .../Bindings/Java9/rtti/Giraffe.java | 2 +- .../Bindings/Java9/rtti/Mammal.java | 2 +- .../Bindings/Java9/rtti/RTTIWrapper.java | 93 +- .../Bindings/Java9/rtti/Reptile.java | 2 +- .../Bindings/Java9/rtti/Snake.java | 2 +- .../Bindings/Java9/rtti/Tiger.java | 4 +- .../Bindings/Java9/rtti/Turtle.java | 2 +- .../Bindings/Java9/rtti/Zoo.java | 11 +- .../Bindings/Pascal/Unit_RTTI.pas | 1301 +++++++++-------- .../RTTI_component/Bindings/Python/RTTI.py | 8 + 21 files changed, 848 insertions(+), 887 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_types.h b/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_types.h index 1e3a2608..000a5b65 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_types.h +++ b/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_types.h @@ -56,13 +56,7 @@ typedef double RTTI_double; **************************************************************************************************************************/ typedef RTTI_int32 RTTIResult; -#pragma pack (1) -typedef struct { - void * Handle; - RTTI_uint64 ClassTypeId; -} RTTIHandle; -#pragma pack () -#define RTTIHandleNull { nullptr, 0 } +typedef void * RTTIHandle; typedef void * RTTI_pvoid; /************************************************************************************************************************* @@ -123,18 +117,5 @@ typedef RTTIHandle RTTI_Turtle; typedef RTTIHandle RTTI_AnimalIterator; typedef RTTIHandle RTTI_Zoo; -/************************************************************************************************************************* - Declaration of structs -**************************************************************************************************************************/ - -#pragma pack (1) - -typedef struct { - RTTI_int32 m_X; - RTTI_int32 m_Y; -} sRTTITestStruct; - -#pragma pack () - #endif // __RTTI_TYPES_HEADER diff --git a/Examples/RTTI/RTTI_component/Bindings/CSharp/RTTI.cs b/Examples/RTTI/RTTI_component/Bindings/CSharp/RTTI.cs index ce1110c1..14dd0347 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CSharp/RTTI.cs +++ b/Examples/RTTI/RTTI_component/Bindings/CSharp/RTTI.cs @@ -4,58 +4,38 @@ namespace RTTI { - public struct sTestStruct - { - public Int32 X; - public Int32 Y; - } - namespace Internal { - [StructLayout(LayoutKind.Explicit, Size=16)] - public unsafe struct RTTIHandle - { - [FieldOffset(0)] public UInt64 Handle; - [FieldOffset(8)] public UInt64 ClassTypeId; - } - - [StructLayout(LayoutKind.Explicit, Size=8)] - public unsafe struct InternalTestStruct - { - [FieldOffset(0)] public Int32 X; - [FieldOffset(4)] public Int32 Y; - } - public class RTTIWrapper { [DllImport("rtti.dll", EntryPoint = "rtti_base_classtypeid", CallingConvention=CallingConvention.Cdecl)] - public unsafe extern static Int32 Base_ClassTypeId (RTTIHandle Handle, out UInt64 AClassTypeId); + public unsafe extern static Int32 Base_ClassTypeId (IntPtr Handle, out UInt64 AClassTypeId); [DllImport("rtti.dll", EntryPoint = "rtti_animal_name", CallingConvention=CallingConvention.Cdecl)] - public unsafe extern static Int32 Animal_Name (RTTIHandle Handle, UInt32 sizeResult, out UInt32 neededResult, IntPtr dataResult); + public unsafe extern static Int32 Animal_Name (IntPtr Handle, UInt32 sizeResult, out UInt32 neededResult, IntPtr dataResult); [DllImport("rtti.dll", EntryPoint = "rtti_tiger_roar", CallingConvention=CallingConvention.Cdecl)] - public unsafe extern static Int32 Tiger_Roar (RTTIHandle Handle); + public unsafe extern static Int32 Tiger_Roar (IntPtr Handle); [DllImport("rtti.dll", EntryPoint = "rtti_animaliterator_getnextanimal", CallingConvention=CallingConvention.Cdecl)] - public unsafe extern static Int32 AnimalIterator_GetNextAnimal (RTTIHandle Handle, out RTTIHandle AAnimal); + public unsafe extern static Int32 AnimalIterator_GetNextAnimal (IntPtr Handle, out IntPtr AAnimal); [DllImport("rtti.dll", EntryPoint = "rtti_zoo_iterator", CallingConvention=CallingConvention.Cdecl)] - public unsafe extern static Int32 Zoo_Iterator (RTTIHandle Handle, out RTTIHandle AIterator); + public unsafe extern static Int32 Zoo_Iterator (IntPtr Handle, out IntPtr AIterator); [DllImport("rtti.dll", EntryPoint = "rtti_getversion", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] public extern static Int32 GetVersion (out UInt32 AMajor, out UInt32 AMinor, out UInt32 AMicro); [DllImport("rtti.dll", EntryPoint = "rtti_getlasterror", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] - public extern static Int32 GetLastError (RTTIHandle AInstance, UInt32 sizeErrorMessage, out UInt32 neededErrorMessage, IntPtr dataErrorMessage, out Byte AHasError); + public extern static Int32 GetLastError (IntPtr AInstance, UInt32 sizeErrorMessage, out UInt32 neededErrorMessage, IntPtr dataErrorMessage, out Byte AHasError); [DllImport("rtti.dll", EntryPoint = "rtti_releaseinstance", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] - public extern static Int32 ReleaseInstance (RTTIHandle AInstance); + public extern static Int32 ReleaseInstance (IntPtr AInstance); [DllImport("rtti.dll", EntryPoint = "rtti_acquireinstance", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] - public extern static Int32 AcquireInstance (RTTIHandle AInstance); + public extern static Int32 AcquireInstance (IntPtr AInstance); [DllImport("rtti.dll", EntryPoint = "rtti_injectcomponent", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] public extern static Int32 InjectComponent (byte[] ANameSpace, UInt64 ASymbolAddressMethod); @@ -64,28 +44,12 @@ public class RTTIWrapper public extern static Int32 GetSymbolLookupMethod (out UInt64 ASymbolLookupMethod); [DllImport("rtti.dll", EntryPoint = "rtti_createzoo", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] - public extern static Int32 CreateZoo (out RTTIHandle AInstance); - - public unsafe static sTestStruct convertInternalToStruct_TestStruct (InternalTestStruct intTestStruct) - { - sTestStruct TestStruct; - TestStruct.X = intTestStruct.X; - TestStruct.Y = intTestStruct.Y; - return TestStruct; - } - - public unsafe static InternalTestStruct convertStructToInternal_TestStruct (sTestStruct TestStruct) - { - InternalTestStruct intTestStruct; - intTestStruct.X = TestStruct.X; - intTestStruct.Y = TestStruct.Y; - return intTestStruct; - } + public extern static Int32 CreateZoo (out IntPtr AInstance); - public static void ThrowError(RTTIHandle Handle, Int32 errorCode) + public static void ThrowError(IntPtr Handle, Int32 errorCode) { String sMessage = "RTTI Error"; - if (Handle.Handle != 0) { + if (Handle != IntPtr.Zero) { UInt32 sizeMessage = 0; UInt32 neededMessage = 0; Byte hasLastError = 0; @@ -107,10 +71,24 @@ public static void ThrowError(RTTIHandle Handle, Int32 errorCode) throw new Exception(sMessage + "(# " + errorCode + ")"); } - public static T PolymorphicFactory<T>(RTTIHandle Handle) where T : class + /** + * IMPORTANT: PolymorphicFactory method should not be used by application directly. + * It's designed to be used on Handle object only once. + * If it's used on any existing object as a form of dynamic cast then + * RTTIWrapper::AcquireInstance(CBase object) must be called after instantiating new object. + * This is important to keep reference count matching between application and library sides. + */ + public static T PolymorphicFactory<T>(IntPtr Handle) where T : class { T Object; - switch (Handle.ClassTypeId) { + if (Handle == IntPtr.Zero) + return System.Activator.CreateInstance(typeof(T), Handle) as T; + + UInt64 resultClassTypeId = 0; + Int32 errorCode = Base_ClassTypeId (Handle, out resultClassTypeId); + if (errorCode != 0) + ThrowError (IntPtr.Zero, errorCode); + switch (resultClassTypeId) { case 0x1549AD28813DAE05: Object = new CBase(Handle) as T; break; // First 64 bits of SHA1 of a string: "RTTI::Base" case 0x8B40467DA6D327AF: Object = new CAnimal(Handle) as T; break; // First 64 bits of SHA1 of a string: "RTTI::Animal" case 0xBC9D5FA7750C1020: Object = new CMammal(Handle) as T; break; // First 64 bits of SHA1 of a string: "RTTI::Mammal" @@ -132,18 +110,18 @@ public static T PolymorphicFactory<T>(RTTIHandle Handle) where T : class public class CBase { - protected Internal.RTTIHandle Handle; + protected IntPtr Handle; - public CBase (Internal.RTTIHandle NewHandle) + public CBase (IntPtr NewHandle) { Handle = NewHandle; } ~CBase () { - if (Handle.Handle != 0) { + if (Handle != IntPtr.Zero) { Internal.RTTIWrapper.ReleaseInstance (Handle); - Handle.Handle = 0; + Handle = IntPtr.Zero; } } @@ -154,7 +132,7 @@ protected void CheckError (Int32 errorCode) } } - public Internal.RTTIHandle GetHandle () + public IntPtr GetHandle () { return Handle; } @@ -171,7 +149,7 @@ public UInt64 ClassTypeId () public class CAnimal : CBase { - public CAnimal (Internal.RTTIHandle NewHandle) : base (NewHandle) + public CAnimal (IntPtr NewHandle) : base (NewHandle) { } @@ -193,7 +171,7 @@ public String Name () public class CMammal : CAnimal { - public CMammal (Internal.RTTIHandle NewHandle) : base (NewHandle) + public CMammal (IntPtr NewHandle) : base (NewHandle) { } @@ -201,7 +179,7 @@ public CMammal (Internal.RTTIHandle NewHandle) : base (NewHandle) public class CReptile : CAnimal { - public CReptile (Internal.RTTIHandle NewHandle) : base (NewHandle) + public CReptile (IntPtr NewHandle) : base (NewHandle) { } @@ -209,7 +187,7 @@ public CReptile (Internal.RTTIHandle NewHandle) : base (NewHandle) public class CGiraffe : CMammal { - public CGiraffe (Internal.RTTIHandle NewHandle) : base (NewHandle) + public CGiraffe (IntPtr NewHandle) : base (NewHandle) { } @@ -217,7 +195,7 @@ public CGiraffe (Internal.RTTIHandle NewHandle) : base (NewHandle) public class CTiger : CMammal { - public CTiger (Internal.RTTIHandle NewHandle) : base (NewHandle) + public CTiger (IntPtr NewHandle) : base (NewHandle) { } @@ -231,7 +209,7 @@ public void Roar () public class CSnake : CReptile { - public CSnake (Internal.RTTIHandle NewHandle) : base (NewHandle) + public CSnake (IntPtr NewHandle) : base (NewHandle) { } @@ -239,7 +217,7 @@ public CSnake (Internal.RTTIHandle NewHandle) : base (NewHandle) public class CTurtle : CReptile { - public CTurtle (Internal.RTTIHandle NewHandle) : base (NewHandle) + public CTurtle (IntPtr NewHandle) : base (NewHandle) { } @@ -247,13 +225,13 @@ public CTurtle (Internal.RTTIHandle NewHandle) : base (NewHandle) public class CAnimalIterator : CBase { - public CAnimalIterator (Internal.RTTIHandle NewHandle) : base (NewHandle) + public CAnimalIterator (IntPtr NewHandle) : base (NewHandle) { } public CAnimal GetNextAnimal () { - Internal.RTTIHandle newAnimal = new Internal.RTTIHandle{ Handle = 0, ClassTypeId = 0}; + IntPtr newAnimal = IntPtr.Zero; CheckError(Internal.RTTIWrapper.AnimalIterator_GetNextAnimal (Handle, out newAnimal)); return Internal.RTTIWrapper.PolymorphicFactory<CAnimal>(newAnimal); @@ -263,13 +241,13 @@ public CAnimal GetNextAnimal () public class CZoo : CBase { - public CZoo (Internal.RTTIHandle NewHandle) : base (NewHandle) + public CZoo (IntPtr NewHandle) : base (NewHandle) { } public CAnimalIterator Iterator () { - Internal.RTTIHandle newIterator = new Internal.RTTIHandle{ Handle = 0, ClassTypeId = 0}; + IntPtr newIterator = IntPtr.Zero; CheckError(Internal.RTTIWrapper.Zoo_Iterator (Handle, out newIterator)); return Internal.RTTIWrapper.PolymorphicFactory<CAnimalIterator>(newIterator); @@ -282,7 +260,7 @@ class Wrapper private static void CheckError (Int32 errorCode) { if (errorCode != 0) { - Internal.RTTIWrapper.ThrowError (new Internal.RTTIHandle{ Handle = 0, ClassTypeId = 0 }, errorCode); + Internal.RTTIWrapper.ThrowError (IntPtr.Zero, errorCode); } } @@ -335,7 +313,7 @@ public static UInt64 GetSymbolLookupMethod () public static CZoo CreateZoo () { - Internal.RTTIHandle newInstance = new Internal.RTTIHandle{ Handle = 0, ClassTypeId = 0}; + IntPtr newInstance = IntPtr.Zero; CheckError(Internal.RTTIWrapper.CreateZoo (out newInstance)); return Internal.RTTIWrapper.PolymorphicFactory<CZoo>(newInstance); diff --git a/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_implicit.hpp b/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_implicit.hpp index e9dea63a..ccfb299b 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_implicit.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_implicit.hpp @@ -117,7 +117,7 @@ template<class T> class classParam { { if (m_ptr != nullptr) return m_ptr->handle(); - return RTTIHandleNull; + return nullptr; } }; @@ -277,6 +277,9 @@ class CWrapper { inline RTTI_pvoid GetSymbolLookupMethod(); inline PZoo CreateZoo(); + template<class U> + std::shared_ptr<U> polymorphicFactory(RTTIHandle); + private: RTTIResult checkBinaryVersion() @@ -289,9 +292,6 @@ class CWrapper { return RTTI_SUCCESS; } - template<class U> - std::shared_ptr<U> polymorphicFactory(RTTIHandle); - friend class CBase; friend class CAnimal; friend class CMammal; @@ -515,10 +515,19 @@ class CZoo : public CBase { RTTI: Polymorphic Factory implementation **************************************************************************************************************************/ +/** +* IMPORTANT: PolymorphicFactory method should not be used by application directly. +* It's designed to be used on RTTIHandle object only once. +* If it's used on any existing object as a form of dynamic cast then +* CWrapper::AcquireInstance(CBase object) must be called after instantiating new object. +* This is important to keep reference count matching between application and library sides. +*/ template <class T> std::shared_ptr<T> CWrapper::polymorphicFactory(RTTIHandle pHandle) { - switch(pHandle.ClassTypeId) { + RTTI_uint64 resultClassTypeId = 0; + CheckError(nullptr, rtti_base_classtypeid(pHandle, &resultClassTypeId)); + switch(resultClassTypeId) { case 0x1549AD28813DAE05UL: return std::dynamic_pointer_cast<T>(std::make_shared<CBase>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Base" case 0x8B40467DA6D327AFUL: return std::dynamic_pointer_cast<T>(std::make_shared<CAnimal>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Animal" case 0xBC9D5FA7750C1020UL: return std::dynamic_pointer_cast<T>(std::make_shared<CMammal>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Mammal" @@ -616,10 +625,10 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(RTTIHandle pHandle) */ inline PZoo CWrapper::CreateZoo() { - RTTIHandle hInstance = RTTIHandleNull; + RTTIHandle hInstance = nullptr; CheckError(nullptr,rtti_createzoo(&hInstance)); - if (!hInstance.Handle) { + if (!hInstance) { CheckError(nullptr,RTTI_ERROR_INVALIDPARAM); } return this->polymorphicFactory<CZoo>(hInstance); @@ -715,10 +724,10 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(RTTIHandle pHandle) */ PAnimal CAnimalIterator::GetNextAnimal() { - RTTIHandle hAnimal = RTTIHandleNull; + RTTIHandle hAnimal = nullptr; CheckError(rtti_animaliterator_getnextanimal(m_pHandle, &hAnimal)); - if (hAnimal.Handle) { + if (hAnimal) { return m_pWrapper->polymorphicFactory<CAnimal>(hAnimal); } else { return nullptr; @@ -735,10 +744,10 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(RTTIHandle pHandle) */ PAnimalIterator CZoo::Iterator() { - RTTIHandle hIterator = RTTIHandleNull; + RTTIHandle hIterator = nullptr; CheckError(rtti_zoo_iterator(m_pHandle, &hIterator)); - if (!hIterator.Handle) { + if (!hIterator) { CheckError(RTTI_ERROR_INVALIDPARAM); } return m_pWrapper->polymorphicFactory<CAnimalIterator>(hIterator); diff --git a/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_types.hpp b/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_types.hpp index 7cbf7886..cc0455f9 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_types.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_types.hpp @@ -55,13 +55,7 @@ typedef double RTTI_double; **************************************************************************************************************************/ typedef RTTI_int32 RTTIResult; -#pragma pack (1) -typedef struct { - void * Handle; - RTTI_uint64 ClassTypeId; -} RTTIHandle; -#pragma pack () -#define RTTIHandleNull { nullptr, 0 } +typedef void * RTTIHandle; typedef void * RTTI_pvoid; /************************************************************************************************************************* @@ -124,22 +118,8 @@ typedef RTTIHandle RTTI_Zoo; namespace RTTI { - /************************************************************************************************************************* - Declaration of structs - **************************************************************************************************************************/ - - #pragma pack (1) - - typedef struct { - RTTI_int32 m_X; - RTTI_int32 m_Y; - } sTestStruct; - - #pragma pack () - } // namespace RTTI; // define legacy C-names for enums, structs and function types -typedef RTTI::sTestStruct sRTTITestStruct; #endif // __RTTI_TYPES_HEADER_CPP diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp index 0ca76c39..494b3a34 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp @@ -296,6 +296,9 @@ class CWrapper { inline RTTI_pvoid GetSymbolLookupMethod(); inline PZoo CreateZoo(); + template<class U> + std::shared_ptr<U> polymorphicFactory(RTTIHandle); + private: sRTTIDynamicWrapperTable m_WrapperTable; @@ -313,9 +316,6 @@ class CWrapper { RTTIResult loadWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable, const char * pLibraryFileName); RTTIResult loadWrapperTableFromSymbolLookupMethod(sRTTIDynamicWrapperTable * pWrapperTable, void* pSymbolLookupMethod); - template<class U> - std::shared_ptr<U> polymorphicFactory(RTTIHandle); - friend class CBase; friend class CAnimal; friend class CMammal; @@ -539,6 +539,13 @@ class CZoo : public CBase { RTTI: Polymorphic Factory implementation **************************************************************************************************************************/ +/** +* IMPORTANT: PolymorphicFactory method should not be used by application directly. +* It's designed to be used on RTTIHandle object only once. +* If it's used on any existing object as a form of dynamic cast then +* CWrapper::AcquireInstance(CBase object) must be called after instantiating new object. +* This is important to keep reference count matching between application and library sides. +*/ template <class T> std::shared_ptr<T> CWrapper::polymorphicFactory(RTTIHandle pHandle) { diff --git a/Examples/RTTI/RTTI_component/Bindings/Go/rtti.go b/Examples/RTTI/RTTI_component/Bindings/Go/rtti.go index 2bd4a5a3..fa11f32b 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Go/rtti.go +++ b/Examples/RTTI/RTTI_component/Bindings/Go/rtti.go @@ -18,9 +18,10 @@ Interface version: 1.0.0 package rtti /* +#cgo linux LDFLAGS: -ldl #include "rtti_dynamic.cc" -RTTI_pvoid loadRTTILibrary (const char * pFileName) +RTTIHandle loadRTTILibrary (const char * pFileName) { RTTIResult nResult; sRTTIDynamicWrapperTable * pWrapperTable = (sRTTIDynamicWrapperTable *) malloc (sizeof (sRTTIDynamicWrapperTable)); @@ -37,12 +38,11 @@ RTTI_pvoid loadRTTILibrary (const char * pFileName) return 0; } - return (RTTI_pvoid) pWrapperTable; + return (RTTIHandle) pWrapperTable; } - return 0; } -void unloadRTTILibrary (RTTI_pvoid nLibraryHandle) +void unloadRTTILibrary (RTTIHandle nLibraryHandle) { sRTTIDynamicWrapperTable * pWrapperTable = (sRTTIDynamicWrapperTable *) malloc (sizeof (sRTTIDynamicWrapperTable)); if (pWrapperTable != NULL) { @@ -52,7 +52,7 @@ void unloadRTTILibrary (RTTI_pvoid nLibraryHandle) } -RTTIResult CCall_rtti_base_classtypeid(RTTI_pvoid libraryHandle, RTTI_Base pBase, RTTI_uint64 * pClassTypeId) +RTTIResult CCall_rtti_base_classtypeid(RTTIHandle libraryHandle, RTTI_Base pBase, RTTI_uint64 * pClassTypeId) { if (libraryHandle == 0) return RTTI_ERROR_INVALIDCAST; @@ -61,7 +61,7 @@ RTTIResult CCall_rtti_base_classtypeid(RTTI_pvoid libraryHandle, RTTI_Base pBase } -RTTIResult CCall_rtti_animal_name(RTTI_pvoid libraryHandle, RTTI_Animal pAnimal, const RTTI_uint32 nResultBufferSize, RTTI_uint32* pResultNeededChars, char * pResultBuffer) +RTTIResult CCall_rtti_animal_name(RTTIHandle libraryHandle, RTTI_Animal pAnimal, const RTTI_uint32 nResultBufferSize, RTTI_uint32* pResultNeededChars, char * pResultBuffer) { if (libraryHandle == 0) return RTTI_ERROR_INVALIDCAST; @@ -70,7 +70,7 @@ RTTIResult CCall_rtti_animal_name(RTTI_pvoid libraryHandle, RTTI_Animal pAnimal, } -RTTIResult CCall_rtti_tiger_roar(RTTI_pvoid libraryHandle, RTTI_Tiger pTiger) +RTTIResult CCall_rtti_tiger_roar(RTTIHandle libraryHandle, RTTI_Tiger pTiger) { if (libraryHandle == 0) return RTTI_ERROR_INVALIDCAST; @@ -79,7 +79,7 @@ RTTIResult CCall_rtti_tiger_roar(RTTI_pvoid libraryHandle, RTTI_Tiger pTiger) } -RTTIResult CCall_rtti_animaliterator_getnextanimal(RTTI_pvoid libraryHandle, RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal) +RTTIResult CCall_rtti_animaliterator_getnextanimal(RTTIHandle libraryHandle, RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal) { if (libraryHandle == 0) return RTTI_ERROR_INVALIDCAST; @@ -88,7 +88,7 @@ RTTIResult CCall_rtti_animaliterator_getnextanimal(RTTI_pvoid libraryHandle, RTT } -RTTIResult CCall_rtti_zoo_iterator(RTTI_pvoid libraryHandle, RTTI_Zoo pZoo, RTTI_AnimalIterator * pIterator) +RTTIResult CCall_rtti_zoo_iterator(RTTIHandle libraryHandle, RTTI_Zoo pZoo, RTTI_AnimalIterator * pIterator) { if (libraryHandle == 0) return RTTI_ERROR_INVALIDCAST; @@ -97,7 +97,7 @@ RTTIResult CCall_rtti_zoo_iterator(RTTI_pvoid libraryHandle, RTTI_Zoo pZoo, RTTI } -RTTIResult CCall_rtti_getversion(RTTI_pvoid libraryHandle, RTTI_uint32 * pMajor, RTTI_uint32 * pMinor, RTTI_uint32 * pMicro) +RTTIResult CCall_rtti_getversion(RTTIHandle libraryHandle, RTTI_uint32 * pMajor, RTTI_uint32 * pMinor, RTTI_uint32 * pMicro) { if (libraryHandle == 0) return RTTI_ERROR_INVALIDCAST; @@ -106,7 +106,7 @@ RTTIResult CCall_rtti_getversion(RTTI_pvoid libraryHandle, RTTI_uint32 * pMajor, } -RTTIResult CCall_rtti_getlasterror(RTTI_pvoid libraryHandle, RTTI_Base pInstance, const RTTI_uint32 nErrorMessageBufferSize, RTTI_uint32* pErrorMessageNeededChars, char * pErrorMessageBuffer, bool * pHasError) +RTTIResult CCall_rtti_getlasterror(RTTIHandle libraryHandle, RTTI_Base pInstance, const RTTI_uint32 nErrorMessageBufferSize, RTTI_uint32* pErrorMessageNeededChars, char * pErrorMessageBuffer, bool * pHasError) { if (libraryHandle == 0) return RTTI_ERROR_INVALIDCAST; @@ -115,7 +115,7 @@ RTTIResult CCall_rtti_getlasterror(RTTI_pvoid libraryHandle, RTTI_Base pInstance } -RTTIResult CCall_rtti_releaseinstance(RTTI_pvoid libraryHandle, RTTI_Base pInstance) +RTTIResult CCall_rtti_releaseinstance(RTTIHandle libraryHandle, RTTI_Base pInstance) { if (libraryHandle == 0) return RTTI_ERROR_INVALIDCAST; @@ -124,7 +124,7 @@ RTTIResult CCall_rtti_releaseinstance(RTTI_pvoid libraryHandle, RTTI_Base pInsta } -RTTIResult CCall_rtti_acquireinstance(RTTI_pvoid libraryHandle, RTTI_Base pInstance) +RTTIResult CCall_rtti_acquireinstance(RTTIHandle libraryHandle, RTTI_Base pInstance) { if (libraryHandle == 0) return RTTI_ERROR_INVALIDCAST; @@ -133,7 +133,7 @@ RTTIResult CCall_rtti_acquireinstance(RTTI_pvoid libraryHandle, RTTI_Base pInsta } -RTTIResult CCall_rtti_injectcomponent(RTTI_pvoid libraryHandle, const char * pNameSpace, RTTI_pvoid pSymbolAddressMethod) +RTTIResult CCall_rtti_injectcomponent(RTTIHandle libraryHandle, const char * pNameSpace, RTTI_pvoid pSymbolAddressMethod) { if (libraryHandle == 0) return RTTI_ERROR_INVALIDCAST; @@ -142,7 +142,7 @@ RTTIResult CCall_rtti_injectcomponent(RTTI_pvoid libraryHandle, const char * pNa } -RTTIResult CCall_rtti_getsymbollookupmethod(RTTI_pvoid libraryHandle, RTTI_pvoid * pSymbolLookupMethod) +RTTIResult CCall_rtti_getsymbollookupmethod(RTTIHandle libraryHandle, RTTI_pvoid * pSymbolLookupMethod) { if (libraryHandle == 0) return RTTI_ERROR_INVALIDCAST; @@ -151,7 +151,7 @@ RTTIResult CCall_rtti_getsymbollookupmethod(RTTI_pvoid libraryHandle, RTTI_pvoid } -RTTIResult CCall_rtti_createzoo(RTTI_pvoid libraryHandle, RTTI_Zoo * pInstance) +RTTIResult CCall_rtti_createzoo(RTTIHandle libraryHandle, RTTI_Zoo * pInstance) { if (libraryHandle == 0) return RTTI_ERROR_INVALIDCAST; @@ -169,13 +169,6 @@ import ( ) type ref = C.RTTIHandle -type refVoid = C.RTTI_pvoid - -// TestStruct represents a RTTI struct. -type TestStruct struct { - X int32 - Y int32 -} // Error constants for RTTI. const RTTI_ERROR_NOTIMPLEMENTED = 1; @@ -227,7 +220,7 @@ func makeError(errorcode uint32) error { // Wrapper represents the number wrapper type Wrapper struct { _ [0]func() // uncomparable; to make == not compile - LibraryHandle refVoid + LibraryHandle ref } // Base represents a RTTI class. @@ -251,7 +244,7 @@ func (wrapper Wrapper) NewBase(r ref) Base { // Release releases the C pointer. func (inst Base) Release() error { err := inst.wrapperRef.ReleaseInstance(inst) - (*inst.gcPtr).Handle = nil + *inst.gcPtr = nil return err } @@ -383,7 +376,7 @@ func (inst AnimalIterator) GetNextAnimal() (*Animal, error) { return nil, makeError(uint32(ret)) } var _animalPtr *Animal - if animal.Handle != nil { + if animal != nil { _animalPtrVal := inst.wrapperRef.NewAnimal(animal) _animalPtr = &_animalPtrVal } @@ -460,8 +453,8 @@ func (wrapper Wrapper) AcquireInstance(instance Base) error { } // InjectComponent injects an imported component for usage within this component. -func (wrapper Wrapper) InjectComponent(nameSpace string, symbolAddressMethod uint64) error { - ret := C.CCall_rtti_injectcomponent(wrapper.LibraryHandle, (*C.char)(unsafe.Pointer(&[]byte(nameSpace)[0])), (C.uint64_t)(symbolAddressMethod)) +func (wrapper Wrapper) InjectComponent(nameSpace string, symbolAddressMethod uintptr) error { + ret := C.CCall_rtti_injectcomponent(wrapper.LibraryHandle, (*C.char)(unsafe.Pointer(&[]byte(nameSpace)[0])), (C.RTTI_pvoid)(symbolAddressMethod)) if ret != 0 { return makeError(uint32(ret)) } @@ -469,13 +462,13 @@ func (wrapper Wrapper) InjectComponent(nameSpace string, symbolAddressMethod uin } // GetSymbolLookupMethod returns the address of the SymbolLookupMethod. -func (wrapper Wrapper) GetSymbolLookupMethod() (uint64, error) { - var symbolLookupMethod C.uint64_t +func (wrapper Wrapper) GetSymbolLookupMethod() (uintptr, error) { + var symbolLookupMethod C.RTTI_pvoid ret := C.CCall_rtti_getsymbollookupmethod(wrapper.LibraryHandle, &symbolLookupMethod) if ret != 0 { return 0, makeError(uint32(ret)) } - return uint64(symbolLookupMethod), nil + return uintptr(symbolLookupMethod), nil } // CreateZoo create a new zoo with animals. @@ -489,7 +482,7 @@ func (wrapper Wrapper) CreateZoo() (Zoo, error) { } func (wrapper Wrapper) releaseC(r *ref) error { - if r == nil || (*r).Handle == nil { + if r == nil || *r == nil { return nil } return wrapper.ReleaseInstance(Base{Ref: *r}) diff --git a/Examples/RTTI/RTTI_component/Bindings/Go/rtti_types.h b/Examples/RTTI/RTTI_component/Bindings/Go/rtti_types.h index 1e3a2608..000a5b65 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Go/rtti_types.h +++ b/Examples/RTTI/RTTI_component/Bindings/Go/rtti_types.h @@ -56,13 +56,7 @@ typedef double RTTI_double; **************************************************************************************************************************/ typedef RTTI_int32 RTTIResult; -#pragma pack (1) -typedef struct { - void * Handle; - RTTI_uint64 ClassTypeId; -} RTTIHandle; -#pragma pack () -#define RTTIHandleNull { nullptr, 0 } +typedef void * RTTIHandle; typedef void * RTTI_pvoid; /************************************************************************************************************************* @@ -123,18 +117,5 @@ typedef RTTIHandle RTTI_Turtle; typedef RTTIHandle RTTI_AnimalIterator; typedef RTTIHandle RTTI_Zoo; -/************************************************************************************************************************* - Declaration of structs -**************************************************************************************************************************/ - -#pragma pack (1) - -typedef struct { - RTTI_int32 m_X; - RTTI_int32 m_Y; -} sRTTITestStruct; - -#pragma pack () - #endif // __RTTI_TYPES_HEADER diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/build_jar.sh b/Examples/RTTI/RTTI_component/Bindings/Java9/build_jar.sh index 1ccec293..bab117af 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Java9/build_jar.sh +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/build_jar.sh @@ -3,7 +3,7 @@ set -euxo pipefail cd "$(dirname "$0")" echo "Download JNA" -[ -f jna-5.5.0.jar ] || wget https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar +[ -f jna-5.5.0.jar ] || curl -O https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar echo "Compile Java Bindings" javac -classpath *.jar rtti/* diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Animal.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Animal.java index 641c5851..24855e07 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Animal.java +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Animal.java @@ -28,7 +28,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. public class Animal extends Base { - public Animal(RTTIWrapper wrapper, RTTIHandle handle) { + public Animal(RTTIWrapper wrapper, Pointer handle) { super(wrapper, handle); } @@ -40,10 +40,10 @@ public Animal(RTTIWrapper wrapper, RTTIHandle handle) { */ public String name() throws RTTIException { Pointer bytesNeededResult = new Memory(4); - mWrapper.checkError(this, mWrapper.rtti_animal_name.invokeInt(new java.lang.Object[]{mHandle.Value(), 0, bytesNeededResult, null})); + mWrapper.checkError(this, mWrapper.rtti_animal_name.invokeInt(new java.lang.Object[]{mHandle, 0, bytesNeededResult, null})); int sizeResult = bytesNeededResult.getInt(0); Pointer bufferResult = new Memory(sizeResult); - mWrapper.checkError(this, mWrapper.rtti_animal_name.invokeInt(new java.lang.Object[]{mHandle.Value(), sizeResult, bytesNeededResult, bufferResult})); + mWrapper.checkError(this, mWrapper.rtti_animal_name.invokeInt(new java.lang.Object[]{mHandle, sizeResult, bytesNeededResult, bufferResult})); return new String(bufferResult.getByteArray(0, sizeResult - 1), StandardCharsets.UTF_8); } diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/AnimalIterator.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/AnimalIterator.java index 83fa7e93..fd84ed29 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/AnimalIterator.java +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/AnimalIterator.java @@ -28,7 +28,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. public class AnimalIterator extends Base { - public AnimalIterator(RTTIWrapper wrapper, RTTIHandle handle) { + public AnimalIterator(RTTIWrapper wrapper, Pointer handle) { super(wrapper, handle); } @@ -39,11 +39,12 @@ public AnimalIterator(RTTIWrapper wrapper, RTTIHandle handle) { * @throws RTTIException */ public Animal getNextAnimal() throws RTTIException { - RTTIHandle handleAnimal = new RTTIHandle(); - mWrapper.checkError(this, mWrapper.rtti_animaliterator_getnextanimal.invokeInt(new java.lang.Object[]{mHandle.Value(), handleAnimal})); + Pointer bufferAnimal = new Memory(8); + mWrapper.checkError(this, mWrapper.rtti_animaliterator_getnextanimal.invokeInt(new java.lang.Object[]{mHandle, bufferAnimal})); + Pointer valueAnimal = bufferAnimal.getPointer(0); Animal animal = null; - if (handleAnimal.Handle != Pointer.NULL) { - animal = mWrapper.PolymorphicFactory(handleAnimal, Animal.class); + if (valueAnimal != Pointer.NULL) { + animal = mWrapper.PolymorphicFactory(valueAnimal, Animal.class); } return animal; } diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Base.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Base.java index 682911f1..e907d446 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Base.java +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Base.java @@ -30,23 +30,23 @@ public class Base { protected static final Cleaner mCleaner = Cleaner.create(); - protected RTTIHandle mHandle; + protected Pointer mHandle; protected RTTIWrapper mWrapper; - public Base(RTTIWrapper wrapper, RTTIHandle handle) { + public Base(RTTIWrapper wrapper, Pointer handle) { mHandle = handle; mWrapper = wrapper; mCleaner.register(this, new InstanceReleaser(this)); } - public RTTIHandle getHandle() { + public Pointer getHandle() { return mHandle; } protected static class InstanceReleaser implements Runnable{ - protected RTTIHandle mHandle; + protected Pointer mHandle; protected RTTIWrapper mWrapper; @@ -58,7 +58,7 @@ protected InstanceReleaser(Base instance) { @Override public void run() { try { - mWrapper.checkError(null, mWrapper.rtti_releaseinstance.invokeInt(new java.lang.Object[]{mHandle.Value()})); + mWrapper.checkError(null, mWrapper.rtti_releaseinstance.invokeInt(new java.lang.Object[]{mHandle})); } catch (RTTIException e) { e.printStackTrace(); } @@ -72,7 +72,7 @@ public void run() { */ public long classTypeId() throws RTTIException { Pointer bufferClassTypeId = new Memory(8); - mWrapper.checkError(this, mWrapper.rtti_base_classtypeid.invokeInt(new java.lang.Object[]{mHandle.Value(), bufferClassTypeId})); + mWrapper.checkError(this, mWrapper.rtti_base_classtypeid.invokeInt(new java.lang.Object[]{mHandle, bufferClassTypeId})); return bufferClassTypeId.getLong(0); } diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Giraffe.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Giraffe.java index 3ecd7153..8a67d287 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Giraffe.java +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Giraffe.java @@ -28,7 +28,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. public class Giraffe extends Mammal { - public Giraffe(RTTIWrapper wrapper, RTTIHandle handle) { + public Giraffe(RTTIWrapper wrapper, Pointer handle) { super(wrapper, handle); } diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Mammal.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Mammal.java index 004c0616..5b1356b8 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Mammal.java +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Mammal.java @@ -28,7 +28,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. public class Mammal extends Animal { - public Mammal(RTTIWrapper wrapper, RTTIHandle handle) { + public Mammal(RTTIWrapper wrapper, Pointer handle) { super(wrapper, handle); } diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIWrapper.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIWrapper.java index c9a77120..89ef6916 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIWrapper.java +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIWrapper.java @@ -140,9 +140,9 @@ public static class GetVersionResult { * @throws RTTIException */ public GetLastErrorResult getLastError(Base instance) throws RTTIException { - RTTIHandle.ByValue instanceHandle; + Pointer instanceHandle = null; if (instance != null) { - instanceHandle = instance.getHandle().Value(); + instanceHandle = instance.getHandle(); } else { throw new RTTIException(RTTIException.RTTI_ERROR_INVALIDPARAM, "Instance is a null value."); } @@ -177,9 +177,9 @@ public static class GetLastErrorResult { * @throws RTTIException */ public void releaseInstance(Base instance) throws RTTIException { - RTTIHandle.ByValue instanceHandle; + Pointer instanceHandle = null; if (instance != null) { - instanceHandle = instance.getHandle().Value(); + instanceHandle = instance.getHandle(); } else { throw new RTTIException(RTTIException.RTTI_ERROR_INVALIDPARAM, "Instance is a null value."); } @@ -193,9 +193,9 @@ public void releaseInstance(Base instance) throws RTTIException { * @throws RTTIException */ public void acquireInstance(Base instance) throws RTTIException { - RTTIHandle.ByValue instanceHandle; + Pointer instanceHandle = null; if (instance != null) { - instanceHandle = instance.getHandle().Value(); + instanceHandle = instance.getHandle(); } else { throw new RTTIException(RTTIException.RTTI_ERROR_INVALIDPARAM, "Instance is a null value."); } @@ -241,76 +241,91 @@ public Pointer getSymbolLookupMethod() throws RTTIException { * @throws RTTIException */ public Zoo createZoo() throws RTTIException { - RTTIHandle handleInstance = new RTTIHandle(); - checkError(null, rtti_createzoo.invokeInt(new java.lang.Object[]{handleInstance})); + Pointer bufferInstance = new Memory(8); + checkError(null, rtti_createzoo.invokeInt(new java.lang.Object[]{bufferInstance})); + Pointer valueInstance = bufferInstance.getPointer(0); Zoo instance = null; - if (handleInstance.Handle == Pointer.NULL) { + if (valueInstance == Pointer.NULL) { throw new RTTIException(RTTIException.RTTI_ERROR_INVALIDPARAM, "Instance was a null pointer"); } - instance = this.PolymorphicFactory(handleInstance, Zoo.class); + instance = this.PolymorphicFactory(valueInstance, Zoo.class); return instance; } - public <T> T PolymorphicFactory(RTTIHandle handle, Class<T> cls) { - Class[] cArg = new Class[2]; - cArg[0] = RTTIWrapper.class; - cArg[1] = RTTIHandle.class; - - try { - int msbId = (int)(handle.ClassTypeId >> 32); - int lsbId = (int)handle.ClassTypeId; - T obj = null; + /** + * IMPORTANT: PolymorphicFactory method should not be used by application directly. + * It's designed to be used on RTTIHandle object only once. + * If it's used on any existing object as a form of dynamic cast then + * RTTIWrapper::acquireInstance(Base object) must be called after instantiating new object. + * This is important to keep reference count matching between application and library sides. + */ + public <T> T PolymorphicFactory(Pointer handle, Class<T> cls) { + if (handle == Pointer.NULL) + return null; + Class[] cArg = new Class[2]; + cArg[0] = RTTIWrapper.class; + cArg[1] = Pointer.class; + + try { + T obj = null; + Pointer bufferClassTypeId = new Memory(8); + checkError(null, rtti_base_classtypeid.invokeInt(new java.lang.Object[]{handle, bufferClassTypeId})); + long classTypeId = bufferClassTypeId.getLong(0); + + int msbId = (int)(classTypeId >> 32); + int lsbId = (int)classTypeId; switch(msbId) { - case 0xBC9D5FA7: + case 0x08D007E7: switch(lsbId) { - case 0x750C1020: obj = (T)(new Mammal(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Mammal" + case 0xB5F7BAF4: obj = (T)(new Tiger(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Tiger" } break; - case 0x6756AA8E: + case 0x1549AD28: switch(lsbId) { - case 0xA5802EC3: obj = (T)(new Reptile(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Reptile" + case 0x813DAE05: obj = (T)(new Base(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Base" } break; - case 0x08D007E7: + case 0x2262ABE8: switch(lsbId) { - case 0xB5F7BAF4: obj = (T)(new Tiger(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Tiger" + case 0x0A5E7878: obj = (T)(new Zoo(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Zoo" } break; - case 0x8E551B20: + case 0x5F6826EF: switch(lsbId) { - case 0x8A2E8321: obj = (T)(new Turtle(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Turtle" + case 0x909803B2: obj = (T)(new Snake(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Snake" } break; - case 0xF1917FE6: + case 0x6756AA8E: switch(lsbId) { - case 0xBBE77831: obj = (T)(new AnimalIterator(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" + case 0xA5802EC3: obj = (T)(new Reptile(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Reptile" } break; - case 0x1549AD28: + case 0x8B40467D: switch(lsbId) { - case 0x813DAE05: obj = (T)(new Base(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Base" + case 0xA6D327AF: obj = (T)(new Animal(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Animal" } break; - case 0x9751971B: + case 0x8E551B20: switch(lsbId) { - case 0xD2C2D958: obj = (T)(new Giraffe(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Giraffe" + case 0x8A2E8321: obj = (T)(new Turtle(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Turtle" } break; - case 0x5F6826EF: + case 0x9751971B: switch(lsbId) { - case 0x909803B2: obj = (T)(new Snake(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Snake" + case 0xD2C2D958: obj = (T)(new Giraffe(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Giraffe" } break; - case 0x2262ABE8: + case 0xBC9D5FA7: switch(lsbId) { - case 0x0A5E7878: obj = (T)(new Zoo(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Zoo" + case 0x750C1020: obj = (T)(new Mammal(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Mammal" } break; - case 0x8B40467D: + case 0xF1917FE6: switch(lsbId) { - case 0xA6D327AF: obj = (T)(new Animal(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Animal" + case 0xBBE77831: obj = (T)(new AnimalIterator(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" } break; + default: obj = cls.getDeclaredConstructor(cArg).newInstance(this, handle); break; } return obj; } diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Reptile.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Reptile.java index 623c83d1..8a49ebe7 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Reptile.java +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Reptile.java @@ -28,7 +28,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. public class Reptile extends Animal { - public Reptile(RTTIWrapper wrapper, RTTIHandle handle) { + public Reptile(RTTIWrapper wrapper, Pointer handle) { super(wrapper, handle); } diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Snake.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Snake.java index 45a1a4a1..e2fc6e44 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Snake.java +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Snake.java @@ -28,7 +28,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. public class Snake extends Reptile { - public Snake(RTTIWrapper wrapper, RTTIHandle handle) { + public Snake(RTTIWrapper wrapper, Pointer handle) { super(wrapper, handle); } diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Tiger.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Tiger.java index 70077437..206e06e7 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Tiger.java +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Tiger.java @@ -28,7 +28,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. public class Tiger extends Mammal { - public Tiger(RTTIWrapper wrapper, RTTIHandle handle) { + public Tiger(RTTIWrapper wrapper, Pointer handle) { super(wrapper, handle); } @@ -38,7 +38,7 @@ public Tiger(RTTIWrapper wrapper, RTTIHandle handle) { * @throws RTTIException */ public void roar() throws RTTIException { - mWrapper.checkError(this, mWrapper.rtti_tiger_roar.invokeInt(new java.lang.Object[]{mHandle.Value()})); + mWrapper.checkError(this, mWrapper.rtti_tiger_roar.invokeInt(new java.lang.Object[]{mHandle})); } diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Turtle.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Turtle.java index f10117b8..157c4032 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Turtle.java +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Turtle.java @@ -28,7 +28,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. public class Turtle extends Reptile { - public Turtle(RTTIWrapper wrapper, RTTIHandle handle) { + public Turtle(RTTIWrapper wrapper, Pointer handle) { super(wrapper, handle); } diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Zoo.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Zoo.java index f01b465c..dd26d525 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Zoo.java +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Zoo.java @@ -28,7 +28,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. public class Zoo extends Base { - public Zoo(RTTIWrapper wrapper, RTTIHandle handle) { + public Zoo(RTTIWrapper wrapper, Pointer handle) { super(wrapper, handle); } @@ -39,13 +39,14 @@ public Zoo(RTTIWrapper wrapper, RTTIHandle handle) { * @throws RTTIException */ public AnimalIterator iterator() throws RTTIException { - RTTIHandle handleIterator = new RTTIHandle(); - mWrapper.checkError(this, mWrapper.rtti_zoo_iterator.invokeInt(new java.lang.Object[]{mHandle.Value(), handleIterator})); + Pointer bufferIterator = new Memory(8); + mWrapper.checkError(this, mWrapper.rtti_zoo_iterator.invokeInt(new java.lang.Object[]{mHandle, bufferIterator})); + Pointer valueIterator = bufferIterator.getPointer(0); AnimalIterator iterator = null; - if (handleIterator.Handle == Pointer.NULL) { + if (valueIterator == Pointer.NULL) { throw new RTTIException(RTTIException.RTTI_ERROR_INVALIDPARAM, "Iterator was a null pointer"); } - iterator = mWrapper.PolymorphicFactory(handleIterator, AnimalIterator.class); + iterator = mWrapper.PolymorphicFactory(valueIterator, AnimalIterator.class); return iterator; } diff --git a/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas b/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas index f9f4d663..70172e7d 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas +++ b/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas @@ -19,25 +19,25 @@ interface uses - {$IFDEF WINDOWS} - Windows, - {$ELSE} - dynlibs, - {$ENDIF} - Types, - Classes, - SysUtils; + {$IFDEF WINDOWS} + Windows, + {$ELSE} + dynlibs, + {$ENDIF} + Types, + Classes, + SysUtils; (************************************************************************************************************************* Version definition for RTTI **************************************************************************************************************************) const - RTTI_VERSION_MAJOR = 1; - RTTI_VERSION_MINOR = 0; - RTTI_VERSION_MICRO = 0; - RTTI_VERSION_PRERELEASEINFO = ''; - RTTI_VERSION_BUILDINFO = ''; + RTTI_VERSION_MAJOR = 1; + RTTI_VERSION_MINOR = 0; + RTTI_VERSION_MICRO = 0; + RTTI_VERSION_PRERELEASEINFO = ''; + RTTI_VERSION_BUILDINFO = ''; (************************************************************************************************************************* @@ -45,26 +45,26 @@ interface **************************************************************************************************************************) type - TRTTIResult = Cardinal; - TRTTIHandle = Pointer; + TRTTIResult = Cardinal; + TRTTIHandle = Pointer; - PRTTIResult = ^TRTTIResult; - PRTTIHandle = ^TRTTIHandle; + PRTTIResult = ^TRTTIResult; + PRTTIHandle = ^TRTTIHandle; (************************************************************************************************************************* Error Constants for RTTI **************************************************************************************************************************) const - RTTI_SUCCESS = 0; - RTTI_ERROR_NOTIMPLEMENTED = 1; - RTTI_ERROR_INVALIDPARAM = 2; - RTTI_ERROR_INVALIDCAST = 3; - RTTI_ERROR_BUFFERTOOSMALL = 4; - RTTI_ERROR_GENERICEXCEPTION = 5; - RTTI_ERROR_COULDNOTLOADLIBRARY = 6; - RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT = 7; - RTTI_ERROR_INCOMPATIBLEBINARYVERSION = 8; + RTTI_SUCCESS = 0; + RTTI_ERROR_NOTIMPLEMENTED = 1; + RTTI_ERROR_INVALIDPARAM = 2; + RTTI_ERROR_INVALIDCAST = 3; + RTTI_ERROR_BUFFERTOOSMALL = 4; + RTTI_ERROR_GENERICEXCEPTION = 5; + RTTI_ERROR_COULDNOTLOADLIBRARY = 6; + RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT = 7; + RTTI_ERROR_INCOMPATIBLEBINARYVERSION = 8; (************************************************************************************************************************* @@ -72,48 +72,48 @@ interface **************************************************************************************************************************) type - TRTTIWrapper = class; - TRTTIBase = class; - TRTTIAnimal = class; - TRTTIMammal = class; - TRTTIReptile = class; - TRTTIGiraffe = class; - TRTTITiger = class; - TRTTISnake = class; - TRTTITurtle = class; - TRTTIAnimalIterator = class; - TRTTIZoo = class; + TRTTIWrapper = class; + TRTTIBase = class; + TRTTIAnimal = class; + TRTTIMammal = class; + TRTTIReptile = class; + TRTTIGiraffe = class; + TRTTITiger = class; + TRTTISnake = class; + TRTTITurtle = class; + TRTTIAnimalIterator = class; + TRTTIZoo = class; (************************************************************************************************************************* Function type definitions for Base **************************************************************************************************************************) - (** - * Get Class Type Id - * - * @param[in] pBase - Base instance. - * @param[out] pClassTypeId - Class type as a 64 bits integer - * @return error code or 0 (success) - *) - TRTTIBase_ClassTypeIdFunc = function(pBase: TRTTIHandle; out pClassTypeId: QWord): TRTTIResult; cdecl; - + (** + * Get Class Type Id + * + * @param[in] pBase - Base instance. + * @param[out] pClassTypeId - Class type as a 64 bits integer + * @return error code or 0 (success) + *) + TRTTIBase_ClassTypeIdFunc = function(pBase: TRTTIHandle; out pClassTypeId: QWord): TRTTIResult; cdecl; + (************************************************************************************************************************* Function type definitions for Animal **************************************************************************************************************************) - (** - * Get the name of the animal - * - * @param[in] pAnimal - Animal instance. - * @param[in] nResultBufferSize - size of the buffer (including trailing 0) - * @param[out] pResultNeededChars - will be filled with the count of the written bytes, or needed buffer size. - * @param[out] pResultBuffer - buffer of , may be NULL - * @return error code or 0 (success) - *) - TRTTIAnimal_NameFunc = function(pAnimal: TRTTIHandle; const nResultBufferSize: Cardinal; out pResultNeededChars: Cardinal; pResultBuffer: PAnsiChar): TRTTIResult; cdecl; - + (** + * Get the name of the animal + * + * @param[in] pAnimal - Animal instance. + * @param[in] nResultBufferSize - size of the buffer (including trailing 0) + * @param[out] pResultNeededChars - will be filled with the count of the written bytes, or needed buffer size. + * @param[out] pResultBuffer - buffer of , may be NULL + * @return error code or 0 (success) + *) + TRTTIAnimal_NameFunc = function(pAnimal: TRTTIHandle; const nResultBufferSize: Cardinal; out pResultNeededChars: Cardinal; pResultBuffer: PAnsiChar): TRTTIResult; cdecl; + (************************************************************************************************************************* Function type definitions for Mammal @@ -134,14 +134,14 @@ TRTTIZoo = class; Function type definitions for Tiger **************************************************************************************************************************) - (** - * Roar like a tiger - * - * @param[in] pTiger - Tiger instance. - * @return error code or 0 (success) - *) - TRTTITiger_RoarFunc = function(pTiger: TRTTIHandle): TRTTIResult; cdecl; - + (** + * Roar like a tiger + * + * @param[in] pTiger - Tiger instance. + * @return error code or 0 (success) + *) + TRTTITiger_RoarFunc = function(pTiger: TRTTIHandle): TRTTIResult; cdecl; + (************************************************************************************************************************* Function type definitions for Snake @@ -157,96 +157,96 @@ TRTTIZoo = class; Function type definitions for AnimalIterator **************************************************************************************************************************) - (** - * Return next animal - * - * @param[in] pAnimalIterator - AnimalIterator instance. - * @param[out] pAnimal - - * @return error code or 0 (success) - *) - TRTTIAnimalIterator_GetNextAnimalFunc = function(pAnimalIterator: TRTTIHandle; out pAnimal: TRTTIHandle): TRTTIResult; cdecl; - + (** + * Return next animal + * + * @param[in] pAnimalIterator - AnimalIterator instance. + * @param[out] pAnimal - + * @return error code or 0 (success) + *) + TRTTIAnimalIterator_GetNextAnimalFunc = function(pAnimalIterator: TRTTIHandle; out pAnimal: TRTTIHandle): TRTTIResult; cdecl; + (************************************************************************************************************************* Function type definitions for Zoo **************************************************************************************************************************) - (** - * Return an iterator over all zoo animals - * - * @param[in] pZoo - Zoo instance. - * @param[out] pIterator - - * @return error code or 0 (success) - *) - TRTTIZoo_IteratorFunc = function(pZoo: TRTTIHandle; out pIterator: TRTTIHandle): TRTTIResult; cdecl; - + (** + * Return an iterator over all zoo animals + * + * @param[in] pZoo - Zoo instance. + * @param[out] pIterator - + * @return error code or 0 (success) + *) + TRTTIZoo_IteratorFunc = function(pZoo: TRTTIHandle; out pIterator: TRTTIHandle): TRTTIResult; cdecl; + (************************************************************************************************************************* Global function definitions **************************************************************************************************************************) - (** - * retrieves the binary version of this library. - * - * @param[out] pMajor - returns the major version of this library - * @param[out] pMinor - returns the minor version of this library - * @param[out] pMicro - returns the micro version of this library - * @return error code or 0 (success) - *) - TRTTIGetVersionFunc = function(out pMajor: Cardinal; out pMinor: Cardinal; out pMicro: Cardinal): TRTTIResult; cdecl; - - (** - * Returns the last error recorded on this object - * - * @param[in] pInstance - Instance Handle - * @param[in] nErrorMessageBufferSize - size of the buffer (including trailing 0) - * @param[out] pErrorMessageNeededChars - will be filled with the count of the written bytes, or needed buffer size. - * @param[out] pErrorMessageBuffer - buffer of Message of the last error, may be NULL - * @param[out] pHasError - Is there a last error to query - * @return error code or 0 (success) - *) - TRTTIGetLastErrorFunc = function(const pInstance: TRTTIHandle; const nErrorMessageBufferSize: Cardinal; out pErrorMessageNeededChars: Cardinal; pErrorMessageBuffer: PAnsiChar; out pHasError: Byte): TRTTIResult; cdecl; - - (** - * Releases shared ownership of an Instance - * - * @param[in] pInstance - Instance Handle - * @return error code or 0 (success) - *) - TRTTIReleaseInstanceFunc = function(const pInstance: TRTTIHandle): TRTTIResult; cdecl; - - (** - * Acquires shared ownership of an Instance - * - * @param[in] pInstance - Instance Handle - * @return error code or 0 (success) - *) - TRTTIAcquireInstanceFunc = function(const pInstance: TRTTIHandle): TRTTIResult; cdecl; - - (** - * Injects an imported component for usage within this component - * - * @param[in] pNameSpace - NameSpace of the injected component - * @param[in] pSymbolAddressMethod - Address of the SymbolAddressMethod of the injected component - * @return error code or 0 (success) - *) - TRTTIInjectComponentFunc = function(const pNameSpace: PAnsiChar; const pSymbolAddressMethod: Pointer): TRTTIResult; cdecl; - - (** - * Returns the address of the SymbolLookupMethod - * - * @param[out] pSymbolLookupMethod - Address of the SymbolAddressMethod - * @return error code or 0 (success) - *) - TRTTIGetSymbolLookupMethodFunc = function(out pSymbolLookupMethod: Pointer): TRTTIResult; cdecl; - - (** - * Create a new zoo with animals - * - * @param[out] pInstance - - * @return error code or 0 (success) - *) - TRTTICreateZooFunc = function(out pInstance: TRTTIHandle): TRTTIResult; cdecl; - + (** + * retrieves the binary version of this library. + * + * @param[out] pMajor - returns the major version of this library + * @param[out] pMinor - returns the minor version of this library + * @param[out] pMicro - returns the micro version of this library + * @return error code or 0 (success) + *) + TRTTIGetVersionFunc = function(out pMajor: Cardinal; out pMinor: Cardinal; out pMicro: Cardinal): TRTTIResult; cdecl; + + (** + * Returns the last error recorded on this object + * + * @param[in] pInstance - Instance Handle + * @param[in] nErrorMessageBufferSize - size of the buffer (including trailing 0) + * @param[out] pErrorMessageNeededChars - will be filled with the count of the written bytes, or needed buffer size. + * @param[out] pErrorMessageBuffer - buffer of Message of the last error, may be NULL + * @param[out] pHasError - Is there a last error to query + * @return error code or 0 (success) + *) + TRTTIGetLastErrorFunc = function(const pInstance: TRTTIHandle; const nErrorMessageBufferSize: Cardinal; out pErrorMessageNeededChars: Cardinal; pErrorMessageBuffer: PAnsiChar; out pHasError: Byte): TRTTIResult; cdecl; + + (** + * Releases shared ownership of an Instance + * + * @param[in] pInstance - Instance Handle + * @return error code or 0 (success) + *) + TRTTIReleaseInstanceFunc = function(const pInstance: TRTTIHandle): TRTTIResult; cdecl; + + (** + * Acquires shared ownership of an Instance + * + * @param[in] pInstance - Instance Handle + * @return error code or 0 (success) + *) + TRTTIAcquireInstanceFunc = function(const pInstance: TRTTIHandle): TRTTIResult; cdecl; + + (** + * Injects an imported component for usage within this component + * + * @param[in] pNameSpace - NameSpace of the injected component + * @param[in] pSymbolAddressMethod - Address of the SymbolAddressMethod of the injected component + * @return error code or 0 (success) + *) + TRTTIInjectComponentFunc = function(const pNameSpace: PAnsiChar; const pSymbolAddressMethod: Pointer): TRTTIResult; cdecl; + + (** + * Returns the address of the SymbolLookupMethod + * + * @param[out] pSymbolLookupMethod - Address of the SymbolAddressMethod + * @return error code or 0 (success) + *) + TRTTIGetSymbolLookupMethodFunc = function(out pSymbolLookupMethod: Pointer): TRTTIResult; cdecl; + + (** + * Create a new zoo with animals + * + * @param[out] pInstance - + * @return error code or 0 (success) + *) + TRTTICreateZooFunc = function(out pInstance: TRTTIHandle): TRTTIResult; cdecl; + (************************************************************************************************************************* Helper function pointer definitions @@ -257,16 +257,16 @@ TRTTIZoo = class; Exception definition **************************************************************************************************************************) - ERTTIException = class(Exception) - private - FErrorCode: TRTTIResult; - FCustomMessage: String; - public - property ErrorCode: TRTTIResult read FErrorCode; - property CustomMessage: String read FCustomMessage; - constructor Create(AErrorCode: TRTTIResult; AMessage: String); - constructor CreateCustomMessage(AErrorCode: TRTTIResult; AMessage: String); - end; + ERTTIException = class(Exception) + private + FErrorCode: TRTTIResult; + FCustomMessage: String; + public + property ErrorCode: TRTTIResult read FErrorCode; + property CustomMessage: String read FCustomMessage; + constructor Create(AErrorCode: TRTTIResult; AMessage: String); + constructor CreateCustomMessage(AErrorCode: TRTTIResult; AMessage: String); + end; (************************************************************************************************************************* @@ -274,177 +274,177 @@ ERTTIException = class(Exception) **************************************************************************************************************************) TRTTIBase = class(TObject) - private - FWrapper: TRTTIWrapper; - FHandle: TRTTIHandle; - public - constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - destructor Destroy; override; - property TheHandle: TRTTIHandle read FHandle; - function ClassTypeId(): QWord; - end; + private + FWrapper: TRTTIWrapper; + FHandle: TRTTIHandle; + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + property TheHandle: TRTTIHandle read FHandle; + function ClassTypeId(): QWord; + end; (************************************************************************************************************************* Class definition for Animal **************************************************************************************************************************) - TRTTIAnimal = class(TRTTIBase) - public - constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - destructor Destroy; override; - function Name(): String; - end; + TRTTIAnimal = class(TRTTIBase) + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + function Name(): String; + end; (************************************************************************************************************************* Class definition for Mammal **************************************************************************************************************************) - TRTTIMammal = class(TRTTIAnimal) - public - constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - destructor Destroy; override; - end; + TRTTIMammal = class(TRTTIAnimal) + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + end; (************************************************************************************************************************* Class definition for Reptile **************************************************************************************************************************) - TRTTIReptile = class(TRTTIAnimal) - public - constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - destructor Destroy; override; - end; + TRTTIReptile = class(TRTTIAnimal) + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + end; (************************************************************************************************************************* Class definition for Giraffe **************************************************************************************************************************) - TRTTIGiraffe = class(TRTTIMammal) - public - constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - destructor Destroy; override; - end; + TRTTIGiraffe = class(TRTTIMammal) + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + end; (************************************************************************************************************************* Class definition for Tiger **************************************************************************************************************************) - TRTTITiger = class(TRTTIMammal) - public - constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - destructor Destroy; override; - procedure Roar(); - end; + TRTTITiger = class(TRTTIMammal) + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + procedure Roar(); + end; (************************************************************************************************************************* Class definition for Snake **************************************************************************************************************************) - TRTTISnake = class(TRTTIReptile) - public - constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - destructor Destroy; override; - end; + TRTTISnake = class(TRTTIReptile) + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + end; (************************************************************************************************************************* Class definition for Turtle **************************************************************************************************************************) - TRTTITurtle = class(TRTTIReptile) - public - constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - destructor Destroy; override; - end; + TRTTITurtle = class(TRTTIReptile) + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + end; (************************************************************************************************************************* Class definition for AnimalIterator **************************************************************************************************************************) - TRTTIAnimalIterator = class(TRTTIBase) - public - constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - destructor Destroy; override; - function GetNextAnimal(): TRTTIAnimal; - end; + TRTTIAnimalIterator = class(TRTTIBase) + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + function GetNextAnimal(): TRTTIAnimal; + end; (************************************************************************************************************************* Class definition for Zoo **************************************************************************************************************************) - TRTTIZoo = class(TRTTIBase) - public - constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - destructor Destroy; override; - function Iterator(): TRTTIAnimalIterator; - end; + TRTTIZoo = class(TRTTIBase) + public + constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + destructor Destroy; override; + function Iterator(): TRTTIAnimalIterator; + end; (************************************************************************************************************************* Wrapper definition **************************************************************************************************************************) - TRTTIWrapper = class(TObject) - private - FModule: HMODULE; - FRTTIBase_ClassTypeIdFunc: TRTTIBase_ClassTypeIdFunc; - FRTTIAnimal_NameFunc: TRTTIAnimal_NameFunc; - FRTTITiger_RoarFunc: TRTTITiger_RoarFunc; - FRTTIAnimalIterator_GetNextAnimalFunc: TRTTIAnimalIterator_GetNextAnimalFunc; - FRTTIZoo_IteratorFunc: TRTTIZoo_IteratorFunc; - FRTTIGetVersionFunc: TRTTIGetVersionFunc; - FRTTIGetLastErrorFunc: TRTTIGetLastErrorFunc; - FRTTIReleaseInstanceFunc: TRTTIReleaseInstanceFunc; - FRTTIAcquireInstanceFunc: TRTTIAcquireInstanceFunc; - FRTTIInjectComponentFunc: TRTTIInjectComponentFunc; - FRTTIGetSymbolLookupMethodFunc: TRTTIGetSymbolLookupMethodFunc; - FRTTICreateZooFunc: TRTTICreateZooFunc; - - {$IFDEF MSWINDOWS} - function LoadFunction(AFunctionName: AnsiString; FailIfNotExistent: Boolean = True): FARPROC; - {$ELSE} - function LoadFunction(AFunctionName: AnsiString; FailIfNotExistent: Boolean = True): Pointer; - {$ENDIF MSWINDOWS} - - procedure checkBinaryVersion(); - - protected - property RTTIBase_ClassTypeIdFunc: TRTTIBase_ClassTypeIdFunc read FRTTIBase_ClassTypeIdFunc; - property RTTIAnimal_NameFunc: TRTTIAnimal_NameFunc read FRTTIAnimal_NameFunc; - property RTTITiger_RoarFunc: TRTTITiger_RoarFunc read FRTTITiger_RoarFunc; - property RTTIAnimalIterator_GetNextAnimalFunc: TRTTIAnimalIterator_GetNextAnimalFunc read FRTTIAnimalIterator_GetNextAnimalFunc; - property RTTIZoo_IteratorFunc: TRTTIZoo_IteratorFunc read FRTTIZoo_IteratorFunc; - property RTTIGetVersionFunc: TRTTIGetVersionFunc read FRTTIGetVersionFunc; - property RTTIGetLastErrorFunc: TRTTIGetLastErrorFunc read FRTTIGetLastErrorFunc; - property RTTIReleaseInstanceFunc: TRTTIReleaseInstanceFunc read FRTTIReleaseInstanceFunc; - property RTTIAcquireInstanceFunc: TRTTIAcquireInstanceFunc read FRTTIAcquireInstanceFunc; - property RTTIInjectComponentFunc: TRTTIInjectComponentFunc read FRTTIInjectComponentFunc; - property RTTIGetSymbolLookupMethodFunc: TRTTIGetSymbolLookupMethodFunc read FRTTIGetSymbolLookupMethodFunc; - property RTTICreateZooFunc: TRTTICreateZooFunc read FRTTICreateZooFunc; - procedure CheckError(AInstance: TRTTIBase; AErrorCode: TRTTIResult); - public - constructor Create(ADLLName: String); - constructor CreateFromSymbolLookupMethod(ALookupMethod: TRTTISymbolLookupMethod); - destructor Destroy; override; - procedure GetVersion(out AMajor: Cardinal; out AMinor: Cardinal; out AMicro: Cardinal); - function GetLastError(const AInstance: TRTTIBase; out AErrorMessage: String): Boolean; - procedure ReleaseInstance(const AInstance: TRTTIBase); - procedure AcquireInstance(const AInstance: TRTTIBase); - procedure InjectComponent(const ANameSpace: String; const ASymbolAddressMethod: Pointer); - function GetSymbolLookupMethod(): Pointer; - function CreateZoo(): TRTTIZoo; - end; - - TPolymorphicFactory<_T:class; _B> = record - class function Make(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): _T; static; - end; + TRTTIWrapper = class(TObject) + private + FModule: HMODULE; + FRTTIBase_ClassTypeIdFunc: TRTTIBase_ClassTypeIdFunc; + FRTTIAnimal_NameFunc: TRTTIAnimal_NameFunc; + FRTTITiger_RoarFunc: TRTTITiger_RoarFunc; + FRTTIAnimalIterator_GetNextAnimalFunc: TRTTIAnimalIterator_GetNextAnimalFunc; + FRTTIZoo_IteratorFunc: TRTTIZoo_IteratorFunc; + FRTTIGetVersionFunc: TRTTIGetVersionFunc; + FRTTIGetLastErrorFunc: TRTTIGetLastErrorFunc; + FRTTIReleaseInstanceFunc: TRTTIReleaseInstanceFunc; + FRTTIAcquireInstanceFunc: TRTTIAcquireInstanceFunc; + FRTTIInjectComponentFunc: TRTTIInjectComponentFunc; + FRTTIGetSymbolLookupMethodFunc: TRTTIGetSymbolLookupMethodFunc; + FRTTICreateZooFunc: TRTTICreateZooFunc; + + {$IFDEF MSWINDOWS} + function LoadFunction(AFunctionName: AnsiString; FailIfNotExistent: Boolean = True): FARPROC; + {$ELSE} + function LoadFunction(AFunctionName: AnsiString; FailIfNotExistent: Boolean = True): Pointer; + {$ENDIF MSWINDOWS} + + procedure checkBinaryVersion(); + + protected + property RTTIBase_ClassTypeIdFunc: TRTTIBase_ClassTypeIdFunc read FRTTIBase_ClassTypeIdFunc; + property RTTIAnimal_NameFunc: TRTTIAnimal_NameFunc read FRTTIAnimal_NameFunc; + property RTTITiger_RoarFunc: TRTTITiger_RoarFunc read FRTTITiger_RoarFunc; + property RTTIAnimalIterator_GetNextAnimalFunc: TRTTIAnimalIterator_GetNextAnimalFunc read FRTTIAnimalIterator_GetNextAnimalFunc; + property RTTIZoo_IteratorFunc: TRTTIZoo_IteratorFunc read FRTTIZoo_IteratorFunc; + property RTTIGetVersionFunc: TRTTIGetVersionFunc read FRTTIGetVersionFunc; + property RTTIGetLastErrorFunc: TRTTIGetLastErrorFunc read FRTTIGetLastErrorFunc; + property RTTIReleaseInstanceFunc: TRTTIReleaseInstanceFunc read FRTTIReleaseInstanceFunc; + property RTTIAcquireInstanceFunc: TRTTIAcquireInstanceFunc read FRTTIAcquireInstanceFunc; + property RTTIInjectComponentFunc: TRTTIInjectComponentFunc read FRTTIInjectComponentFunc; + property RTTIGetSymbolLookupMethodFunc: TRTTIGetSymbolLookupMethodFunc read FRTTIGetSymbolLookupMethodFunc; + property RTTICreateZooFunc: TRTTICreateZooFunc read FRTTICreateZooFunc; + procedure CheckError(AInstance: TRTTIBase; AErrorCode: TRTTIResult); + public + constructor Create(ADLLName: String); + constructor CreateFromSymbolLookupMethod(ALookupMethod: TRTTISymbolLookupMethod); + destructor Destroy; override; + procedure GetVersion(out AMajor: Cardinal; out AMinor: Cardinal; out AMicro: Cardinal); + function GetLastError(const AInstance: TRTTIBase; out AErrorMessage: String): Boolean; + procedure ReleaseInstance(const AInstance: TRTTIBase); + procedure AcquireInstance(const AInstance: TRTTIBase); + procedure InjectComponent(const ANameSpace: String; const ASymbolAddressMethod: Pointer); + function GetSymbolLookupMethod(): Pointer; + function CreateZoo(): TRTTIZoo; + end; + + TRTTIPolymorphicFactory<_T:class; _B> = record + class function Make(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): _T; static; + end; implementation @@ -453,461 +453,468 @@ implementation PolymorficFactory implementation **************************************************************************************************************************) - class function TPolymorphicFactory<_T, _B>.Make(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): _T; - var - ClassTypeId: QWord; - Obj: TRTTIBase; - begin - Result := nil; - Wrapper.CheckError(nil, Wrapper.RTTIBase_ClassTypeIdFunc(handle, ClassTypeId)); - case (ClassTypeId) of - $1549AD28813DAE05: begin Obj := TRTTIBase.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Base" - $8B40467DA6D327AF: begin Obj := TRTTIAnimal.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Animal" - $BC9D5FA7750C1020: begin Obj := TRTTIMammal.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Mammal" - $6756AA8EA5802EC3: begin Obj := TRTTIReptile.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Reptile" - $9751971BD2C2D958: begin Obj := TRTTIGiraffe.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Giraffe" - $08D007E7B5F7BAF4: begin Obj := TRTTITiger.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Tiger" - $5F6826EF909803B2: begin Obj := TRTTISnake.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Snake" - $8E551B208A2E8321: begin Obj := TRTTITurtle.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Turtle" - $F1917FE6BBE77831: begin Obj := TRTTIAnimalIterator.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" - $2262ABE80A5E7878: begin Obj := TRTTIZoo.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Zoo" - end; - if Result = nil then Result := _B.Create(Wrapper, Handle); - end; + (** + * IMPORTANT: PolymorphicFactory method should not be used by application directly. + * It's designed to be used on RTTIHandle object only once. + * If it's used on any existing object as a form of dynamic cast then + * TRTTIWrapper::AcquireInstance(object: TRTTIBase) must be called after instantiating new object. + * This is important to keep reference count matching between application and library sides. + *) + class function TRTTIPolymorphicFactory<_T, _B>.Make(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): _T; + var + ClassTypeId: QWord; + Obj: TRTTIBase; + begin + Result := nil; + Wrapper.CheckError(nil, Wrapper.RTTIBase_ClassTypeIdFunc(handle, ClassTypeId)); + case (ClassTypeId) of + QWord($1549AD28813DAE05): begin Obj := TRTTIBase.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Base" + QWord($8B40467DA6D327AF): begin Obj := TRTTIAnimal.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Animal" + QWord($BC9D5FA7750C1020): begin Obj := TRTTIMammal.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Mammal" + QWord($6756AA8EA5802EC3): begin Obj := TRTTIReptile.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Reptile" + QWord($9751971BD2C2D958): begin Obj := TRTTIGiraffe.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Giraffe" + QWord($08D007E7B5F7BAF4): begin Obj := TRTTITiger.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Tiger" + QWord($5F6826EF909803B2): begin Obj := TRTTISnake.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Snake" + QWord($8E551B208A2E8321): begin Obj := TRTTITurtle.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Turtle" + QWord($F1917FE6BBE77831): begin Obj := TRTTIAnimalIterator.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" + QWord($2262ABE80A5E7878): begin Obj := TRTTIZoo.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "RTTI::Zoo" + end; + if Result = nil then Result := _B.Create(Wrapper, Handle); + end; (************************************************************************************************************************* Exception implementation **************************************************************************************************************************) - constructor ERTTIException.Create(AErrorCode: TRTTIResult; AMessage: String); - var - ADescription: String; - begin - FErrorCode := AErrorCode; - case FErrorCode of - RTTI_ERROR_NOTIMPLEMENTED: ADescription := 'functionality not implemented'; - RTTI_ERROR_INVALIDPARAM: ADescription := 'an invalid parameter was passed'; - RTTI_ERROR_INVALIDCAST: ADescription := 'a type cast failed'; - RTTI_ERROR_BUFFERTOOSMALL: ADescription := 'a provided buffer is too small'; - RTTI_ERROR_GENERICEXCEPTION: ADescription := 'a generic exception occurred'; - RTTI_ERROR_COULDNOTLOADLIBRARY: ADescription := 'the library could not be loaded'; - RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT: ADescription := 'a required exported symbol could not be found in the library'; - RTTI_ERROR_INCOMPATIBLEBINARYVERSION: ADescription := 'the version of the binary interface does not match the bindings interface'; - else - ADescription := 'unknown'; - end; - - inherited Create(Format('RTTI Error - %s (#%d, %s)', [ ADescription, AErrorCode, AMessage ])); - end; - - constructor ERTTIException.CreateCustomMessage(AErrorCode: TRTTIResult; AMessage: String); - begin - FCustomMessage := AMessage; - FErrorCode := AErrorCode; - inherited Create(Format('%s (%d)', [FCustomMessage, AErrorCode])); - end; + constructor ERTTIException.Create(AErrorCode: TRTTIResult; AMessage: String); + var + ADescription: String; + begin + FErrorCode := AErrorCode; + case FErrorCode of + RTTI_ERROR_NOTIMPLEMENTED: ADescription := 'functionality not implemented'; + RTTI_ERROR_INVALIDPARAM: ADescription := 'an invalid parameter was passed'; + RTTI_ERROR_INVALIDCAST: ADescription := 'a type cast failed'; + RTTI_ERROR_BUFFERTOOSMALL: ADescription := 'a provided buffer is too small'; + RTTI_ERROR_GENERICEXCEPTION: ADescription := 'a generic exception occurred'; + RTTI_ERROR_COULDNOTLOADLIBRARY: ADescription := 'the library could not be loaded'; + RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT: ADescription := 'a required exported symbol could not be found in the library'; + RTTI_ERROR_INCOMPATIBLEBINARYVERSION: ADescription := 'the version of the binary interface does not match the bindings interface'; + else + ADescription := 'unknown'; + end; + + inherited Create(Format('RTTI Error - %s (#%d, %s)', [ ADescription, AErrorCode, AMessage ])); + end; + + constructor ERTTIException.CreateCustomMessage(AErrorCode: TRTTIResult; AMessage: String); + begin + FCustomMessage := AMessage; + FErrorCode := AErrorCode; + inherited Create(Format('%s (%d)', [FCustomMessage, AErrorCode])); + end; (************************************************************************************************************************* Class implementation for Base **************************************************************************************************************************) - constructor TRTTIBase.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - begin - if not Assigned(AWrapper) then - raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM, ''); - if not Assigned(AHandle) then - raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM, ''); + constructor TRTTIBase.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + if not Assigned(AWrapper) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM, ''); + if not Assigned(AHandle) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM, ''); - inherited Create(); - FWrapper := AWrapper; - FHandle := AHandle; - end; + inherited Create(); + FWrapper := AWrapper; + FHandle := AHandle; + end; - destructor TRTTIBase.Destroy; - begin - FWrapper.ReleaseInstance(self); - inherited; - end; + destructor TRTTIBase.Destroy; + begin + FWrapper.ReleaseInstance(self); + inherited; + end; - function TRTTIBase.ClassTypeId(): QWord; - begin - FWrapper.CheckError(Self, FWrapper.RTTIBase_ClassTypeIdFunc(FHandle, Result)); - end; + function TRTTIBase.ClassTypeId(): QWord; + begin + FWrapper.CheckError(Self, FWrapper.RTTIBase_ClassTypeIdFunc(FHandle, Result)); + end; (************************************************************************************************************************* Class implementation for Animal **************************************************************************************************************************) - constructor TRTTIAnimal.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - begin - inherited Create(AWrapper, AHandle); - end; + constructor TRTTIAnimal.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + inherited Create(AWrapper, AHandle); + end; - destructor TRTTIAnimal.Destroy; - begin - inherited; - end; + destructor TRTTIAnimal.Destroy; + begin + inherited; + end; - function TRTTIAnimal.Name(): String; - var - bytesNeededResult: Cardinal; - bytesWrittenResult: Cardinal; - bufferResult: array of Char; - begin - bytesNeededResult:= 0; - bytesWrittenResult:= 0; - FWrapper.CheckError(Self, FWrapper.RTTIAnimal_NameFunc(FHandle, 0, bytesNeededResult, nil)); - SetLength(bufferResult, bytesNeededResult); - FWrapper.CheckError(Self, FWrapper.RTTIAnimal_NameFunc(FHandle, bytesNeededResult, bytesWrittenResult, @bufferResult[0])); - Result := StrPas(@bufferResult[0]); - end; + function TRTTIAnimal.Name(): String; + var + bytesNeededResult: Cardinal; + bytesWrittenResult: Cardinal; + bufferResult: array of Char; + begin + bytesNeededResult:= 0; + bytesWrittenResult:= 0; + FWrapper.CheckError(Self, FWrapper.RTTIAnimal_NameFunc(FHandle, 0, bytesNeededResult, nil)); + SetLength(bufferResult, bytesNeededResult); + FWrapper.CheckError(Self, FWrapper.RTTIAnimal_NameFunc(FHandle, bytesNeededResult, bytesWrittenResult, @bufferResult[0])); + Result := StrPas(@bufferResult[0]); + end; (************************************************************************************************************************* Class implementation for Mammal **************************************************************************************************************************) - constructor TRTTIMammal.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - begin - inherited Create(AWrapper, AHandle); - end; + constructor TRTTIMammal.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + inherited Create(AWrapper, AHandle); + end; - destructor TRTTIMammal.Destroy; - begin - inherited; - end; + destructor TRTTIMammal.Destroy; + begin + inherited; + end; (************************************************************************************************************************* Class implementation for Reptile **************************************************************************************************************************) - constructor TRTTIReptile.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - begin - inherited Create(AWrapper, AHandle); - end; + constructor TRTTIReptile.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + inherited Create(AWrapper, AHandle); + end; - destructor TRTTIReptile.Destroy; - begin - inherited; - end; + destructor TRTTIReptile.Destroy; + begin + inherited; + end; (************************************************************************************************************************* Class implementation for Giraffe **************************************************************************************************************************) - constructor TRTTIGiraffe.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - begin - inherited Create(AWrapper, AHandle); - end; + constructor TRTTIGiraffe.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + inherited Create(AWrapper, AHandle); + end; - destructor TRTTIGiraffe.Destroy; - begin - inherited; - end; + destructor TRTTIGiraffe.Destroy; + begin + inherited; + end; (************************************************************************************************************************* Class implementation for Tiger **************************************************************************************************************************) - constructor TRTTITiger.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - begin - inherited Create(AWrapper, AHandle); - end; + constructor TRTTITiger.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + inherited Create(AWrapper, AHandle); + end; - destructor TRTTITiger.Destroy; - begin - inherited; - end; + destructor TRTTITiger.Destroy; + begin + inherited; + end; - procedure TRTTITiger.Roar(); - begin - FWrapper.CheckError(Self, FWrapper.RTTITiger_RoarFunc(FHandle)); - end; + procedure TRTTITiger.Roar(); + begin + FWrapper.CheckError(Self, FWrapper.RTTITiger_RoarFunc(FHandle)); + end; (************************************************************************************************************************* Class implementation for Snake **************************************************************************************************************************) - constructor TRTTISnake.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - begin - inherited Create(AWrapper, AHandle); - end; + constructor TRTTISnake.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + inherited Create(AWrapper, AHandle); + end; - destructor TRTTISnake.Destroy; - begin - inherited; - end; + destructor TRTTISnake.Destroy; + begin + inherited; + end; (************************************************************************************************************************* Class implementation for Turtle **************************************************************************************************************************) - constructor TRTTITurtle.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - begin - inherited Create(AWrapper, AHandle); - end; + constructor TRTTITurtle.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + inherited Create(AWrapper, AHandle); + end; - destructor TRTTITurtle.Destroy; - begin - inherited; - end; + destructor TRTTITurtle.Destroy; + begin + inherited; + end; (************************************************************************************************************************* Class implementation for AnimalIterator **************************************************************************************************************************) - constructor TRTTIAnimalIterator.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - begin - inherited Create(AWrapper, AHandle); - end; + constructor TRTTIAnimalIterator.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + inherited Create(AWrapper, AHandle); + end; - destructor TRTTIAnimalIterator.Destroy; - begin - inherited; - end; + destructor TRTTIAnimalIterator.Destroy; + begin + inherited; + end; - function TRTTIAnimalIterator.GetNextAnimal(): TRTTIAnimal; - var - HAnimal: TRTTIHandle; - begin - Result := nil; - HAnimal := nil; - FWrapper.CheckError(Self, FWrapper.RTTIAnimalIterator_GetNextAnimalFunc(FHandle, HAnimal)); - if Assigned(HAnimal) then - Result := TPolymorphicFactory<TRTTIAnimal, TRTTIAnimal>.Make(FWrapper, HAnimal); - end; + function TRTTIAnimalIterator.GetNextAnimal(): TRTTIAnimal; + var + HAnimal: TRTTIHandle; + begin + Result := nil; + HAnimal := nil; + FWrapper.CheckError(Self, FWrapper.RTTIAnimalIterator_GetNextAnimalFunc(FHandle, HAnimal)); + if Assigned(HAnimal) then + Result := TRTTIPolymorphicFactory<TRTTIAnimal, TRTTIAnimal>.Make(FWrapper, HAnimal); + end; (************************************************************************************************************************* Class implementation for Zoo **************************************************************************************************************************) - constructor TRTTIZoo.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); - begin - inherited Create(AWrapper, AHandle); - end; + constructor TRTTIZoo.Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); + begin + inherited Create(AWrapper, AHandle); + end; - destructor TRTTIZoo.Destroy; - begin - inherited; - end; + destructor TRTTIZoo.Destroy; + begin + inherited; + end; - function TRTTIZoo.Iterator(): TRTTIAnimalIterator; - var - HIterator: TRTTIHandle; - begin - Result := nil; - HIterator := nil; - FWrapper.CheckError(Self, FWrapper.RTTIZoo_IteratorFunc(FHandle, HIterator)); - if Assigned(HIterator) then - Result := TPolymorphicFactory<TRTTIAnimalIterator, TRTTIAnimalIterator>.Make(FWrapper, HIterator); - end; + function TRTTIZoo.Iterator(): TRTTIAnimalIterator; + var + HIterator: TRTTIHandle; + begin + Result := nil; + HIterator := nil; + FWrapper.CheckError(Self, FWrapper.RTTIZoo_IteratorFunc(FHandle, HIterator)); + if Assigned(HIterator) then + Result := TRTTIPolymorphicFactory<TRTTIAnimalIterator, TRTTIAnimalIterator>.Make(FWrapper, HIterator); + end; (************************************************************************************************************************* Wrapper class implementation **************************************************************************************************************************) - constructor TRTTIWrapper.Create(ADLLName: String); - {$IFDEF MSWINDOWS} - var - AWideString: WideString; - {$ENDIF MSWINDOWS} - begin - inherited Create; - - - {$IFDEF MSWINDOWS} - AWideString := UTF8Decode(ADLLName + #0); - FModule := LoadLibraryW(PWideChar(AWideString)); - {$ELSE} - FModule := dynlibs.LoadLibrary(ADLLName); - {$ENDIF MSWINDOWS} - if FModule = 0 then - raise ERTTIException.Create(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); - - FRTTIBase_ClassTypeIdFunc := LoadFunction('rtti_base_classtypeid'); - FRTTIAnimal_NameFunc := LoadFunction('rtti_animal_name'); - FRTTITiger_RoarFunc := LoadFunction('rtti_tiger_roar'); - FRTTIAnimalIterator_GetNextAnimalFunc := LoadFunction('rtti_animaliterator_getnextanimal'); - FRTTIZoo_IteratorFunc := LoadFunction('rtti_zoo_iterator'); - FRTTIGetVersionFunc := LoadFunction('rtti_getversion'); - FRTTIGetLastErrorFunc := LoadFunction('rtti_getlasterror'); - FRTTIReleaseInstanceFunc := LoadFunction('rtti_releaseinstance'); - FRTTIAcquireInstanceFunc := LoadFunction('rtti_acquireinstance'); - FRTTIInjectComponentFunc := LoadFunction('rtti_injectcomponent'); - FRTTIGetSymbolLookupMethodFunc := LoadFunction('rtti_getsymbollookupmethod'); - FRTTICreateZooFunc := LoadFunction('rtti_createzoo'); - - checkBinaryVersion(); - end; - - constructor TRTTIWrapper.CreateFromSymbolLookupMethod(ALookupMethod: TRTTISymbolLookupMethod); - var - AResult : TRTTIResult; - begin - inherited Create; - - - AResult := ALookupMethod(PAnsiChar('rtti_base_classtypeid'), @FRTTIBase_ClassTypeIdFunc); - if AResult <> RTTI_SUCCESS then - raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); - AResult := ALookupMethod(PAnsiChar('rtti_animal_name'), @FRTTIAnimal_NameFunc); - if AResult <> RTTI_SUCCESS then - raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); - AResult := ALookupMethod(PAnsiChar('rtti_tiger_roar'), @FRTTITiger_RoarFunc); - if AResult <> RTTI_SUCCESS then - raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); - AResult := ALookupMethod(PAnsiChar('rtti_animaliterator_getnextanimal'), @FRTTIAnimalIterator_GetNextAnimalFunc); - if AResult <> RTTI_SUCCESS then - raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); - AResult := ALookupMethod(PAnsiChar('rtti_zoo_iterator'), @FRTTIZoo_IteratorFunc); - if AResult <> RTTI_SUCCESS then - raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); - AResult := ALookupMethod(PAnsiChar('rtti_getversion'), @FRTTIGetVersionFunc); - if AResult <> RTTI_SUCCESS then - raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); - AResult := ALookupMethod(PAnsiChar('rtti_getlasterror'), @FRTTIGetLastErrorFunc); - if AResult <> RTTI_SUCCESS then - raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); - AResult := ALookupMethod(PAnsiChar('rtti_releaseinstance'), @FRTTIReleaseInstanceFunc); - if AResult <> RTTI_SUCCESS then - raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); - AResult := ALookupMethod(PAnsiChar('rtti_acquireinstance'), @FRTTIAcquireInstanceFunc); - if AResult <> RTTI_SUCCESS then - raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); - AResult := ALookupMethod(PAnsiChar('rtti_injectcomponent'), @FRTTIInjectComponentFunc); - if AResult <> RTTI_SUCCESS then - raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); - AResult := ALookupMethod(PAnsiChar('rtti_getsymbollookupmethod'), @FRTTIGetSymbolLookupMethodFunc); - if AResult <> RTTI_SUCCESS then - raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); - AResult := ALookupMethod(PAnsiChar('rtti_createzoo'), @FRTTICreateZooFunc); - if AResult <> RTTI_SUCCESS then - raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); - - checkBinaryVersion(); - end; - - destructor TRTTIWrapper.Destroy; - begin - {$IFDEF MSWINDOWS} - if FModule <> 0 then - FreeLibrary(FModule); - {$ELSE} - if FModule <> 0 then - UnloadLibrary(FModule); - {$ENDIF MSWINDOWS} - inherited; - end; - - procedure TRTTIWrapper.CheckError(AInstance: TRTTIBase; AErrorCode: TRTTIResult); - var - AErrorMessage: String; - begin - if AInstance <> nil then begin - if AInstance.FWrapper <> Self then - raise ERTTIException.CreateCustomMessage(RTTI_ERROR_INVALIDCAST, 'invalid wrapper call'); - end; - if AErrorCode <> RTTI_SUCCESS then begin - AErrorMessage := ''; - if Assigned(AInstance) then - GetLastError(AInstance, AErrorMessage); - raise ERTTIException.Create(AErrorCode, AErrorMessage); - end; - end; - - {$IFDEF MSWINDOWS} - function TRTTIWrapper.LoadFunction(AFunctionName: AnsiString; FailIfNotExistent: Boolean): FARPROC; - begin - Result := GetProcAddress(FModule, PAnsiChar(AFunctionName)); - if FailIfNotExistent and not Assigned(Result) then - raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT, 'could not find function ' + AFunctionName); - end; - {$ELSE} - function TRTTIWrapper.LoadFunction(AFunctionName: AnsiString; FailIfNotExistent: Boolean): Pointer; - begin - Result := dynlibs.GetProcAddress(FModule, AFunctionName); - if FailIfNotExistent and not Assigned(Result) then - raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT, 'could not find function ' + AFunctionName); - end; - {$ENDIF MSWINDOWS} - - procedure TRTTIWrapper.checkBinaryVersion(); - var - AMajor, AMinor, AMicro: Cardinal; - begin - GetVersion(AMajor, AMinor, AMicro); - if (AMajor <> RTTI_VERSION_MAJOR) then - raise ERTTIException.Create(RTTI_ERROR_INCOMPATIBLEBINARYVERSION, ''); - end; - - procedure TRTTIWrapper.GetVersion(out AMajor: Cardinal; out AMinor: Cardinal; out AMicro: Cardinal); - begin - CheckError(nil, RTTIGetVersionFunc(AMajor, AMinor, AMicro)); - end; - - function TRTTIWrapper.GetLastError(const AInstance: TRTTIBase; out AErrorMessage: String): Boolean; - var - AInstanceHandle: TRTTIHandle; - bytesNeededErrorMessage: Cardinal; - bytesWrittenErrorMessage: Cardinal; - bufferErrorMessage: array of Char; - ResultHasError: Byte; - begin - if Assigned(AInstance) then - AInstanceHandle := AInstance.TheHandle - else - raise ERTTIException.CreateCustomMessage(RTTI_ERROR_INVALIDPARAM, 'AInstance is a nil value.'); - bytesNeededErrorMessage:= 0; - bytesWrittenErrorMessage:= 0; - ResultHasError := 0; - CheckError(nil, RTTIGetLastErrorFunc(AInstanceHandle, 0, bytesNeededErrorMessage, nil, ResultHasError)); - SetLength(bufferErrorMessage, bytesNeededErrorMessage); - CheckError(nil, RTTIGetLastErrorFunc(AInstanceHandle, bytesNeededErrorMessage, bytesWrittenErrorMessage, @bufferErrorMessage[0], ResultHasError)); - AErrorMessage := StrPas(@bufferErrorMessage[0]); - Result := (ResultHasError <> 0); - end; - - procedure TRTTIWrapper.ReleaseInstance(const AInstance: TRTTIBase); - var - AInstanceHandle: TRTTIHandle; - begin - if Assigned(AInstance) then - AInstanceHandle := AInstance.TheHandle - else - raise ERTTIException.CreateCustomMessage(RTTI_ERROR_INVALIDPARAM, 'AInstance is a nil value.'); - CheckError(nil, RTTIReleaseInstanceFunc(AInstanceHandle)); - end; - - procedure TRTTIWrapper.AcquireInstance(const AInstance: TRTTIBase); - var - AInstanceHandle: TRTTIHandle; - begin - if Assigned(AInstance) then - AInstanceHandle := AInstance.TheHandle - else - raise ERTTIException.CreateCustomMessage(RTTI_ERROR_INVALIDPARAM, 'AInstance is a nil value.'); - CheckError(nil, RTTIAcquireInstanceFunc(AInstanceHandle)); - end; - - procedure TRTTIWrapper.InjectComponent(const ANameSpace: String; const ASymbolAddressMethod: Pointer); - begin - CheckError(nil, RTTIInjectComponentFunc(PAnsiChar(ANameSpace), ASymbolAddressMethod)); - end; - - function TRTTIWrapper.GetSymbolLookupMethod(): Pointer; - begin - CheckError(nil, RTTIGetSymbolLookupMethodFunc(Result)); - end; - - function TRTTIWrapper.CreateZoo(): TRTTIZoo; - var - HInstance: TRTTIHandle; - begin - Result := nil; - HInstance := nil; - CheckError(nil, RTTICreateZooFunc(HInstance)); - if Assigned(HInstance) then - Result := TPolymorphicFactory<TRTTIZoo, TRTTIZoo>.Make(Self, HInstance); - end; + constructor TRTTIWrapper.Create(ADLLName: String); + {$IFDEF MSWINDOWS} + var + AWideString: WideString; + {$ENDIF MSWINDOWS} + begin + inherited Create; + + + {$IFDEF MSWINDOWS} + AWideString := UTF8Decode(ADLLName + #0); + FModule := LoadLibraryW(PWideChar(AWideString)); + {$ELSE} + FModule := dynlibs.LoadLibrary(ADLLName); + {$ENDIF MSWINDOWS} + if FModule = 0 then + raise ERTTIException.Create(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + + FRTTIBase_ClassTypeIdFunc := LoadFunction('rtti_base_classtypeid'); + FRTTIAnimal_NameFunc := LoadFunction('rtti_animal_name'); + FRTTITiger_RoarFunc := LoadFunction('rtti_tiger_roar'); + FRTTIAnimalIterator_GetNextAnimalFunc := LoadFunction('rtti_animaliterator_getnextanimal'); + FRTTIZoo_IteratorFunc := LoadFunction('rtti_zoo_iterator'); + FRTTIGetVersionFunc := LoadFunction('rtti_getversion'); + FRTTIGetLastErrorFunc := LoadFunction('rtti_getlasterror'); + FRTTIReleaseInstanceFunc := LoadFunction('rtti_releaseinstance'); + FRTTIAcquireInstanceFunc := LoadFunction('rtti_acquireinstance'); + FRTTIInjectComponentFunc := LoadFunction('rtti_injectcomponent'); + FRTTIGetSymbolLookupMethodFunc := LoadFunction('rtti_getsymbollookupmethod'); + FRTTICreateZooFunc := LoadFunction('rtti_createzoo'); + + checkBinaryVersion(); + end; + + constructor TRTTIWrapper.CreateFromSymbolLookupMethod(ALookupMethod: TRTTISymbolLookupMethod); + var + AResult : TRTTIResult; + begin + inherited Create; + + + AResult := ALookupMethod(PAnsiChar('rtti_base_classtypeid'), @FRTTIBase_ClassTypeIdFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_animal_name'), @FRTTIAnimal_NameFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_tiger_roar'), @FRTTITiger_RoarFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_animaliterator_getnextanimal'), @FRTTIAnimalIterator_GetNextAnimalFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_zoo_iterator'), @FRTTIZoo_IteratorFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_getversion'), @FRTTIGetVersionFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_getlasterror'), @FRTTIGetLastErrorFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_releaseinstance'), @FRTTIReleaseInstanceFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_acquireinstance'), @FRTTIAcquireInstanceFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_injectcomponent'), @FRTTIInjectComponentFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_getsymbollookupmethod'), @FRTTIGetSymbolLookupMethodFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_createzoo'), @FRTTICreateZooFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + + checkBinaryVersion(); + end; + + destructor TRTTIWrapper.Destroy; + begin + {$IFDEF MSWINDOWS} + if FModule <> 0 then + FreeLibrary(FModule); + {$ELSE} + if FModule <> 0 then + UnloadLibrary(FModule); + {$ENDIF MSWINDOWS} + inherited; + end; + + procedure TRTTIWrapper.CheckError(AInstance: TRTTIBase; AErrorCode: TRTTIResult); + var + AErrorMessage: String; + begin + if AInstance <> nil then begin + if AInstance.FWrapper <> Self then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_INVALIDCAST, 'invalid wrapper call'); + end; + if AErrorCode <> RTTI_SUCCESS then begin + AErrorMessage := ''; + if Assigned(AInstance) then + GetLastError(AInstance, AErrorMessage); + raise ERTTIException.Create(AErrorCode, AErrorMessage); + end; + end; + + {$IFDEF MSWINDOWS} + function TRTTIWrapper.LoadFunction(AFunctionName: AnsiString; FailIfNotExistent: Boolean): FARPROC; + begin + Result := GetProcAddress(FModule, PAnsiChar(AFunctionName)); + if FailIfNotExistent and not Assigned(Result) then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT, 'could not find function ' + AFunctionName); + end; + {$ELSE} + function TRTTIWrapper.LoadFunction(AFunctionName: AnsiString; FailIfNotExistent: Boolean): Pointer; + begin + Result := dynlibs.GetProcAddress(FModule, AFunctionName); + if FailIfNotExistent and not Assigned(Result) then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT, 'could not find function ' + AFunctionName); + end; + {$ENDIF MSWINDOWS} + + procedure TRTTIWrapper.checkBinaryVersion(); + var + AMajor, AMinor, AMicro: Cardinal; + begin + GetVersion(AMajor, AMinor, AMicro); + if (AMajor <> RTTI_VERSION_MAJOR) then + raise ERTTIException.Create(RTTI_ERROR_INCOMPATIBLEBINARYVERSION, ''); + end; + + procedure TRTTIWrapper.GetVersion(out AMajor: Cardinal; out AMinor: Cardinal; out AMicro: Cardinal); + begin + CheckError(nil, RTTIGetVersionFunc(AMajor, AMinor, AMicro)); + end; + + function TRTTIWrapper.GetLastError(const AInstance: TRTTIBase; out AErrorMessage: String): Boolean; + var + AInstanceHandle: TRTTIHandle; + bytesNeededErrorMessage: Cardinal; + bytesWrittenErrorMessage: Cardinal; + bufferErrorMessage: array of Char; + ResultHasError: Byte; + begin + if Assigned(AInstance) then + AInstanceHandle := AInstance.TheHandle + else + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_INVALIDPARAM, 'AInstance is a nil value.'); + bytesNeededErrorMessage:= 0; + bytesWrittenErrorMessage:= 0; + ResultHasError := 0; + CheckError(nil, RTTIGetLastErrorFunc(AInstanceHandle, 0, bytesNeededErrorMessage, nil, ResultHasError)); + SetLength(bufferErrorMessage, bytesNeededErrorMessage); + CheckError(nil, RTTIGetLastErrorFunc(AInstanceHandle, bytesNeededErrorMessage, bytesWrittenErrorMessage, @bufferErrorMessage[0], ResultHasError)); + AErrorMessage := StrPas(@bufferErrorMessage[0]); + Result := (ResultHasError <> 0); + end; + + procedure TRTTIWrapper.ReleaseInstance(const AInstance: TRTTIBase); + var + AInstanceHandle: TRTTIHandle; + begin + if Assigned(AInstance) then + AInstanceHandle := AInstance.TheHandle + else + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_INVALIDPARAM, 'AInstance is a nil value.'); + CheckError(nil, RTTIReleaseInstanceFunc(AInstanceHandle)); + end; + + procedure TRTTIWrapper.AcquireInstance(const AInstance: TRTTIBase); + var + AInstanceHandle: TRTTIHandle; + begin + if Assigned(AInstance) then + AInstanceHandle := AInstance.TheHandle + else + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_INVALIDPARAM, 'AInstance is a nil value.'); + CheckError(nil, RTTIAcquireInstanceFunc(AInstanceHandle)); + end; + + procedure TRTTIWrapper.InjectComponent(const ANameSpace: String; const ASymbolAddressMethod: Pointer); + begin + CheckError(nil, RTTIInjectComponentFunc(PAnsiChar(ANameSpace), ASymbolAddressMethod)); + end; + + function TRTTIWrapper.GetSymbolLookupMethod(): Pointer; + begin + CheckError(nil, RTTIGetSymbolLookupMethodFunc(Result)); + end; + + function TRTTIWrapper.CreateZoo(): TRTTIZoo; + var + HInstance: TRTTIHandle; + begin + Result := nil; + HInstance := nil; + CheckError(nil, RTTICreateZooFunc(HInstance)); + if Assigned(HInstance) then + Result := TRTTIPolymorphicFactory<TRTTIZoo, TRTTIZoo>.Make(Self, HInstance); + end; end. diff --git a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py index 1d0d6215..6129b058 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py +++ b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py @@ -309,6 +309,12 @@ def CreateZoo(self): return InstanceObject + '''IMPORTANT: PolymorphicFactory method should not be used by application directly. + It's designed to be used on RTTIHandle object only once. + If it's used on any existing object as a form of dynamic cast then + Wrapper.AcquireInstance(object) must be called after instantiating new object. + This is important to keep reference count matching between application and library sides. + ''' def _polymorphicFactory(self, handle): class PolymorphicFactory(): def getObjectById(self, classtypeid, handle, wrapper): @@ -336,6 +342,8 @@ def getObjectById_F1917FE6BBE77831(self, handle, wrapper): # First 64 bits of SH def getObjectById_2262ABE80A5E7878(self, handle, wrapper): # First 64 bits of SHA1 of a string: "RTTI::Zoo" return Zoo(handle, wrapper) + if not handle: + return None pClassTypeId = ctypes.c_uint64() self.checkError(None, self.lib.rtti_base_classtypeid(handle, pClassTypeId)) factory = PolymorphicFactory() From d225dccd2c8b75c619d301035f81393be0f8f665 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 18:05:11 -0700 Subject: [PATCH 087/143] Ignore empty examples --- Examples/Injection/Numbers_component/Examples/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 Examples/Injection/Numbers_component/Examples/.gitignore diff --git a/Examples/Injection/Numbers_component/Examples/.gitignore b/Examples/Injection/Numbers_component/Examples/.gitignore new file mode 100644 index 00000000..945c9b46 --- /dev/null +++ b/Examples/Injection/Numbers_component/Examples/.gitignore @@ -0,0 +1 @@ +. \ No newline at end of file From 05f03040f921471acb7d564f6fb0abb6fd8720cf Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 18:06:38 -0700 Subject: [PATCH 088/143] Ignore empty examples --- Examples/Injection/Numbers_component/Examples/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/Injection/Numbers_component/Examples/.gitignore b/Examples/Injection/Numbers_component/Examples/.gitignore index 945c9b46..f59ec20a 100644 --- a/Examples/Injection/Numbers_component/Examples/.gitignore +++ b/Examples/Injection/Numbers_component/Examples/.gitignore @@ -1 +1 @@ -. \ No newline at end of file +* \ No newline at end of file From 9cef0c5ab08a1357c3e51b66b3adb67079558a0b Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 18:06:54 -0700 Subject: [PATCH 089/143] Update Injection example --- .../Bindings/Cpp/calculation_abi.hpp | 15 +- .../Bindings/Cpp/calculation_implicit.hpp | 189 ++++++++++++---- .../Bindings/Cpp/calculation_types.hpp | 37 +++- .../Bindings/CppDynamic/calculation_dynamic.h | 12 +- .../CppDynamic/calculation_dynamic.hpp | 209 ++++++++++++++---- .../Bindings/CppDynamic/calculation_types.hpp | 37 +++- .../Bindings/Pascal/Unit_Calculation.pas | 75 +++++-- .../Bindings/Python/Calculation.py | 50 ++++- .../Cpp/Interfaces/calculation_abi.hpp | 15 +- .../calculation_interfaceexception.cpp | 4 +- .../calculation_interfaceexception.hpp | 2 +- .../Cpp/Interfaces/calculation_interfaces.hpp | 81 ++++++- .../calculation_interfacewrapper.cpp | 93 +++++--- .../Cpp/Interfaces/calculation_types.hpp | 37 +++- .../Pascal/Interfaces/calculation.lpr | 7 +- .../Interfaces/calculation_exception.pas | 2 +- .../Pascal/Interfaces/calculation_exports.pas | 66 +++++- .../Interfaces/calculation_interfaces.pas | 3 +- .../Pascal/Interfaces/calculation_types.pas | 2 +- .../Bindings/CppDynamic/numbers_dynamic.h | 12 +- .../Bindings/CppDynamic/numbers_dynamic.hpp | 188 +++++++++++++--- .../Bindings/CppDynamic/numbers_types.hpp | 37 +++- .../Bindings/Pascal/Unit_Numbers.pas | 53 ++++- .../Bindings/Python/Numbers.py | 44 +++- .../Cpp/Interfaces/numbers_abi.hpp | 183 ++++++++------- .../Interfaces/numbers_interfaceexception.cpp | 4 +- .../Interfaces/numbers_interfaceexception.hpp | 5 +- .../Cpp/Interfaces/numbers_interfaces.hpp | 85 ++++++- .../Interfaces/numbers_interfacewrapper.cpp | 75 ++++--- .../Cpp/Interfaces/numbers_types.hpp | 39 +++- .../Pascal/Interfaces/numbers.lpr | 7 +- .../Pascal/Interfaces/numbers_exception.pas | 2 +- .../Pascal/Interfaces/numbers_exports.pas | 50 ++++- .../Pascal/Interfaces/numbers_interfaces.pas | 3 +- .../Pascal/Interfaces/numbers_types.pas | 2 +- 35 files changed, 1368 insertions(+), 357 deletions(-) diff --git a/Examples/Injection/Calculation_component/Bindings/Cpp/calculation_abi.hpp b/Examples/Injection/Calculation_component/Bindings/Cpp/calculation_abi.hpp index 8bbf2b12..f782c141 100644 --- a/Examples/Injection/Calculation_component/Bindings/Cpp/calculation_abi.hpp +++ b/Examples/Injection/Calculation_component/Bindings/Cpp/calculation_abi.hpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Calculation developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of Calculation library @@ -30,12 +30,23 @@ Interface version: 1.0.0 #include "numbers_dynamic.hpp" +#ifdef __cplusplus extern "C" { +#endif /************************************************************************************************************************* Class definition for Base **************************************************************************************************************************/ +/** +* Get Class Type Id +* +* @param[in] pBase - Base instance. +* @param[out] pClassTypeId - Class type as a 64 bits integer +* @return error code or 0 (success) +*/ +CALCULATION_DECLSPEC CalculationResult calculation_base_classtypeid(Calculation_Base pBase, Calculation_uint64 * pClassTypeId); + /************************************************************************************************************************* Class definition for Calculator **************************************************************************************************************************/ @@ -152,7 +163,9 @@ CALCULATION_DECLSPEC CalculationResult calculation_injectcomponent(const char * */ CALCULATION_DECLSPEC CalculationResult calculation_getsymbollookupmethod(Calculation_pvoid * pSymbolLookupMethod); +#ifdef __cplusplus } +#endif #endif // __CALCULATION_HEADER_CPP diff --git a/Examples/Injection/Calculation_component/Bindings/Cpp/calculation_implicit.hpp b/Examples/Injection/Calculation_component/Bindings/Cpp/calculation_implicit.hpp index 8bd61216..9d671fc1 100644 --- a/Examples/Injection/Calculation_component/Bindings/Cpp/calculation_implicit.hpp +++ b/Examples/Injection/Calculation_component/Bindings/Cpp/calculation_implicit.hpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Calculation developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of Calculation library @@ -26,6 +26,7 @@ Interface version: 1.0.0 #else // _WIN32 #include <dlfcn.h> #endif // _WIN32 +#include <array> #include <string> #include <memory> #include <vector> @@ -62,6 +63,33 @@ typedef PBase PCalculationBase; typedef PCalculator PCalculationCalculator; +/************************************************************************************************************************* + classParam Definition +**************************************************************************************************************************/ + +template<class T> class classParam { +private: + const T* m_ptr; + +public: + classParam(const T* ptr) + : m_ptr (ptr) + { + } + + classParam(std::shared_ptr <T> sharedPtr) + : m_ptr (sharedPtr.get()) + { + } + + CalculationHandle GetHandle() + { + if (m_ptr != nullptr) + return m_ptr->handle(); + return nullptr; + } +}; + /************************************************************************************************************************* Class ECalculationException **************************************************************************************************************************/ @@ -75,15 +103,16 @@ class ECalculationException : public std::exception { * Error message for the Exception. */ std::string m_errorMessage; + std::string m_originalErrorMessage; public: /** * Exception Constructor. */ ECalculationException(CalculationResult errorCode, const std::string & sErrorMessage) - : m_errorMessage("Calculation Error " + std::to_string(errorCode) + " (" + sErrorMessage + ")") + : m_errorCode(errorCode), m_originalErrorMessage(sErrorMessage) { - m_errorCode = errorCode; + m_errorMessage = buildErrorMessage(); } /** @@ -102,6 +131,53 @@ class ECalculationException : public std::exception { return m_errorMessage.c_str(); } + const char* getErrorMessage() const noexcept + { + return m_originalErrorMessage.c_str(); + } + + const char* getErrorName() const noexcept + { + switch(getErrorCode()) { + case CALCULATION_SUCCESS: return "SUCCESS"; + case CALCULATION_ERROR_NOTIMPLEMENTED: return "NOTIMPLEMENTED"; + case CALCULATION_ERROR_INVALIDPARAM: return "INVALIDPARAM"; + case CALCULATION_ERROR_INVALIDCAST: return "INVALIDCAST"; + case CALCULATION_ERROR_BUFFERTOOSMALL: return "BUFFERTOOSMALL"; + case CALCULATION_ERROR_GENERICEXCEPTION: return "GENERICEXCEPTION"; + case CALCULATION_ERROR_COULDNOTLOADLIBRARY: return "COULDNOTLOADLIBRARY"; + case CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT: return "COULDNOTFINDLIBRARYEXPORT"; + case CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION: return "INCOMPATIBLEBINARYVERSION"; + } + return "UNKNOWN"; + } + + const char* getErrorDescription() const noexcept + { + switch(getErrorCode()) { + case CALCULATION_SUCCESS: return "success"; + case CALCULATION_ERROR_NOTIMPLEMENTED: return "functionality not implemented"; + case CALCULATION_ERROR_INVALIDPARAM: return "an invalid parameter was passed"; + case CALCULATION_ERROR_INVALIDCAST: return "a type cast failed"; + case CALCULATION_ERROR_BUFFERTOOSMALL: return "a provided buffer is too small"; + case CALCULATION_ERROR_GENERICEXCEPTION: return "a generic exception occurred"; + case CALCULATION_ERROR_COULDNOTLOADLIBRARY: return "the library could not be loaded"; + case CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT: return "a required exported symbol could not be found in the library"; + case CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION: return "the version of the binary interface does not match the bindings interface"; + } + return "unknown error"; + } + +private: + + std::string buildErrorMessage() const noexcept + { + std::string msg = m_originalErrorMessage; + if (msg.empty()) { + msg = getErrorDescription(); + } + return std::string("Error: ") + getErrorName() + ": " + msg; + } }; /************************************************************************************************************************* @@ -116,7 +192,7 @@ class CInputVector { public: - CInputVector( const std::vector<T>& vec) + explicit CInputVector( const std::vector<T>& vec) : m_data( vec.data() ), m_size( vec.size() ) { } @@ -164,12 +240,15 @@ class CWrapper { inline PCalculator CreateCalculator(); inline void GetVersion(Calculation_uint32 & nMajor, Calculation_uint32 & nMinor, Calculation_uint32 & nMicro); - inline bool GetLastError(CBase * pInstance, std::string & sErrorMessage); - inline void ReleaseInstance(CBase * pInstance); - inline void AcquireInstance(CBase * pInstance); + inline bool GetLastError(classParam<CBase> pInstance, std::string & sErrorMessage); + inline void ReleaseInstance(classParam<CBase> pInstance); + inline void AcquireInstance(classParam<CBase> pInstance); inline void InjectComponent(const std::string & sNameSpace, const Calculation_pvoid pSymbolAddressMethod); inline Calculation_pvoid GetSymbolLookupMethod(); + template<class U> + std::shared_ptr<U> polymorphicFactory(CalculationHandle); + private: // Injected Components Numbers::PWrapper m_pNumbersWrapper; @@ -179,7 +258,7 @@ class CWrapper { { Calculation_uint32 nMajor, nMinor, nMicro; GetVersion(nMajor, nMinor, nMicro); - if ( (nMajor != CALCULATION_VERSION_MAJOR) || (nMinor < CALCULATION_VERSION_MINOR) ) { + if (nMajor != CALCULATION_VERSION_MAJOR) { return CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION; } return CALCULATION_SUCCESS; @@ -229,14 +308,23 @@ class CBase { } /** - * CBase::GetHandle - Returns handle to instance. + * CBase::handle - Returns handle to instance. */ - CalculationHandle GetHandle() + CalculationHandle handle() const { return m_pHandle; } - + + /** + * CBase::wrapper - Returns wrapper instance. + */ + CWrapper * wrapper() const + { + return m_pWrapper; + } + friend class CWrapper; + inline Calculation_uint64 ClassTypeId(); }; /************************************************************************************************************************* @@ -253,12 +341,35 @@ class CCalculator : public CBase { { } - inline void EnlistVariable(Numbers::CVariable * pVariable); + inline void EnlistVariable(Numbers::classParam<Numbers::CVariable> pVariable); inline Numbers::PVariable GetEnlistedVariable(const Calculation_uint32 nIndex); inline void ClearVariables(); inline Numbers::PVariable Multiply(); inline Numbers::PVariable Add(); }; + +/************************************************************************************************************************* + RTTI: Polymorphic Factory implementation +**************************************************************************************************************************/ + +/** +* IMPORTANT: PolymorphicFactory method should not be used by application directly. +* It's designed to be used on CalculationHandle object only once. +* If it's used on any existing object as a form of dynamic cast then +* CWrapper::AcquireInstance(CBase object) must be called after instantiating new object. +* This is important to keep reference count matching between application and library sides. +*/ +template <class T> +std::shared_ptr<T> CWrapper::polymorphicFactory(CalculationHandle pHandle) +{ + Calculation_uint64 resultClassTypeId = 0; + CheckError(nullptr, calculation_base_classtypeid(pHandle, &resultClassTypeId)); + switch(resultClassTypeId) { + case 0x3BA5271BAB410E5DUL: return std::dynamic_pointer_cast<T>(std::make_shared<CBase>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "Calculation::Base" + case 0xB23F514353D0C606UL: return std::dynamic_pointer_cast<T>(std::make_shared<CCalculator>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "Calculation::Calculator" + } + return std::make_shared<T>(this, pHandle); +} /** * CWrapper::CreateCalculator - Creates a new Calculator instance @@ -272,7 +383,7 @@ class CCalculator : public CBase { if (!hInstance) { CheckError(nullptr,CALCULATION_ERROR_INVALIDPARAM); } - return std::make_shared<CCalculator>(this, hInstance); + return this->polymorphicFactory<CCalculator>(hInstance); } /** @@ -292,12 +403,9 @@ class CCalculator : public CBase { * @param[out] sErrorMessage - Message of the last error * @return Is there a last error to query */ - inline bool CWrapper::GetLastError(CBase * pInstance, std::string & sErrorMessage) + inline bool CWrapper::GetLastError(classParam<CBase> pInstance, std::string & sErrorMessage) { - CalculationHandle hInstance = nullptr; - if (pInstance != nullptr) { - hInstance = pInstance->GetHandle(); - }; + CalculationHandle hInstance = pInstance.GetHandle(); Calculation_uint32 bytesNeededErrorMessage = 0; Calculation_uint32 bytesWrittenErrorMessage = 0; bool resultHasError = 0; @@ -313,12 +421,9 @@ class CCalculator : public CBase { * CWrapper::ReleaseInstance - Releases shared ownership of an Instance * @param[in] pInstance - Instance Handle */ - inline void CWrapper::ReleaseInstance(CBase * pInstance) + inline void CWrapper::ReleaseInstance(classParam<CBase> pInstance) { - CalculationHandle hInstance = nullptr; - if (pInstance != nullptr) { - hInstance = pInstance->GetHandle(); - }; + CalculationHandle hInstance = pInstance.GetHandle(); CheckError(nullptr,calculation_releaseinstance(hInstance)); } @@ -326,12 +431,9 @@ class CCalculator : public CBase { * CWrapper::AcquireInstance - Acquires shared ownership of an Instance * @param[in] pInstance - Instance Handle */ - inline void CWrapper::AcquireInstance(CBase * pInstance) + inline void CWrapper::AcquireInstance(classParam<CBase> pInstance) { - CalculationHandle hInstance = nullptr; - if (pInstance != nullptr) { - hInstance = pInstance->GetHandle(); - }; + CalculationHandle hInstance = pInstance.GetHandle(); CheckError(nullptr,calculation_acquireinstance(hInstance)); } @@ -385,6 +487,18 @@ class CCalculator : public CBase { * Method definitions for class CBase */ + /** + * CBase::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + Calculation_uint64 CBase::ClassTypeId() + { + Calculation_uint64 resultClassTypeId = 0; + CheckError(calculation_base_classtypeid(m_pHandle, &resultClassTypeId)); + + return resultClassTypeId; + } + /** * Method definitions for class CCalculator */ @@ -393,12 +507,9 @@ class CCalculator : public CBase { * CCalculator::EnlistVariable - Adds a Variable to the list of Variables this calculator works on * @param[in] pVariable - The new variable in this calculator */ - void CCalculator::EnlistVariable(Numbers::CVariable * pVariable) + void CCalculator::EnlistVariable(Numbers::classParam<Numbers::CVariable> pVariable) { - NumbersHandle hVariable = nullptr; - if (pVariable != nullptr) { - hVariable = pVariable->GetHandle(); - }; + NumbersHandle hVariable = pVariable.GetHandle(); CheckError(calculation_calculator_enlistvariable(m_pHandle, hVariable)); } @@ -409,13 +520,13 @@ class CCalculator : public CBase { */ Numbers::PVariable CCalculator::GetEnlistedVariable(const Calculation_uint32 nIndex) { - CalculationHandle hVariable = nullptr; + NumbersHandle hVariable = nullptr; CheckError(calculation_calculator_getenlistedvariable(m_pHandle, nIndex, &hVariable)); if (!hVariable) { CheckError(CALCULATION_ERROR_INVALIDPARAM); } - return std::make_shared<Numbers::CVariable>(m_pWrapper->m_pNumbersWrapper.get(), hVariable); + return m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory<Numbers::CVariable>(hVariable); } /** @@ -432,13 +543,13 @@ class CCalculator : public CBase { */ Numbers::PVariable CCalculator::Multiply() { - CalculationHandle hInstance = nullptr; + NumbersHandle hInstance = nullptr; CheckError(calculation_calculator_multiply(m_pHandle, &hInstance)); if (!hInstance) { CheckError(CALCULATION_ERROR_INVALIDPARAM); } - return std::make_shared<Numbers::CVariable>(m_pWrapper->m_pNumbersWrapper.get(), hInstance); + return m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory<Numbers::CVariable>(hInstance); } /** @@ -447,13 +558,13 @@ class CCalculator : public CBase { */ Numbers::PVariable CCalculator::Add() { - CalculationHandle hInstance = nullptr; + NumbersHandle hInstance = nullptr; CheckError(calculation_calculator_add(m_pHandle, &hInstance)); if (!hInstance) { CheckError(CALCULATION_ERROR_INVALIDPARAM); } - return std::make_shared<Numbers::CVariable>(m_pWrapper->m_pNumbersWrapper.get(), hInstance); + return m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory<Numbers::CVariable>(hInstance); } } // namespace Calculation diff --git a/Examples/Injection/Calculation_component/Bindings/Cpp/calculation_types.hpp b/Examples/Injection/Calculation_component/Bindings/Cpp/calculation_types.hpp index b735e30c..1e3ccd4d 100644 --- a/Examples/Injection/Calculation_component/Bindings/Cpp/calculation_types.hpp +++ b/Examples/Injection/Calculation_component/Bindings/Cpp/calculation_types.hpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Calculation developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++-Header file with basic types in order to allow an easy use of Calculation library @@ -73,14 +73,33 @@ typedef void * Calculation_pvoid; **************************************************************************************************************************/ #define CALCULATION_SUCCESS 0 -#define CALCULATION_ERROR_NOTIMPLEMENTED 1 -#define CALCULATION_ERROR_INVALIDPARAM 2 -#define CALCULATION_ERROR_INVALIDCAST 3 -#define CALCULATION_ERROR_BUFFERTOOSMALL 4 -#define CALCULATION_ERROR_GENERICEXCEPTION 5 -#define CALCULATION_ERROR_COULDNOTLOADLIBRARY 6 -#define CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT 7 -#define CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION 8 +#define CALCULATION_ERROR_NOTIMPLEMENTED 1 /** functionality not implemented */ +#define CALCULATION_ERROR_INVALIDPARAM 2 /** an invalid parameter was passed */ +#define CALCULATION_ERROR_INVALIDCAST 3 /** a type cast failed */ +#define CALCULATION_ERROR_BUFFERTOOSMALL 4 /** a provided buffer is too small */ +#define CALCULATION_ERROR_GENERICEXCEPTION 5 /** a generic exception occurred */ +#define CALCULATION_ERROR_COULDNOTLOADLIBRARY 6 /** the library could not be loaded */ +#define CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT 7 /** a required exported symbol could not be found in the library */ +#define CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION 8 /** the version of the binary interface does not match the bindings interface */ + +/************************************************************************************************************************* + Error strings for Calculation +**************************************************************************************************************************/ + +inline const char * CALCULATION_GETERRORSTRING (CalculationResult nErrorCode) { + switch (nErrorCode) { + case CALCULATION_SUCCESS: return "no error"; + case CALCULATION_ERROR_NOTIMPLEMENTED: return "functionality not implemented"; + case CALCULATION_ERROR_INVALIDPARAM: return "an invalid parameter was passed"; + case CALCULATION_ERROR_INVALIDCAST: return "a type cast failed"; + case CALCULATION_ERROR_BUFFERTOOSMALL: return "a provided buffer is too small"; + case CALCULATION_ERROR_GENERICEXCEPTION: return "a generic exception occurred"; + case CALCULATION_ERROR_COULDNOTLOADLIBRARY: return "the library could not be loaded"; + case CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT: return "a required exported symbol could not be found in the library"; + case CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION: return "the version of the binary interface does not match the bindings interface"; + default: return "unknown error"; + } +} /************************************************************************************************************************* Declaration of handle classes diff --git a/Examples/Injection/Calculation_component/Bindings/CppDynamic/calculation_dynamic.h b/Examples/Injection/Calculation_component/Bindings/CppDynamic/calculation_dynamic.h index 43d83fe4..b369df1b 100644 --- a/Examples/Injection/Calculation_component/Bindings/CppDynamic/calculation_dynamic.h +++ b/Examples/Injection/Calculation_component/Bindings/CppDynamic/calculation_dynamic.h @@ -4,7 +4,7 @@ Copyright (C) 2019 Calculation developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of Calculation library @@ -25,6 +25,15 @@ Interface version: 1.0.0 Class definition for Base **************************************************************************************************************************/ +/** +* Get Class Type Id +* +* @param[in] pBase - Base instance. +* @param[out] pClassTypeId - Class type as a 64 bits integer +* @return error code or 0 (success) +*/ +typedef CalculationResult (*PCalculationBase_ClassTypeIdPtr) (Calculation_Base pBase, Calculation_uint64 * pClassTypeId); + /************************************************************************************************************************* Class definition for Calculator **************************************************************************************************************************/ @@ -147,6 +156,7 @@ typedef CalculationResult (*PCalculationGetSymbolLookupMethodPtr) (Calculation_p typedef struct { void * m_LibraryHandle; + PCalculationBase_ClassTypeIdPtr m_Base_ClassTypeId; PCalculationCalculator_EnlistVariablePtr m_Calculator_EnlistVariable; PCalculationCalculator_GetEnlistedVariablePtr m_Calculator_GetEnlistedVariable; PCalculationCalculator_ClearVariablesPtr m_Calculator_ClearVariables; diff --git a/Examples/Injection/Calculation_component/Bindings/CppDynamic/calculation_dynamic.hpp b/Examples/Injection/Calculation_component/Bindings/CppDynamic/calculation_dynamic.hpp index 6cdc844b..a291acf1 100644 --- a/Examples/Injection/Calculation_component/Bindings/CppDynamic/calculation_dynamic.hpp +++ b/Examples/Injection/Calculation_component/Bindings/CppDynamic/calculation_dynamic.hpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Calculation developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of Calculation library @@ -26,6 +26,7 @@ Interface version: 1.0.0 #else // _WIN32 #include <dlfcn.h> #endif // _WIN32 +#include <array> #include <string> #include <memory> #include <vector> @@ -62,6 +63,33 @@ typedef PBase PCalculationBase; typedef PCalculator PCalculationCalculator; +/************************************************************************************************************************* + classParam Definition +**************************************************************************************************************************/ + +template<class T> class classParam { +private: + const T* m_ptr; + +public: + classParam(const T* ptr) + : m_ptr (ptr) + { + } + + classParam(std::shared_ptr <T> sharedPtr) + : m_ptr (sharedPtr.get()) + { + } + + CalculationHandle GetHandle() + { + if (m_ptr != nullptr) + return m_ptr->handle(); + return nullptr; + } +}; + /************************************************************************************************************************* Class ECalculationException **************************************************************************************************************************/ @@ -75,15 +103,16 @@ class ECalculationException : public std::exception { * Error message for the Exception. */ std::string m_errorMessage; + std::string m_originalErrorMessage; public: /** * Exception Constructor. */ ECalculationException(CalculationResult errorCode, const std::string & sErrorMessage) - : m_errorMessage("Calculation Error " + std::to_string(errorCode) + " (" + sErrorMessage + ")") + : m_errorCode(errorCode), m_originalErrorMessage(sErrorMessage) { - m_errorCode = errorCode; + m_errorMessage = buildErrorMessage(); } /** @@ -102,6 +131,53 @@ class ECalculationException : public std::exception { return m_errorMessage.c_str(); } + const char* getErrorMessage() const noexcept + { + return m_originalErrorMessage.c_str(); + } + + const char* getErrorName() const noexcept + { + switch(getErrorCode()) { + case CALCULATION_SUCCESS: return "SUCCESS"; + case CALCULATION_ERROR_NOTIMPLEMENTED: return "NOTIMPLEMENTED"; + case CALCULATION_ERROR_INVALIDPARAM: return "INVALIDPARAM"; + case CALCULATION_ERROR_INVALIDCAST: return "INVALIDCAST"; + case CALCULATION_ERROR_BUFFERTOOSMALL: return "BUFFERTOOSMALL"; + case CALCULATION_ERROR_GENERICEXCEPTION: return "GENERICEXCEPTION"; + case CALCULATION_ERROR_COULDNOTLOADLIBRARY: return "COULDNOTLOADLIBRARY"; + case CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT: return "COULDNOTFINDLIBRARYEXPORT"; + case CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION: return "INCOMPATIBLEBINARYVERSION"; + } + return "UNKNOWN"; + } + + const char* getErrorDescription() const noexcept + { + switch(getErrorCode()) { + case CALCULATION_SUCCESS: return "success"; + case CALCULATION_ERROR_NOTIMPLEMENTED: return "functionality not implemented"; + case CALCULATION_ERROR_INVALIDPARAM: return "an invalid parameter was passed"; + case CALCULATION_ERROR_INVALIDCAST: return "a type cast failed"; + case CALCULATION_ERROR_BUFFERTOOSMALL: return "a provided buffer is too small"; + case CALCULATION_ERROR_GENERICEXCEPTION: return "a generic exception occurred"; + case CALCULATION_ERROR_COULDNOTLOADLIBRARY: return "the library could not be loaded"; + case CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT: return "a required exported symbol could not be found in the library"; + case CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION: return "the version of the binary interface does not match the bindings interface"; + } + return "unknown error"; + } + +private: + + std::string buildErrorMessage() const noexcept + { + std::string msg = m_originalErrorMessage; + if (msg.empty()) { + msg = getErrorDescription(); + } + return std::string("Error: ") + getErrorName() + ": " + msg; + } }; /************************************************************************************************************************* @@ -116,7 +192,7 @@ class CInputVector { public: - CInputVector( const std::vector<T>& vec) + explicit CInputVector( const std::vector<T>& vec) : m_data( vec.data() ), m_size( vec.size() ) { } @@ -148,7 +224,7 @@ using CCalculationInputVector = CInputVector<T>; class CWrapper { public: - CWrapper(void* pSymbolLookupMethod) + explicit CWrapper(void* pSymbolLookupMethod) { CheckError(nullptr, initWrapperTable(&m_WrapperTable)); CheckError(nullptr, loadWrapperTableFromSymbolLookupMethod(&m_WrapperTable, pSymbolLookupMethod)); @@ -156,7 +232,7 @@ class CWrapper { CheckError(nullptr, checkBinaryVersion()); } - CWrapper(const std::string &sFileName) + explicit CWrapper(const std::string &sFileName) { CheckError(nullptr, initWrapperTable(&m_WrapperTable)); CheckError(nullptr, loadWrapperTable(&m_WrapperTable, sFileName.c_str())); @@ -183,12 +259,15 @@ class CWrapper { inline PCalculator CreateCalculator(); inline void GetVersion(Calculation_uint32 & nMajor, Calculation_uint32 & nMinor, Calculation_uint32 & nMicro); - inline bool GetLastError(CBase * pInstance, std::string & sErrorMessage); - inline void ReleaseInstance(CBase * pInstance); - inline void AcquireInstance(CBase * pInstance); + inline bool GetLastError(classParam<CBase> pInstance, std::string & sErrorMessage); + inline void ReleaseInstance(classParam<CBase> pInstance); + inline void AcquireInstance(classParam<CBase> pInstance); inline void InjectComponent(const std::string & sNameSpace, const Calculation_pvoid pSymbolAddressMethod); inline Calculation_pvoid GetSymbolLookupMethod(); + template<class U> + std::shared_ptr<U> polymorphicFactory(CalculationHandle); + private: sCalculationDynamicWrapperTable m_WrapperTable; // Injected Components @@ -199,7 +278,7 @@ class CWrapper { { Calculation_uint32 nMajor, nMinor, nMicro; GetVersion(nMajor, nMinor, nMicro); - if ( (nMajor != CALCULATION_VERSION_MAJOR) || (nMinor < CALCULATION_VERSION_MINOR) ) { + if (nMajor != CALCULATION_VERSION_MAJOR) { return CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION; } return CALCULATION_SUCCESS; @@ -253,14 +332,23 @@ class CBase { } /** - * CBase::GetHandle - Returns handle to instance. + * CBase::handle - Returns handle to instance. */ - CalculationHandle GetHandle() + CalculationHandle handle() const { return m_pHandle; } - + + /** + * CBase::wrapper - Returns wrapper instance. + */ + CWrapper * wrapper() const + { + return m_pWrapper; + } + friend class CWrapper; + inline Calculation_uint64 ClassTypeId(); }; /************************************************************************************************************************* @@ -277,12 +365,35 @@ class CCalculator : public CBase { { } - inline void EnlistVariable(Numbers::CVariable * pVariable); + inline void EnlistVariable(Numbers::classParam<Numbers::CVariable> pVariable); inline Numbers::PVariable GetEnlistedVariable(const Calculation_uint32 nIndex); inline void ClearVariables(); inline Numbers::PVariable Multiply(); inline Numbers::PVariable Add(); }; + +/************************************************************************************************************************* + RTTI: Polymorphic Factory implementation +**************************************************************************************************************************/ + +/** +* IMPORTANT: PolymorphicFactory method should not be used by application directly. +* It's designed to be used on CalculationHandle object only once. +* If it's used on any existing object as a form of dynamic cast then +* CWrapper::AcquireInstance(CBase object) must be called after instantiating new object. +* This is important to keep reference count matching between application and library sides. +*/ +template <class T> +std::shared_ptr<T> CWrapper::polymorphicFactory(CalculationHandle pHandle) +{ + Calculation_uint64 resultClassTypeId = 0; + CheckError(nullptr, m_WrapperTable.m_Base_ClassTypeId(pHandle, &resultClassTypeId)); + switch(resultClassTypeId) { + case 0x3BA5271BAB410E5DUL: return std::dynamic_pointer_cast<T>(std::make_shared<CBase>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "Calculation::Base" + case 0xB23F514353D0C606UL: return std::dynamic_pointer_cast<T>(std::make_shared<CCalculator>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "Calculation::Calculator" + } + return std::make_shared<T>(this, pHandle); +} /** * CWrapper::CreateCalculator - Creates a new Calculator instance @@ -296,7 +407,7 @@ class CCalculator : public CBase { if (!hInstance) { CheckError(nullptr,CALCULATION_ERROR_INVALIDPARAM); } - return std::make_shared<CCalculator>(this, hInstance); + return this->polymorphicFactory<CCalculator>(hInstance); } /** @@ -316,12 +427,9 @@ class CCalculator : public CBase { * @param[out] sErrorMessage - Message of the last error * @return Is there a last error to query */ - inline bool CWrapper::GetLastError(CBase * pInstance, std::string & sErrorMessage) + inline bool CWrapper::GetLastError(classParam<CBase> pInstance, std::string & sErrorMessage) { - CalculationHandle hInstance = nullptr; - if (pInstance != nullptr) { - hInstance = pInstance->GetHandle(); - }; + CalculationHandle hInstance = pInstance.GetHandle(); Calculation_uint32 bytesNeededErrorMessage = 0; Calculation_uint32 bytesWrittenErrorMessage = 0; bool resultHasError = 0; @@ -337,12 +445,9 @@ class CCalculator : public CBase { * CWrapper::ReleaseInstance - Releases shared ownership of an Instance * @param[in] pInstance - Instance Handle */ - inline void CWrapper::ReleaseInstance(CBase * pInstance) + inline void CWrapper::ReleaseInstance(classParam<CBase> pInstance) { - CalculationHandle hInstance = nullptr; - if (pInstance != nullptr) { - hInstance = pInstance->GetHandle(); - }; + CalculationHandle hInstance = pInstance.GetHandle(); CheckError(nullptr,m_WrapperTable.m_ReleaseInstance(hInstance)); } @@ -350,12 +455,9 @@ class CCalculator : public CBase { * CWrapper::AcquireInstance - Acquires shared ownership of an Instance * @param[in] pInstance - Instance Handle */ - inline void CWrapper::AcquireInstance(CBase * pInstance) + inline void CWrapper::AcquireInstance(classParam<CBase> pInstance) { - CalculationHandle hInstance = nullptr; - if (pInstance != nullptr) { - hInstance = pInstance->GetHandle(); - }; + CalculationHandle hInstance = pInstance.GetHandle(); CheckError(nullptr,m_WrapperTable.m_AcquireInstance(hInstance)); } @@ -410,6 +512,7 @@ class CCalculator : public CBase { return CALCULATION_ERROR_INVALIDPARAM; pWrapperTable->m_LibraryHandle = nullptr; + pWrapperTable->m_Base_ClassTypeId = nullptr; pWrapperTable->m_Calculator_EnlistVariable = nullptr; pWrapperTable->m_Calculator_GetEnlistedVariable = nullptr; pWrapperTable->m_Calculator_ClearVariables = nullptr; @@ -453,7 +556,7 @@ class CCalculator : public CBase { #ifdef _WIN32 // Convert filename to UTF16-string - int nLength = (int)strlen(pLibraryFileName); + int nLength = static_cast<int>(strnlen_s(pLibraryFileName, MAX_PATH)); int nBufferSize = nLength * 2 + 2; std::vector<wchar_t> wsLibraryFileName(nBufferSize); int nResult = MultiByteToWideChar(CP_UTF8, 0, pLibraryFileName, nLength, &wsLibraryFileName[0], nBufferSize); @@ -470,6 +573,15 @@ class CCalculator : public CBase { dlerror(); #endif // _WIN32 + #ifdef _WIN32 + pWrapperTable->m_Base_ClassTypeId = (PCalculationBase_ClassTypeIdPtr) GetProcAddress(hLibrary, "calculation_base_classtypeid"); + #else // _WIN32 + pWrapperTable->m_Base_ClassTypeId = (PCalculationBase_ClassTypeIdPtr) dlsym(hLibrary, "calculation_base_classtypeid"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_Base_ClassTypeId == nullptr) + return CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 pWrapperTable->m_Calculator_EnlistVariable = (PCalculationCalculator_EnlistVariablePtr) GetProcAddress(hLibrary, "calculation_calculator_enlistvariable"); #else // _WIN32 @@ -594,6 +706,10 @@ class CCalculator : public CBase { SymbolLookupType pLookup = (SymbolLookupType)pSymbolLookupMethod; CalculationResult eLookupError = CALCULATION_SUCCESS; + eLookupError = (*pLookup)("calculation_base_classtypeid", (void**)&(pWrapperTable->m_Base_ClassTypeId)); + if ( (eLookupError != 0) || (pWrapperTable->m_Base_ClassTypeId == nullptr) ) + return CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT; + eLookupError = (*pLookup)("calculation_calculator_enlistvariable", (void**)&(pWrapperTable->m_Calculator_EnlistVariable)); if ( (eLookupError != 0) || (pWrapperTable->m_Calculator_EnlistVariable == nullptr) ) return CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT; @@ -651,6 +767,18 @@ class CCalculator : public CBase { * Method definitions for class CBase */ + /** + * CBase::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + Calculation_uint64 CBase::ClassTypeId() + { + Calculation_uint64 resultClassTypeId = 0; + CheckError(m_pWrapper->m_WrapperTable.m_Base_ClassTypeId(m_pHandle, &resultClassTypeId)); + + return resultClassTypeId; + } + /** * Method definitions for class CCalculator */ @@ -659,12 +787,9 @@ class CCalculator : public CBase { * CCalculator::EnlistVariable - Adds a Variable to the list of Variables this calculator works on * @param[in] pVariable - The new variable in this calculator */ - void CCalculator::EnlistVariable(Numbers::CVariable * pVariable) + void CCalculator::EnlistVariable(Numbers::classParam<Numbers::CVariable> pVariable) { - NumbersHandle hVariable = nullptr; - if (pVariable != nullptr) { - hVariable = pVariable->GetHandle(); - }; + NumbersHandle hVariable = pVariable.GetHandle(); CheckError(m_pWrapper->m_WrapperTable.m_Calculator_EnlistVariable(m_pHandle, hVariable)); } @@ -675,13 +800,13 @@ class CCalculator : public CBase { */ Numbers::PVariable CCalculator::GetEnlistedVariable(const Calculation_uint32 nIndex) { - CalculationHandle hVariable = nullptr; + NumbersHandle hVariable = nullptr; CheckError(m_pWrapper->m_WrapperTable.m_Calculator_GetEnlistedVariable(m_pHandle, nIndex, &hVariable)); if (!hVariable) { CheckError(CALCULATION_ERROR_INVALIDPARAM); } - return std::make_shared<Numbers::CVariable>(m_pWrapper->m_pNumbersWrapper.get(), hVariable); + return m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory<Numbers::CVariable>(hVariable); } /** @@ -698,13 +823,13 @@ class CCalculator : public CBase { */ Numbers::PVariable CCalculator::Multiply() { - CalculationHandle hInstance = nullptr; + NumbersHandle hInstance = nullptr; CheckError(m_pWrapper->m_WrapperTable.m_Calculator_Multiply(m_pHandle, &hInstance)); if (!hInstance) { CheckError(CALCULATION_ERROR_INVALIDPARAM); } - return std::make_shared<Numbers::CVariable>(m_pWrapper->m_pNumbersWrapper.get(), hInstance); + return m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory<Numbers::CVariable>(hInstance); } /** @@ -713,13 +838,13 @@ class CCalculator : public CBase { */ Numbers::PVariable CCalculator::Add() { - CalculationHandle hInstance = nullptr; + NumbersHandle hInstance = nullptr; CheckError(m_pWrapper->m_WrapperTable.m_Calculator_Add(m_pHandle, &hInstance)); if (!hInstance) { CheckError(CALCULATION_ERROR_INVALIDPARAM); } - return std::make_shared<Numbers::CVariable>(m_pWrapper->m_pNumbersWrapper.get(), hInstance); + return m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory<Numbers::CVariable>(hInstance); } } // namespace Calculation diff --git a/Examples/Injection/Calculation_component/Bindings/CppDynamic/calculation_types.hpp b/Examples/Injection/Calculation_component/Bindings/CppDynamic/calculation_types.hpp index b735e30c..1e3ccd4d 100644 --- a/Examples/Injection/Calculation_component/Bindings/CppDynamic/calculation_types.hpp +++ b/Examples/Injection/Calculation_component/Bindings/CppDynamic/calculation_types.hpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Calculation developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++-Header file with basic types in order to allow an easy use of Calculation library @@ -73,14 +73,33 @@ typedef void * Calculation_pvoid; **************************************************************************************************************************/ #define CALCULATION_SUCCESS 0 -#define CALCULATION_ERROR_NOTIMPLEMENTED 1 -#define CALCULATION_ERROR_INVALIDPARAM 2 -#define CALCULATION_ERROR_INVALIDCAST 3 -#define CALCULATION_ERROR_BUFFERTOOSMALL 4 -#define CALCULATION_ERROR_GENERICEXCEPTION 5 -#define CALCULATION_ERROR_COULDNOTLOADLIBRARY 6 -#define CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT 7 -#define CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION 8 +#define CALCULATION_ERROR_NOTIMPLEMENTED 1 /** functionality not implemented */ +#define CALCULATION_ERROR_INVALIDPARAM 2 /** an invalid parameter was passed */ +#define CALCULATION_ERROR_INVALIDCAST 3 /** a type cast failed */ +#define CALCULATION_ERROR_BUFFERTOOSMALL 4 /** a provided buffer is too small */ +#define CALCULATION_ERROR_GENERICEXCEPTION 5 /** a generic exception occurred */ +#define CALCULATION_ERROR_COULDNOTLOADLIBRARY 6 /** the library could not be loaded */ +#define CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT 7 /** a required exported symbol could not be found in the library */ +#define CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION 8 /** the version of the binary interface does not match the bindings interface */ + +/************************************************************************************************************************* + Error strings for Calculation +**************************************************************************************************************************/ + +inline const char * CALCULATION_GETERRORSTRING (CalculationResult nErrorCode) { + switch (nErrorCode) { + case CALCULATION_SUCCESS: return "no error"; + case CALCULATION_ERROR_NOTIMPLEMENTED: return "functionality not implemented"; + case CALCULATION_ERROR_INVALIDPARAM: return "an invalid parameter was passed"; + case CALCULATION_ERROR_INVALIDCAST: return "a type cast failed"; + case CALCULATION_ERROR_BUFFERTOOSMALL: return "a provided buffer is too small"; + case CALCULATION_ERROR_GENERICEXCEPTION: return "a generic exception occurred"; + case CALCULATION_ERROR_COULDNOTLOADLIBRARY: return "the library could not be loaded"; + case CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT: return "a required exported symbol could not be found in the library"; + case CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION: return "the version of the binary interface does not match the bindings interface"; + default: return "unknown error"; + } +} /************************************************************************************************************************* Declaration of handle classes diff --git a/Examples/Injection/Calculation_component/Bindings/Pascal/Unit_Calculation.pas b/Examples/Injection/Calculation_component/Bindings/Pascal/Unit_Calculation.pas index e4db83b1..af3fcd35 100644 --- a/Examples/Injection/Calculation_component/Bindings/Pascal/Unit_Calculation.pas +++ b/Examples/Injection/Calculation_component/Bindings/Pascal/Unit_Calculation.pas @@ -5,7 +5,7 @@ All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated Pascal Header file in order to allow an easy use of Calculation library @@ -82,6 +82,15 @@ TCalculationCalculator = class; Function type definitions for Base **************************************************************************************************************************) + (** + * Get Class Type Id + * + * @param[in] pBase - Base instance. + * @param[out] pClassTypeId - Class type as a 64 bits integer + * @return error code or 0 (success) + *) + TCalculationBase_ClassTypeIdFunc = function(pBase: TCalculationHandle; out pClassTypeId: QWord): TCalculationResult; cdecl; + (************************************************************************************************************************* Function type definitions for Calculator @@ -94,7 +103,7 @@ TCalculationCalculator = class; * @param[in] pVariable - The new variable in this calculator * @return error code or 0 (success) *) - TCalculationCalculator_EnlistVariableFunc = function(pCalculator: TCalculationHandle; const pVariable: TCalculationHandle): TCalculationResult; cdecl; + TCalculationCalculator_EnlistVariableFunc = function(pCalculator: TCalculationHandle; const pVariable: TNumbersHandle): TCalculationResult; cdecl; (** * Returns an instance of a enlisted variable @@ -104,7 +113,7 @@ TCalculationCalculator = class; * @param[out] pVariable - The Index-th variable in this calculator * @return error code or 0 (success) *) - TCalculationCalculator_GetEnlistedVariableFunc = function(pCalculator: TCalculationHandle; const nIndex: Cardinal; out pVariable: TCalculationHandle): TCalculationResult; cdecl; + TCalculationCalculator_GetEnlistedVariableFunc = function(pCalculator: TCalculationHandle; const nIndex: Cardinal; out pVariable: TNumbersHandle): TCalculationResult; cdecl; (** * Clears all variables in enlisted in this calculator @@ -121,7 +130,7 @@ TCalculationCalculator = class; * @param[out] pInstance - Variable that holds the product of all enlisted Variables * @return error code or 0 (success) *) - TCalculationCalculator_MultiplyFunc = function(pCalculator: TCalculationHandle; out pInstance: TCalculationHandle): TCalculationResult; cdecl; + TCalculationCalculator_MultiplyFunc = function(pCalculator: TCalculationHandle; out pInstance: TNumbersHandle): TCalculationResult; cdecl; (** * Sums all enlisted variables @@ -130,7 +139,7 @@ TCalculationCalculator = class; * @param[out] pInstance - Variable that holds the sum of all enlisted Variables * @return error code or 0 (success) *) - TCalculationCalculator_AddFunc = function(pCalculator: TCalculationHandle; out pInstance: TCalculationHandle): TCalculationResult; cdecl; + TCalculationCalculator_AddFunc = function(pCalculator: TCalculationHandle; out pInstance: TNumbersHandle): TCalculationResult; cdecl; (************************************************************************************************************************* Global function definitions @@ -233,6 +242,7 @@ TCalculationBase = class(TObject) constructor Create(AWrapper: TCalculationWrapper; AHandle: TCalculationHandle); destructor Destroy; override; property TheHandle: TCalculationHandle read FHandle; + function ClassTypeId(): QWord; end; @@ -261,6 +271,7 @@ TCalculationWrapper = class(TObject) // Imported Components FNumbersWrapper: TNumbersWrapper; + FCalculationBase_ClassTypeIdFunc: TCalculationBase_ClassTypeIdFunc; FCalculationCalculator_EnlistVariableFunc: TCalculationCalculator_EnlistVariableFunc; FCalculationCalculator_GetEnlistedVariableFunc: TCalculationCalculator_GetEnlistedVariableFunc; FCalculationCalculator_ClearVariablesFunc: TCalculationCalculator_ClearVariablesFunc; @@ -286,6 +297,7 @@ TCalculationWrapper = class(TObject) function GetNumbersWrapper(): TNumbersWrapper; protected + property CalculationBase_ClassTypeIdFunc: TCalculationBase_ClassTypeIdFunc read FCalculationBase_ClassTypeIdFunc; property CalculationCalculator_EnlistVariableFunc: TCalculationCalculator_EnlistVariableFunc read FCalculationCalculator_EnlistVariableFunc; property CalculationCalculator_GetEnlistedVariableFunc: TCalculationCalculator_GetEnlistedVariableFunc read FCalculationCalculator_GetEnlistedVariableFunc; property CalculationCalculator_ClearVariablesFunc: TCalculationCalculator_ClearVariablesFunc read FCalculationCalculator_ClearVariablesFunc; @@ -315,10 +327,38 @@ TCalculationWrapper = class(TObject) function GetSymbolLookupMethod(): Pointer; end; + TCalculationPolymorphicFactory<_T:class; _B> = record + class function Make(Wrapper: TCalculationWrapper; Handle: TCalculationHandle): _T; static; + end; implementation +(************************************************************************************************************************* + PolymorficFactory implementation +**************************************************************************************************************************) + + (** + * IMPORTANT: PolymorphicFactory method should not be used by application directly. + * It's designed to be used on CalculationHandle object only once. + * If it's used on any existing object as a form of dynamic cast then + * TCALCULATIONWrapper::AcquireInstance(object: TCALCULATIONBase) must be called after instantiating new object. + * This is important to keep reference count matching between application and library sides. + *) + class function TCalculationPolymorphicFactory<_T, _B>.Make(Wrapper: TCalculationWrapper; Handle: TCalculationHandle): _T; + var + ClassTypeId: QWord; + Obj: TCALCULATIONBase; + begin + Result := nil; + Wrapper.CheckError(nil, Wrapper.CalculationBase_ClassTypeIdFunc(handle, ClassTypeId)); + case (ClassTypeId) of + QWord($3BA5271BAB410E5D): begin Obj := TCALCULATIONBase.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "Calculation::Base" + QWord($B23F514353D0C606): begin Obj := TCALCULATIONCalculator.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "Calculation::Calculator" + end; + if Result = nil then Result := _B.Create(Wrapper, Handle); + end; + (************************************************************************************************************************* Exception implementation **************************************************************************************************************************) @@ -373,6 +413,11 @@ implementation inherited; end; + function TCalculationBase.ClassTypeId(): QWord; + begin + FWrapper.CheckError(Self, FWrapper.CalculationBase_ClassTypeIdFunc(FHandle, Result)); + end; + (************************************************************************************************************************* Class implementation for Calculator **************************************************************************************************************************) @@ -389,7 +434,7 @@ implementation procedure TCalculationCalculator.EnlistVariable(const AVariable: TNumbersVariable); var - AVariableHandle: TCalculationHandle; + AVariableHandle: TNumbersHandle; begin if Assigned(AVariable) then AVariableHandle := AVariable.TheHandle @@ -400,13 +445,13 @@ implementation function TCalculationCalculator.GetEnlistedVariable(const AIndex: Cardinal): TNumbersVariable; var - HVariable: TCalculationHandle; + HVariable: TNumbersHandle; begin Result := nil; HVariable := nil; FWrapper.CheckError(Self, FWrapper.CalculationCalculator_GetEnlistedVariableFunc(FHandle, AIndex, HVariable)); if Assigned(HVariable) then - Result := TNumbersVariable.Create(FWrapper.NumbersWrapper, HVariable); + Result := TNumbersPolymorphicFactory<TNumbersVariable, TNumbersVariable>.Make(FWrapper.NumbersWrapper, HVariable); end; procedure TCalculationCalculator.ClearVariables(); @@ -416,24 +461,24 @@ implementation function TCalculationCalculator.Multiply(): TNumbersVariable; var - HInstance: TCalculationHandle; + HInstance: TNumbersHandle; begin Result := nil; HInstance := nil; FWrapper.CheckError(Self, FWrapper.CalculationCalculator_MultiplyFunc(FHandle, HInstance)); if Assigned(HInstance) then - Result := TNumbersVariable.Create(FWrapper.NumbersWrapper, HInstance); + Result := TNumbersPolymorphicFactory<TNumbersVariable, TNumbersVariable>.Make(FWrapper.NumbersWrapper, HInstance); end; function TCalculationCalculator.Add(): TNumbersVariable; var - HInstance: TCalculationHandle; + HInstance: TNumbersHandle; begin Result := nil; HInstance := nil; FWrapper.CheckError(Self, FWrapper.CalculationCalculator_AddFunc(FHandle, HInstance)); if Assigned(HInstance) then - Result := TNumbersVariable.Create(FWrapper.NumbersWrapper, HInstance); + Result := TNumbersPolymorphicFactory<TNumbersVariable, TNumbersVariable>.Make(FWrapper.NumbersWrapper, HInstance); end; (************************************************************************************************************************* @@ -459,6 +504,7 @@ implementation if FModule = 0 then raise ECalculationException.Create(CALCULATION_ERROR_COULDNOTLOADLIBRARY, ''); + FCalculationBase_ClassTypeIdFunc := LoadFunction('calculation_base_classtypeid'); FCalculationCalculator_EnlistVariableFunc := LoadFunction('calculation_calculator_enlistvariable'); FCalculationCalculator_GetEnlistedVariableFunc := LoadFunction('calculation_calculator_getenlistedvariable'); FCalculationCalculator_ClearVariablesFunc := LoadFunction('calculation_calculator_clearvariables'); @@ -483,6 +529,9 @@ implementation FNumbersWrapper := nil; + AResult := ALookupMethod(PAnsiChar('calculation_base_classtypeid'), @FCalculationBase_ClassTypeIdFunc); + if AResult <> CALCULATION_SUCCESS then + raise ECalculationException.CreateCustomMessage(CALCULATION_ERROR_COULDNOTLOADLIBRARY, ''); AResult := ALookupMethod(PAnsiChar('calculation_calculator_enlistvariable'), @FCalculationCalculator_EnlistVariableFunc); if AResult <> CALCULATION_SUCCESS then raise ECalculationException.CreateCustomMessage(CALCULATION_ERROR_COULDNOTLOADLIBRARY, ''); @@ -592,7 +641,7 @@ implementation HInstance := nil; CheckError(nil, CalculationCreateCalculatorFunc(HInstance)); if Assigned(HInstance) then - Result := TCalculationCalculator.Create(Self, HInstance); + Result := TCalculationPolymorphicFactory<TCalculationCalculator, TCalculationCalculator>.Make(Self, HInstance); end; procedure TCalculationWrapper.GetVersion(out AMajor: Cardinal; out AMinor: Cardinal; out AMicro: Cardinal); diff --git a/Examples/Injection/Calculation_component/Bindings/Python/Calculation.py b/Examples/Injection/Calculation_component/Bindings/Python/Calculation.py index 4a720234..ade5fc28 100644 --- a/Examples/Injection/Calculation_component/Bindings/Python/Calculation.py +++ b/Examples/Injection/Calculation_component/Bindings/Python/Calculation.py @@ -4,7 +4,7 @@ All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated Python file in order to allow an easy use of Calculation library @@ -68,6 +68,7 @@ class FunctionTable: calculation_acquireinstance = None calculation_injectcomponent = None calculation_getsymbollookupmethod = None + calculation_base_classtypeid = None calculation_calculator_enlistvariable = None calculation_calculator_getenlistedvariable = None calculation_calculator_clearvariables = None @@ -161,6 +162,12 @@ def _loadFunctionTableFromMethod(self, symbolLookupMethodAddress): methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.POINTER(ctypes.c_void_p)) self.lib.calculation_getsymbollookupmethod = methodType(int(methodAddress.value)) + err = symbolLookupMethod(ctypes.c_char_p(str.encode("calculation_base_classtypeid")), methodAddress) + if err != 0: + raise ECalculationException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.POINTER(ctypes.c_uint64)) + self.lib.calculation_base_classtypeid = methodType(int(methodAddress.value)) + err = symbolLookupMethod(ctypes.c_char_p(str.encode("calculation_calculator_enlistvariable")), methodAddress) if err != 0: raise ECalculationException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) @@ -217,6 +224,9 @@ def _loadFunctionTable(self): self.lib.calculation_getsymbollookupmethod.restype = ctypes.c_int32 self.lib.calculation_getsymbollookupmethod.argtypes = [ctypes.POINTER(ctypes.c_void_p)] + self.lib.calculation_base_classtypeid.restype = ctypes.c_int32 + self.lib.calculation_base_classtypeid.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_uint64)] + self.lib.calculation_calculator_enlistvariable.restype = ctypes.c_int32 self.lib.calculation_calculator_enlistvariable.argtypes = [ctypes.c_void_p, ctypes.c_void_p] @@ -252,7 +262,7 @@ def CreateCalculator(self): InstanceHandle = ctypes.c_void_p() self.checkError(None, self.lib.calculation_createcalculator(InstanceHandle)) if InstanceHandle: - InstanceObject = Calculator(InstanceHandle, self) + InstanceObject = self._polymorphicFactory(InstanceHandle) else: raise ECalculationException(ErrorCodes.INVALIDCAST, 'Invalid return/output value') @@ -322,6 +332,30 @@ def GetSymbolLookupMethod(self): return pSymbolLookupMethod.value + '''IMPORTANT: PolymorphicFactory method should not be used by application directly. + It's designed to be used on CalculationHandle object only once. + If it's used on any existing object as a form of dynamic cast then + Wrapper.AcquireInstance(object) must be called after instantiating new object. + This is important to keep reference count matching between application and library sides. + ''' + def _polymorphicFactory(self, handle): + class PolymorphicFactory(): + def getObjectById(self, classtypeid, handle, wrapper): + methodName = 'getObjectById_' + format(classtypeid.value, '016X') + method = getattr(self, methodName, lambda: 'Invalid class type id') + return method(handle, wrapper) + def getObjectById_3BA5271BAB410E5D(self, handle, wrapper): # First 64 bits of SHA1 of a string: "Calculation::Base" + return Base(handle, wrapper) + def getObjectById_B23F514353D0C606(self, handle, wrapper): # First 64 bits of SHA1 of a string: "Calculation::Calculator" + return Calculator(handle, wrapper) + + if not handle: + return None + pClassTypeId = ctypes.c_uint64() + self.checkError(None, self.lib.calculation_base_classtypeid(handle, pClassTypeId)) + factory = PolymorphicFactory() + return factory.getObjectById(pClassTypeId, handle, self) + ''' Class Implementation for Base @@ -335,6 +369,12 @@ def __init__(self, handle, wrapper): def __del__(self): self._wrapper.ReleaseInstance(self) + def ClassTypeId(self): + pClassTypeId = ctypes.c_uint64() + self._wrapper.checkError(self, self._wrapper.lib.calculation_base_classtypeid(self._handle, pClassTypeId)) + + return pClassTypeId.value + ''' Class Implementation for Calculator @@ -356,7 +396,7 @@ def GetEnlistedVariable(self, Index): VariableHandle = ctypes.c_void_p() self._wrapper.checkError(self, self._wrapper.lib.calculation_calculator_getenlistedvariable(self._handle, nIndex, VariableHandle)) if VariableHandle: - VariableObject = Numbers.Variable(VariableHandle, self._wrapper._NumbersWrapper) + VariableObject = self._wrapper._NumbersWrapper._polymorphicFactory(VariableHandle) else: raise ECalculationException(ErrorCodes.INVALIDCAST, 'Invalid return/output value') @@ -370,7 +410,7 @@ def Multiply(self): InstanceHandle = ctypes.c_void_p() self._wrapper.checkError(self, self._wrapper.lib.calculation_calculator_multiply(self._handle, InstanceHandle)) if InstanceHandle: - InstanceObject = Numbers.Variable(InstanceHandle, self._wrapper._NumbersWrapper) + InstanceObject = self._wrapper._NumbersWrapper._polymorphicFactory(InstanceHandle) else: raise ECalculationException(ErrorCodes.INVALIDCAST, 'Invalid return/output value') @@ -380,7 +420,7 @@ def Add(self): InstanceHandle = ctypes.c_void_p() self._wrapper.checkError(self, self._wrapper.lib.calculation_calculator_add(self._handle, InstanceHandle)) if InstanceHandle: - InstanceObject = Numbers.Variable(InstanceHandle, self._wrapper._NumbersWrapper) + InstanceObject = self._wrapper._NumbersWrapper._polymorphicFactory(InstanceHandle) else: raise ECalculationException(ErrorCodes.INVALIDCAST, 'Invalid return/output value') diff --git a/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_abi.hpp b/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_abi.hpp index 8bbf2b12..f782c141 100644 --- a/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_abi.hpp +++ b/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_abi.hpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Calculation developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of Calculation library @@ -30,12 +30,23 @@ Interface version: 1.0.0 #include "numbers_dynamic.hpp" +#ifdef __cplusplus extern "C" { +#endif /************************************************************************************************************************* Class definition for Base **************************************************************************************************************************/ +/** +* Get Class Type Id +* +* @param[in] pBase - Base instance. +* @param[out] pClassTypeId - Class type as a 64 bits integer +* @return error code or 0 (success) +*/ +CALCULATION_DECLSPEC CalculationResult calculation_base_classtypeid(Calculation_Base pBase, Calculation_uint64 * pClassTypeId); + /************************************************************************************************************************* Class definition for Calculator **************************************************************************************************************************/ @@ -152,7 +163,9 @@ CALCULATION_DECLSPEC CalculationResult calculation_injectcomponent(const char * */ CALCULATION_DECLSPEC CalculationResult calculation_getsymbollookupmethod(Calculation_pvoid * pSymbolLookupMethod); +#ifdef __cplusplus } +#endif #endif // __CALCULATION_HEADER_CPP diff --git a/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfaceexception.cpp b/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfaceexception.cpp index cee550d0..c996908f 100644 --- a/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfaceexception.cpp +++ b/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfaceexception.cpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Calculation developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++ Implementation file with the basic internal exception type in order to allow an easy use of Calculation library @@ -22,7 +22,7 @@ Interface version: 1.0.0 Class ECalculationInterfaceException **************************************************************************************************************************/ ECalculationInterfaceException::ECalculationInterfaceException(CalculationResult errorCode) - : m_errorMessage("Calculation Error " + std::to_string (errorCode)) + : m_errorMessage(CALCULATION_GETERRORSTRING (errorCode)) { m_errorCode = errorCode; } diff --git a/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfaceexception.hpp b/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfaceexception.hpp index 61d2302f..98f51261 100644 --- a/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfaceexception.hpp +++ b/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfaceexception.hpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Calculation developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++ Header file with the basic internal exception type in order to allow an easy use of Calculation library diff --git a/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfaces.hpp b/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfaces.hpp index c9518542..73076d44 100644 --- a/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfaces.hpp +++ b/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfaces.hpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Calculation developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++ header file in order to allow easy development of Calculation library. The implementer of Calculation library needs to @@ -37,6 +37,67 @@ class ICalculator; +/************************************************************************************************************************* + Parameter Cache definitions +**************************************************************************************************************************/ + +class ParameterCache { + public: + virtual ~ParameterCache() {} +}; + +template <class T1> class ParameterCache_1 : public ParameterCache { + private: + T1 m_param1; + public: + ParameterCache_1 (const T1 & param1) + : m_param1 (param1) + { + } + + void retrieveData (T1 & param1) + { + param1 = m_param1; + } +}; + +template <class T1, class T2> class ParameterCache_2 : public ParameterCache { + private: + T1 m_param1; + T2 m_param2; + public: + ParameterCache_2 (const T1 & param1, const T2 & param2) + : m_param1 (param1), m_param2 (param2) + { + } + + void retrieveData (T1 & param1, T2 & param2) + { + param1 = m_param1; + param2 = m_param2; + } +}; + +template <class T1, class T2, class T3> class ParameterCache_3 : public ParameterCache { + private: + T1 m_param1; + T2 m_param2; + T3 m_param3; + public: + ParameterCache_3 (const T1 & param1, const T2 & param2, const T3 & param3) + : m_param1 (param1), m_param2 (param2), m_param3 (param3) + { + } + + void retrieveData (T1 & param1, T2 & param2, T3 & param3) + { + param1 = m_param1; + param2 = m_param2; + param3 = m_param3; + } +}; + + /************************************************************************************************************************* Class interface for Base **************************************************************************************************************************/ @@ -99,6 +160,11 @@ class IBase { * @return Has the object been released */ virtual bool DecRefCount() = 0; + /** + * IBase::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + virtual Calculation_uint64 ClassTypeId() = 0; }; @@ -140,6 +206,17 @@ typedef IBaseSharedPtr<IBase> PIBase; class ICalculator : public virtual IBase { public: + /** + * ICalculator::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + Calculation_uint64 ClassTypeId() override + { + // First 64 bits of SHA1 of a string: "Calculation::Calculator" + static const Calculation_uint64 s_CalculatorTypeId = 0xB23F514353D0C606UL; + return s_CalculatorTypeId; + } + /** * ICalculator::EnlistVariable - Adds a Variable to the list of Variables this calculator works on * @param[in] pVariable - The new variable in this calculator @@ -219,6 +296,8 @@ class CWrapper { }; +CalculationResult Calculation_GetProcAddress (const char * pProcName, void ** ppProcAddress); + } // namespace Impl } // namespace Calculation diff --git a/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfacewrapper.cpp b/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfacewrapper.cpp index 3b985cd4..5708bc33 100644 --- a/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfacewrapper.cpp +++ b/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfacewrapper.cpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Calculation developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++ implementation file in order to allow easy development of Calculation library. The functions in this file need to be implemented. It needs to be generated only once. @@ -56,6 +56,32 @@ CalculationResult handleUnhandledException(IBase * pIBaseClass) /************************************************************************************************************************* Class implementation for Base **************************************************************************************************************************/ +CalculationResult calculation_base_classtypeid(Calculation_Base pBase, Calculation_uint64 * pClassTypeId) +{ + IBase* pIBaseClass = (IBase *)pBase; + + try { + if (pClassTypeId == nullptr) + throw ECalculationInterfaceException (CALCULATION_ERROR_INVALIDPARAM); + IBase* pIBase = dynamic_cast<IBase*>(pIBaseClass); + if (!pIBase) + throw ECalculationInterfaceException(CALCULATION_ERROR_INVALIDCAST); + + *pClassTypeId = pIBase->ClassTypeId(); + + return CALCULATION_SUCCESS; + } + catch (ECalculationInterfaceException & Exception) { + return handleCalculationException(pIBaseClass, Exception); + } + catch (std::exception & StdException) { + return handleStdException(pIBaseClass, StdException); + } + catch (...) { + return handleUnhandledException(pIBaseClass); + } +} + /************************************************************************************************************************* Class implementation for Calculator @@ -104,7 +130,7 @@ CalculationResult calculation_calculator_getenlistedvariable(Calculation_Calcula pNumbersVariable = pICalculator->GetEnlistedVariable(nIndex); CWrapper::sPNumbersWrapper->AcquireInstance(pNumbersVariable.get()); - *pVariable = pNumbersVariable->GetHandle(); + *pVariable = pNumbersVariable->handle(); return CALCULATION_SUCCESS; } catch (ECalculationInterfaceException & Exception) { @@ -157,7 +183,7 @@ CalculationResult calculation_calculator_multiply(Calculation_Calculator pCalcul pNumbersInstance = pICalculator->Multiply(); CWrapper::sPNumbersWrapper->AcquireInstance(pNumbersInstance.get()); - *pInstance = pNumbersInstance->GetHandle(); + *pInstance = pNumbersInstance->handle(); return CALCULATION_SUCCESS; } catch (ECalculationInterfaceException & Exception) { @@ -186,7 +212,7 @@ CalculationResult calculation_calculator_add(Calculation_Calculator pCalculator, pNumbersInstance = pICalculator->Add(); CWrapper::sPNumbersWrapper->AcquireInstance(pNumbersInstance.get()); - *pInstance = pNumbersInstance->GetHandle(); + *pInstance = pNumbersInstance->handle(); return CALCULATION_SUCCESS; } catch (ECalculationInterfaceException & Exception) { @@ -206,26 +232,8 @@ CalculationResult calculation_calculator_add(Calculation_Calculator pCalculator, Function table lookup implementation **************************************************************************************************************************/ -CalculationResult _calculation_getprocaddress_internal(const char * pProcName, void ** ppProcAddress) +CalculationResult Calculation::Impl::Calculation_GetProcAddress (const char * pProcName, void ** ppProcAddress) { - static bool sbProcAddressMapHasBeenInitialized = false; - static std::map<std::string, void*> sProcAddressMap; - if (!sbProcAddressMapHasBeenInitialized) { - sProcAddressMap["calculation_calculator_enlistvariable"] = (void*)&calculation_calculator_enlistvariable; - sProcAddressMap["calculation_calculator_getenlistedvariable"] = (void*)&calculation_calculator_getenlistedvariable; - sProcAddressMap["calculation_calculator_clearvariables"] = (void*)&calculation_calculator_clearvariables; - sProcAddressMap["calculation_calculator_multiply"] = (void*)&calculation_calculator_multiply; - sProcAddressMap["calculation_calculator_add"] = (void*)&calculation_calculator_add; - sProcAddressMap["calculation_createcalculator"] = (void*)&calculation_createcalculator; - sProcAddressMap["calculation_getversion"] = (void*)&calculation_getversion; - sProcAddressMap["calculation_getlasterror"] = (void*)&calculation_getlasterror; - sProcAddressMap["calculation_releaseinstance"] = (void*)&calculation_releaseinstance; - sProcAddressMap["calculation_acquireinstance"] = (void*)&calculation_acquireinstance; - sProcAddressMap["calculation_injectcomponent"] = (void*)&calculation_injectcomponent; - sProcAddressMap["calculation_getsymbollookupmethod"] = (void*)&calculation_getsymbollookupmethod; - - sbProcAddressMapHasBeenInitialized = true; - } if (pProcName == nullptr) return CALCULATION_ERROR_INVALIDPARAM; if (ppProcAddress == nullptr) @@ -233,15 +241,36 @@ CalculationResult _calculation_getprocaddress_internal(const char * pProcName, v *ppProcAddress = nullptr; std::string sProcName (pProcName); - auto procPair = sProcAddressMap.find(sProcName); - if (procPair == sProcAddressMap.end()) { - return CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT; - } - else { - *ppProcAddress = procPair->second; - return CALCULATION_SUCCESS; - } + if (sProcName == "calculation_base_classtypeid") + *ppProcAddress = (void*) &calculation_base_classtypeid; + if (sProcName == "calculation_calculator_enlistvariable") + *ppProcAddress = (void*) &calculation_calculator_enlistvariable; + if (sProcName == "calculation_calculator_getenlistedvariable") + *ppProcAddress = (void*) &calculation_calculator_getenlistedvariable; + if (sProcName == "calculation_calculator_clearvariables") + *ppProcAddress = (void*) &calculation_calculator_clearvariables; + if (sProcName == "calculation_calculator_multiply") + *ppProcAddress = (void*) &calculation_calculator_multiply; + if (sProcName == "calculation_calculator_add") + *ppProcAddress = (void*) &calculation_calculator_add; + if (sProcName == "calculation_createcalculator") + *ppProcAddress = (void*) &calculation_createcalculator; + if (sProcName == "calculation_getversion") + *ppProcAddress = (void*) &calculation_getversion; + if (sProcName == "calculation_getlasterror") + *ppProcAddress = (void*) &calculation_getlasterror; + if (sProcName == "calculation_releaseinstance") + *ppProcAddress = (void*) &calculation_releaseinstance; + if (sProcName == "calculation_acquireinstance") + *ppProcAddress = (void*) &calculation_acquireinstance; + if (sProcName == "calculation_injectcomponent") + *ppProcAddress = (void*) &calculation_injectcomponent; + if (sProcName == "calculation_getsymbollookupmethod") + *ppProcAddress = (void*) &calculation_getsymbollookupmethod; + if (*ppProcAddress == nullptr) + return CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT; + return CALCULATION_SUCCESS; } /************************************************************************************************************************* @@ -428,7 +457,7 @@ CalculationResult calculation_getsymbollookupmethod(Calculation_pvoid * pSymbolL try { if (pSymbolLookupMethod == nullptr) throw ECalculationInterfaceException (CALCULATION_ERROR_INVALIDPARAM); - *pSymbolLookupMethod = (void*)&_calculation_getprocaddress_internal; + *pSymbolLookupMethod = (void*)&Calculation::Impl::Calculation_GetProcAddress; return CALCULATION_SUCCESS; } catch (ECalculationInterfaceException & Exception) { diff --git a/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_types.hpp b/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_types.hpp index b735e30c..1e3ccd4d 100644 --- a/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_types.hpp +++ b/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_types.hpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Calculation developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++-Header file with basic types in order to allow an easy use of Calculation library @@ -73,14 +73,33 @@ typedef void * Calculation_pvoid; **************************************************************************************************************************/ #define CALCULATION_SUCCESS 0 -#define CALCULATION_ERROR_NOTIMPLEMENTED 1 -#define CALCULATION_ERROR_INVALIDPARAM 2 -#define CALCULATION_ERROR_INVALIDCAST 3 -#define CALCULATION_ERROR_BUFFERTOOSMALL 4 -#define CALCULATION_ERROR_GENERICEXCEPTION 5 -#define CALCULATION_ERROR_COULDNOTLOADLIBRARY 6 -#define CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT 7 -#define CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION 8 +#define CALCULATION_ERROR_NOTIMPLEMENTED 1 /** functionality not implemented */ +#define CALCULATION_ERROR_INVALIDPARAM 2 /** an invalid parameter was passed */ +#define CALCULATION_ERROR_INVALIDCAST 3 /** a type cast failed */ +#define CALCULATION_ERROR_BUFFERTOOSMALL 4 /** a provided buffer is too small */ +#define CALCULATION_ERROR_GENERICEXCEPTION 5 /** a generic exception occurred */ +#define CALCULATION_ERROR_COULDNOTLOADLIBRARY 6 /** the library could not be loaded */ +#define CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT 7 /** a required exported symbol could not be found in the library */ +#define CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION 8 /** the version of the binary interface does not match the bindings interface */ + +/************************************************************************************************************************* + Error strings for Calculation +**************************************************************************************************************************/ + +inline const char * CALCULATION_GETERRORSTRING (CalculationResult nErrorCode) { + switch (nErrorCode) { + case CALCULATION_SUCCESS: return "no error"; + case CALCULATION_ERROR_NOTIMPLEMENTED: return "functionality not implemented"; + case CALCULATION_ERROR_INVALIDPARAM: return "an invalid parameter was passed"; + case CALCULATION_ERROR_INVALIDCAST: return "a type cast failed"; + case CALCULATION_ERROR_BUFFERTOOSMALL: return "a provided buffer is too small"; + case CALCULATION_ERROR_GENERICEXCEPTION: return "a generic exception occurred"; + case CALCULATION_ERROR_COULDNOTLOADLIBRARY: return "the library could not be loaded"; + case CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT: return "a required exported symbol could not be found in the library"; + case CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION: return "the version of the binary interface does not match the bindings interface"; + default: return "unknown error"; + } +} /************************************************************************************************************************* Declaration of handle classes diff --git a/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation.lpr b/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation.lpr index fd19d4bc..22d4598d 100644 --- a/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation.lpr +++ b/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation.lpr @@ -4,7 +4,7 @@ All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated Pascal project file in order to allow easy development of Calculation library. @@ -27,6 +27,7 @@ sysutils; exports + calculation_base_classtypeid, calculation_calculator_enlistvariable, calculation_calculator_getenlistedvariable, calculation_calculator_clearvariables, @@ -40,6 +41,10 @@ calculation_injectcomponent, calculation_getsymbollookupmethod; +{$IFDEF CALCULATION_INCLUDE_RES_FILE} +{$R *.res} +{$ENDIF CALCULATION_INCLUDE_RES_FILE} + begin end. diff --git a/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation_exception.pas b/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation_exception.pas index 9a212b69..7f845a70 100644 --- a/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation_exception.pas +++ b/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation_exception.pas @@ -4,7 +4,7 @@ All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated Pascal exception class definition file in order to allow easy development of Calculation library. The functions in this file need to be implemented. It needs to be generated only once. diff --git a/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation_exports.pas b/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation_exports.pas index 5401e45c..8f769db6 100644 --- a/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation_exports.pas +++ b/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation_exports.pas @@ -4,7 +4,7 @@ All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated Pascal export implementation file in order to allow easy development of Calculation library. The functions in this file need to be implemented. It needs to be generated only once. @@ -31,6 +31,15 @@ interface Class export definition of Base **************************************************************************************************************************) +(** +* Get Class Type Id +* +* @param[in] pBase - Base instance. +* @param[out] pClassTypeId - Class type as a 64 bits integer +* @return error code or 0 (success) +*) +function calculation_base_classtypeid(pBase: TCalculationHandle; pClassTypeId: PQWord): TCalculationResult; cdecl; + (************************************************************************************************************************* Class export definition of Calculator **************************************************************************************************************************) @@ -42,7 +51,7 @@ interface * @param[in] pVariable - The new variable in this calculator * @return error code or 0 (success) *) -function calculation_calculator_enlistvariable(pCalculator: TCalculationHandle; pVariable: TCalculationHandle): TCalculationResult; cdecl; +function calculation_calculator_enlistvariable(pCalculator: TCalculationHandle; pVariable: TNumbersHandle): TCalculationResult; cdecl; (** * Returns an instance of a enlisted variable @@ -52,7 +61,7 @@ function calculation_calculator_enlistvariable(pCalculator: TCalculationHandle; * @param[out] pVariable - The Index-th variable in this calculator * @return error code or 0 (success) *) -function calculation_calculator_getenlistedvariable(pCalculator: TCalculationHandle; nIndex: Cardinal; pVariable: PCalculationHandle): TCalculationResult; cdecl; +function calculation_calculator_getenlistedvariable(pCalculator: TCalculationHandle; nIndex: Cardinal; pVariable: PNumbersHandle): TCalculationResult; cdecl; (** * Clears all variables in enlisted in this calculator @@ -69,7 +78,7 @@ function calculation_calculator_clearvariables(pCalculator: TCalculationHandle): * @param[out] pInstance - Variable that holds the product of all enlisted Variables * @return error code or 0 (success) *) -function calculation_calculator_multiply(pCalculator: TCalculationHandle; pInstance: PCalculationHandle): TCalculationResult; cdecl; +function calculation_calculator_multiply(pCalculator: TCalculationHandle; pInstance: PNumbersHandle): TCalculationResult; cdecl; (** * Sums all enlisted variables @@ -78,7 +87,7 @@ function calculation_calculator_multiply(pCalculator: TCalculationHandle; pInsta * @param[out] pInstance - Variable that holds the sum of all enlisted Variables * @return error code or 0 (success) *) -function calculation_calculator_add(pCalculator: TCalculationHandle; pInstance: PCalculationHandle): TCalculationResult; cdecl; +function calculation_calculator_add(pCalculator: TCalculationHandle; pInstance: PNumbersHandle): TCalculationResult; cdecl; (************************************************************************************************************************* Global function export definition @@ -156,7 +165,42 @@ function _calculation_getprocaddress_internal(pProcName: PAnsiChar; out ppProcAd implementation -function calculation_calculator_enlistvariable(pCalculator: TCalculationHandle; pVariable: TCalculationHandle): TCalculationResult; cdecl; +function calculation_base_classtypeid(pBase: TCalculationHandle; pClassTypeId: PQWord): TCalculationResult; cdecl; +var + ResultClassTypeId: QWord; + ObjectBase: TObject; + IntfBase: ICalculationBase; +begin + try + if not Assigned(pClassTypeId) then + raise ECalculationException.Create(CALCULATION_ERROR_INVALIDPARAM); + if not Assigned(pBase) then + raise ECalculationException.Create(CALCULATION_ERROR_INVALIDPARAM); + + ObjectBase := TObject(pBase); + if Supports(ObjectBase, ICalculationBase) then begin + IntfBase := ObjectBase as ICalculationBase; + ResultClassTypeId := IntfBase.ClassTypeId(); + + pClassTypeId^ := ResultClassTypeId; + end else + raise ECalculationException.Create(CALCULATION_ERROR_INVALIDCAST); + + Result := CALCULATION_SUCCESS; + except + On E: ECalculationException do begin + Result := HandleCalculationException(ObjectBase , E); + end; + On E: Exception do begin + Result := HandleStdException(ObjectBase , E); + end + else begin + Result := HandleUnhandledException(ObjectBase); + end; + end; +end; + +function calculation_calculator_enlistvariable(pCalculator: TCalculationHandle; pVariable: TNumbersHandle): TCalculationResult; cdecl; var ObjectVariable: TNumbersVariable; ObjectCalculator: TObject; @@ -191,7 +235,7 @@ function calculation_calculator_enlistvariable(pCalculator: TCalculationHandle; end; end; -function calculation_calculator_getenlistedvariable(pCalculator: TCalculationHandle; nIndex: Cardinal; pVariable: PCalculationHandle): TCalculationResult; cdecl; +function calculation_calculator_getenlistedvariable(pCalculator: TCalculationHandle; nIndex: Cardinal; pVariable: PNumbersHandle): TCalculationResult; cdecl; var ResultVariable: TNumbersVariable; ObjectCalculator: TObject; @@ -258,7 +302,7 @@ function calculation_calculator_clearvariables(pCalculator: TCalculationHandle): end; end; -function calculation_calculator_multiply(pCalculator: TCalculationHandle; pInstance: PCalculationHandle): TCalculationResult; cdecl; +function calculation_calculator_multiply(pCalculator: TCalculationHandle; pInstance: PNumbersHandle): TCalculationResult; cdecl; var ResultInstance: TNumbersVariable; ObjectCalculator: TObject; @@ -294,7 +338,7 @@ function calculation_calculator_multiply(pCalculator: TCalculationHandle; pInsta end; end; -function calculation_calculator_add(pCalculator: TCalculationHandle; pInstance: PCalculationHandle): TCalculationResult; cdecl; +function calculation_calculator_add(pCalculator: TCalculationHandle; pInstance: PNumbersHandle): TCalculationResult; cdecl; var ResultInstance: TNumbersVariable; ObjectCalculator: TObject; @@ -520,7 +564,9 @@ function _calculation_getprocaddress_internal(pProcName: PAnsiChar; out ppProcAd result := CALCULATION_SUCCESS; ppProcAddress := nil; - if (pProcName = 'calculation_calculator_enlistvariable') then + if (pProcName = 'calculation_base_classtypeid') then + ppProcAddress := @calculation_base_classtypeid + else if (pProcName = 'calculation_calculator_enlistvariable') then ppProcAddress := @calculation_calculator_enlistvariable else if (pProcName = 'calculation_calculator_getenlistedvariable') then ppProcAddress := @calculation_calculator_getenlistedvariable diff --git a/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation_interfaces.pas b/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation_interfaces.pas index 19d9a83d..b98cd3ea 100644 --- a/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation_interfaces.pas +++ b/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation_interfaces.pas @@ -4,7 +4,7 @@ All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated Pascal interface definition file in order to allow easy development of Calculation library. The functions in this file need to be implemented. It needs to be generated only once. @@ -40,6 +40,7 @@ interface procedure RegisterErrorMessage(const AErrorMessage: String); procedure IncRefCount(); function DecRefCount(): Boolean; + function ClassTypeId(): QWord; end; diff --git a/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation_types.pas b/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation_types.pas index b18eef85..6046e610 100644 --- a/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation_types.pas +++ b/Examples/Injection/Calculation_component/Implementations/Pascal/Interfaces/calculation_types.pas @@ -4,7 +4,7 @@ All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated Pascal type definition file in order to allow easy development of Calculation library. The functions in this file need to be implemented. It needs to be generated only once. diff --git a/Examples/Injection/Numbers_component/Bindings/CppDynamic/numbers_dynamic.h b/Examples/Injection/Numbers_component/Bindings/CppDynamic/numbers_dynamic.h index eb2e5999..5f2c3c42 100644 --- a/Examples/Injection/Numbers_component/Bindings/CppDynamic/numbers_dynamic.h +++ b/Examples/Injection/Numbers_component/Bindings/CppDynamic/numbers_dynamic.h @@ -4,7 +4,7 @@ Copyright (C) 2019 Numbers developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of Numbers library @@ -24,6 +24,15 @@ Interface version: 1.0.0 Class definition for Base **************************************************************************************************************************/ +/** +* Get Class Type Id +* +* @param[in] pBase - Base instance. +* @param[out] pClassTypeId - Class type as a 64 bits integer +* @return error code or 0 (success) +*/ +typedef NumbersResult (*PNumbersBase_ClassTypeIdPtr) (Numbers_Base pBase, Numbers_uint64 * pClassTypeId); + /************************************************************************************************************************* Class definition for Variable **************************************************************************************************************************/ @@ -111,6 +120,7 @@ typedef NumbersResult (*PNumbersGetSymbolLookupMethodPtr) (Numbers_pvoid * pSymb typedef struct { void * m_LibraryHandle; + PNumbersBase_ClassTypeIdPtr m_Base_ClassTypeId; PNumbersVariable_GetValuePtr m_Variable_GetValue; PNumbersVariable_SetValuePtr m_Variable_SetValue; PNumbersCreateVariablePtr m_CreateVariable; diff --git a/Examples/Injection/Numbers_component/Bindings/CppDynamic/numbers_dynamic.hpp b/Examples/Injection/Numbers_component/Bindings/CppDynamic/numbers_dynamic.hpp index 4c3758f7..991747ec 100644 --- a/Examples/Injection/Numbers_component/Bindings/CppDynamic/numbers_dynamic.hpp +++ b/Examples/Injection/Numbers_component/Bindings/CppDynamic/numbers_dynamic.hpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Numbers developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of Numbers library @@ -25,6 +25,7 @@ Interface version: 1.0.0 #else // _WIN32 #include <dlfcn.h> #endif // _WIN32 +#include <array> #include <string> #include <memory> #include <vector> @@ -61,6 +62,33 @@ typedef PBase PNumbersBase; typedef PVariable PNumbersVariable; +/************************************************************************************************************************* + classParam Definition +**************************************************************************************************************************/ + +template<class T> class classParam { +private: + const T* m_ptr; + +public: + classParam(const T* ptr) + : m_ptr (ptr) + { + } + + classParam(std::shared_ptr <T> sharedPtr) + : m_ptr (sharedPtr.get()) + { + } + + NumbersHandle GetHandle() + { + if (m_ptr != nullptr) + return m_ptr->handle(); + return nullptr; + } +}; + /************************************************************************************************************************* Class ENumbersException **************************************************************************************************************************/ @@ -74,15 +102,16 @@ class ENumbersException : public std::exception { * Error message for the Exception. */ std::string m_errorMessage; + std::string m_originalErrorMessage; public: /** * Exception Constructor. */ ENumbersException(NumbersResult errorCode, const std::string & sErrorMessage) - : m_errorMessage("Numbers Error " + std::to_string(errorCode) + " (" + sErrorMessage + ")") + : m_errorCode(errorCode), m_originalErrorMessage(sErrorMessage) { - m_errorCode = errorCode; + m_errorMessage = buildErrorMessage(); } /** @@ -101,6 +130,53 @@ class ENumbersException : public std::exception { return m_errorMessage.c_str(); } + const char* getErrorMessage() const noexcept + { + return m_originalErrorMessage.c_str(); + } + + const char* getErrorName() const noexcept + { + switch(getErrorCode()) { + case NUMBERS_SUCCESS: return "SUCCESS"; + case NUMBERS_ERROR_NOTIMPLEMENTED: return "NOTIMPLEMENTED"; + case NUMBERS_ERROR_INVALIDPARAM: return "INVALIDPARAM"; + case NUMBERS_ERROR_INVALIDCAST: return "INVALIDCAST"; + case NUMBERS_ERROR_BUFFERTOOSMALL: return "BUFFERTOOSMALL"; + case NUMBERS_ERROR_GENERICEXCEPTION: return "GENERICEXCEPTION"; + case NUMBERS_ERROR_COULDNOTLOADLIBRARY: return "COULDNOTLOADLIBRARY"; + case NUMBERS_ERROR_COULDNOTFINDLIBRARYEXPORT: return "COULDNOTFINDLIBRARYEXPORT"; + case NUMBERS_ERROR_INCOMPATIBLEBINARYVERSION: return "INCOMPATIBLEBINARYVERSION"; + } + return "UNKNOWN"; + } + + const char* getErrorDescription() const noexcept + { + switch(getErrorCode()) { + case NUMBERS_SUCCESS: return "success"; + case NUMBERS_ERROR_NOTIMPLEMENTED: return "functionality not implemented"; + case NUMBERS_ERROR_INVALIDPARAM: return "an invalid parameter was passed"; + case NUMBERS_ERROR_INVALIDCAST: return "a type cast failed"; + case NUMBERS_ERROR_BUFFERTOOSMALL: return "a provided buffer is too small"; + case NUMBERS_ERROR_GENERICEXCEPTION: return "a generic exception occurred"; + case NUMBERS_ERROR_COULDNOTLOADLIBRARY: return "the library could not be loaded"; + case NUMBERS_ERROR_COULDNOTFINDLIBRARYEXPORT: return "a required exported symbol could not be found in the library"; + case NUMBERS_ERROR_INCOMPATIBLEBINARYVERSION: return "the version of the binary interface does not match the bindings interface"; + } + return "unknown error"; + } + +private: + + std::string buildErrorMessage() const noexcept + { + std::string msg = m_originalErrorMessage; + if (msg.empty()) { + msg = getErrorDescription(); + } + return std::string("Error: ") + getErrorName() + ": " + msg; + } }; /************************************************************************************************************************* @@ -115,7 +191,7 @@ class CInputVector { public: - CInputVector( const std::vector<T>& vec) + explicit CInputVector( const std::vector<T>& vec) : m_data( vec.data() ), m_size( vec.size() ) { } @@ -147,7 +223,7 @@ using CNumbersInputVector = CInputVector<T>; class CWrapper { public: - CWrapper(void* pSymbolLookupMethod) + explicit CWrapper(void* pSymbolLookupMethod) { CheckError(nullptr, initWrapperTable(&m_WrapperTable)); CheckError(nullptr, loadWrapperTableFromSymbolLookupMethod(&m_WrapperTable, pSymbolLookupMethod)); @@ -155,7 +231,7 @@ class CWrapper { CheckError(nullptr, checkBinaryVersion()); } - CWrapper(const std::string &sFileName) + explicit CWrapper(const std::string &sFileName) { CheckError(nullptr, initWrapperTable(&m_WrapperTable)); CheckError(nullptr, loadWrapperTable(&m_WrapperTable, sFileName.c_str())); @@ -182,11 +258,14 @@ class CWrapper { inline PVariable CreateVariable(const Numbers_double dInitialValue); inline void GetVersion(Numbers_uint32 & nMajor, Numbers_uint32 & nMinor, Numbers_uint32 & nMicro); - inline bool GetLastError(CBase * pInstance, std::string & sErrorMessage); - inline void ReleaseInstance(CBase * pInstance); - inline void AcquireInstance(CBase * pInstance); + inline bool GetLastError(classParam<CBase> pInstance, std::string & sErrorMessage); + inline void ReleaseInstance(classParam<CBase> pInstance); + inline void AcquireInstance(classParam<CBase> pInstance); inline Numbers_pvoid GetSymbolLookupMethod(); + template<class U> + std::shared_ptr<U> polymorphicFactory(NumbersHandle); + private: sNumbersDynamicWrapperTable m_WrapperTable; @@ -194,7 +273,7 @@ class CWrapper { { Numbers_uint32 nMajor, nMinor, nMicro; GetVersion(nMajor, nMinor, nMicro); - if ( (nMajor != NUMBERS_VERSION_MAJOR) || (nMinor < NUMBERS_VERSION_MINOR) ) { + if (nMajor != NUMBERS_VERSION_MAJOR) { return NUMBERS_ERROR_INCOMPATIBLEBINARYVERSION; } return NUMBERS_SUCCESS; @@ -248,14 +327,23 @@ class CBase { } /** - * CBase::GetHandle - Returns handle to instance. + * CBase::handle - Returns handle to instance. */ - NumbersHandle GetHandle() + NumbersHandle handle() const { return m_pHandle; } - + + /** + * CBase::wrapper - Returns wrapper instance. + */ + CWrapper * wrapper() const + { + return m_pWrapper; + } + friend class CWrapper; + inline Numbers_uint64 ClassTypeId(); }; /************************************************************************************************************************* @@ -275,6 +363,29 @@ class CVariable : public CBase { inline Numbers_double GetValue(); inline void SetValue(const Numbers_double dValue); }; + +/************************************************************************************************************************* + RTTI: Polymorphic Factory implementation +**************************************************************************************************************************/ + +/** +* IMPORTANT: PolymorphicFactory method should not be used by application directly. +* It's designed to be used on NumbersHandle object only once. +* If it's used on any existing object as a form of dynamic cast then +* CWrapper::AcquireInstance(CBase object) must be called after instantiating new object. +* This is important to keep reference count matching between application and library sides. +*/ +template <class T> +std::shared_ptr<T> CWrapper::polymorphicFactory(NumbersHandle pHandle) +{ + Numbers_uint64 resultClassTypeId = 0; + CheckError(nullptr, m_WrapperTable.m_Base_ClassTypeId(pHandle, &resultClassTypeId)); + switch(resultClassTypeId) { + case 0x27799F69B3FD1C9EUL: return std::dynamic_pointer_cast<T>(std::make_shared<CBase>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "Numbers::Base" + case 0x23934EDF762423EAUL: return std::dynamic_pointer_cast<T>(std::make_shared<CVariable>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "Numbers::Variable" + } + return std::make_shared<T>(this, pHandle); +} /** * CWrapper::CreateVariable - Creates a new Variable instance @@ -289,7 +400,7 @@ class CVariable : public CBase { if (!hInstance) { CheckError(nullptr,NUMBERS_ERROR_INVALIDPARAM); } - return std::make_shared<CVariable>(this, hInstance); + return this->polymorphicFactory<CVariable>(hInstance); } /** @@ -309,12 +420,9 @@ class CVariable : public CBase { * @param[out] sErrorMessage - Message of the last error * @return Is there a last error to query */ - inline bool CWrapper::GetLastError(CBase * pInstance, std::string & sErrorMessage) + inline bool CWrapper::GetLastError(classParam<CBase> pInstance, std::string & sErrorMessage) { - NumbersHandle hInstance = nullptr; - if (pInstance != nullptr) { - hInstance = pInstance->GetHandle(); - }; + NumbersHandle hInstance = pInstance.GetHandle(); Numbers_uint32 bytesNeededErrorMessage = 0; Numbers_uint32 bytesWrittenErrorMessage = 0; bool resultHasError = 0; @@ -330,12 +438,9 @@ class CVariable : public CBase { * CWrapper::ReleaseInstance - Releases shared ownership of an Instance * @param[in] pInstance - Instance Handle */ - inline void CWrapper::ReleaseInstance(CBase * pInstance) + inline void CWrapper::ReleaseInstance(classParam<CBase> pInstance) { - NumbersHandle hInstance = nullptr; - if (pInstance != nullptr) { - hInstance = pInstance->GetHandle(); - }; + NumbersHandle hInstance = pInstance.GetHandle(); CheckError(nullptr,m_WrapperTable.m_ReleaseInstance(hInstance)); } @@ -343,12 +448,9 @@ class CVariable : public CBase { * CWrapper::AcquireInstance - Acquires shared ownership of an Instance * @param[in] pInstance - Instance Handle */ - inline void CWrapper::AcquireInstance(CBase * pInstance) + inline void CWrapper::AcquireInstance(classParam<CBase> pInstance) { - NumbersHandle hInstance = nullptr; - if (pInstance != nullptr) { - hInstance = pInstance->GetHandle(); - }; + NumbersHandle hInstance = pInstance.GetHandle(); CheckError(nullptr,m_WrapperTable.m_AcquireInstance(hInstance)); } @@ -382,6 +484,7 @@ class CVariable : public CBase { return NUMBERS_ERROR_INVALIDPARAM; pWrapperTable->m_LibraryHandle = nullptr; + pWrapperTable->m_Base_ClassTypeId = nullptr; pWrapperTable->m_Variable_GetValue = nullptr; pWrapperTable->m_Variable_SetValue = nullptr; pWrapperTable->m_CreateVariable = nullptr; @@ -421,7 +524,7 @@ class CVariable : public CBase { #ifdef _WIN32 // Convert filename to UTF16-string - int nLength = (int)strlen(pLibraryFileName); + int nLength = static_cast<int>(strnlen_s(pLibraryFileName, MAX_PATH)); int nBufferSize = nLength * 2 + 2; std::vector<wchar_t> wsLibraryFileName(nBufferSize); int nResult = MultiByteToWideChar(CP_UTF8, 0, pLibraryFileName, nLength, &wsLibraryFileName[0], nBufferSize); @@ -438,6 +541,15 @@ class CVariable : public CBase { dlerror(); #endif // _WIN32 + #ifdef _WIN32 + pWrapperTable->m_Base_ClassTypeId = (PNumbersBase_ClassTypeIdPtr) GetProcAddress(hLibrary, "numbers_base_classtypeid"); + #else // _WIN32 + pWrapperTable->m_Base_ClassTypeId = (PNumbersBase_ClassTypeIdPtr) dlsym(hLibrary, "numbers_base_classtypeid"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_Base_ClassTypeId == nullptr) + return NUMBERS_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 pWrapperTable->m_Variable_GetValue = (PNumbersVariable_GetValuePtr) GetProcAddress(hLibrary, "numbers_variable_getvalue"); #else // _WIN32 @@ -526,6 +638,10 @@ class CVariable : public CBase { SymbolLookupType pLookup = (SymbolLookupType)pSymbolLookupMethod; NumbersResult eLookupError = NUMBERS_SUCCESS; + eLookupError = (*pLookup)("numbers_base_classtypeid", (void**)&(pWrapperTable->m_Base_ClassTypeId)); + if ( (eLookupError != 0) || (pWrapperTable->m_Base_ClassTypeId == nullptr) ) + return NUMBERS_ERROR_COULDNOTFINDLIBRARYEXPORT; + eLookupError = (*pLookup)("numbers_variable_getvalue", (void**)&(pWrapperTable->m_Variable_GetValue)); if ( (eLookupError != 0) || (pWrapperTable->m_Variable_GetValue == nullptr) ) return NUMBERS_ERROR_COULDNOTFINDLIBRARYEXPORT; @@ -567,6 +683,18 @@ class CVariable : public CBase { * Method definitions for class CBase */ + /** + * CBase::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + Numbers_uint64 CBase::ClassTypeId() + { + Numbers_uint64 resultClassTypeId = 0; + CheckError(m_pWrapper->m_WrapperTable.m_Base_ClassTypeId(m_pHandle, &resultClassTypeId)); + + return resultClassTypeId; + } + /** * Method definitions for class CVariable */ diff --git a/Examples/Injection/Numbers_component/Bindings/CppDynamic/numbers_types.hpp b/Examples/Injection/Numbers_component/Bindings/CppDynamic/numbers_types.hpp index e3722625..eda05a8a 100644 --- a/Examples/Injection/Numbers_component/Bindings/CppDynamic/numbers_types.hpp +++ b/Examples/Injection/Numbers_component/Bindings/CppDynamic/numbers_types.hpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Numbers developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++-Header file with basic types in order to allow an easy use of Numbers library @@ -73,14 +73,33 @@ typedef void * Numbers_pvoid; **************************************************************************************************************************/ #define NUMBERS_SUCCESS 0 -#define NUMBERS_ERROR_NOTIMPLEMENTED 1 -#define NUMBERS_ERROR_INVALIDPARAM 2 -#define NUMBERS_ERROR_INVALIDCAST 3 -#define NUMBERS_ERROR_BUFFERTOOSMALL 4 -#define NUMBERS_ERROR_GENERICEXCEPTION 5 -#define NUMBERS_ERROR_COULDNOTLOADLIBRARY 6 -#define NUMBERS_ERROR_COULDNOTFINDLIBRARYEXPORT 7 -#define NUMBERS_ERROR_INCOMPATIBLEBINARYVERSION 8 +#define NUMBERS_ERROR_NOTIMPLEMENTED 1 /** functionality not implemented */ +#define NUMBERS_ERROR_INVALIDPARAM 2 /** an invalid parameter was passed */ +#define NUMBERS_ERROR_INVALIDCAST 3 /** a type cast failed */ +#define NUMBERS_ERROR_BUFFERTOOSMALL 4 /** a provided buffer is too small */ +#define NUMBERS_ERROR_GENERICEXCEPTION 5 /** a generic exception occurred */ +#define NUMBERS_ERROR_COULDNOTLOADLIBRARY 6 /** the library could not be loaded */ +#define NUMBERS_ERROR_COULDNOTFINDLIBRARYEXPORT 7 /** a required exported symbol could not be found in the library */ +#define NUMBERS_ERROR_INCOMPATIBLEBINARYVERSION 8 /** the version of the binary interface does not match the bindings interface */ + +/************************************************************************************************************************* + Error strings for Numbers +**************************************************************************************************************************/ + +inline const char * NUMBERS_GETERRORSTRING (NumbersResult nErrorCode) { + switch (nErrorCode) { + case NUMBERS_SUCCESS: return "no error"; + case NUMBERS_ERROR_NOTIMPLEMENTED: return "functionality not implemented"; + case NUMBERS_ERROR_INVALIDPARAM: return "an invalid parameter was passed"; + case NUMBERS_ERROR_INVALIDCAST: return "a type cast failed"; + case NUMBERS_ERROR_BUFFERTOOSMALL: return "a provided buffer is too small"; + case NUMBERS_ERROR_GENERICEXCEPTION: return "a generic exception occurred"; + case NUMBERS_ERROR_COULDNOTLOADLIBRARY: return "the library could not be loaded"; + case NUMBERS_ERROR_COULDNOTFINDLIBRARYEXPORT: return "a required exported symbol could not be found in the library"; + case NUMBERS_ERROR_INCOMPATIBLEBINARYVERSION: return "the version of the binary interface does not match the bindings interface"; + default: return "unknown error"; + } +} /************************************************************************************************************************* Declaration of handle classes diff --git a/Examples/Injection/Numbers_component/Bindings/Pascal/Unit_Numbers.pas b/Examples/Injection/Numbers_component/Bindings/Pascal/Unit_Numbers.pas index 106bf41e..21387fac 100644 --- a/Examples/Injection/Numbers_component/Bindings/Pascal/Unit_Numbers.pas +++ b/Examples/Injection/Numbers_component/Bindings/Pascal/Unit_Numbers.pas @@ -5,7 +5,7 @@ All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated Pascal Header file in order to allow an easy use of Numbers library @@ -81,6 +81,15 @@ TNumbersVariable = class; Function type definitions for Base **************************************************************************************************************************) + (** + * Get Class Type Id + * + * @param[in] pBase - Base instance. + * @param[out] pClassTypeId - Class type as a 64 bits integer + * @return error code or 0 (success) + *) + TNumbersBase_ClassTypeIdFunc = function(pBase: TNumbersHandle; out pClassTypeId: QWord): TNumbersResult; cdecl; + (************************************************************************************************************************* Function type definitions for Variable @@ -197,6 +206,7 @@ TNumbersBase = class(TObject) constructor Create(AWrapper: TNumbersWrapper; AHandle: TNumbersHandle); destructor Destroy; override; property TheHandle: TNumbersHandle read FHandle; + function ClassTypeId(): QWord; end; @@ -219,6 +229,7 @@ TNumbersVariable = class(TNumbersBase) TNumbersWrapper = class(TObject) private FModule: HMODULE; + FNumbersBase_ClassTypeIdFunc: TNumbersBase_ClassTypeIdFunc; FNumbersVariable_GetValueFunc: TNumbersVariable_GetValueFunc; FNumbersVariable_SetValueFunc: TNumbersVariable_SetValueFunc; FNumbersCreateVariableFunc: TNumbersCreateVariableFunc; @@ -237,6 +248,7 @@ TNumbersWrapper = class(TObject) procedure checkBinaryVersion(); protected + property NumbersBase_ClassTypeIdFunc: TNumbersBase_ClassTypeIdFunc read FNumbersBase_ClassTypeIdFunc; property NumbersVariable_GetValueFunc: TNumbersVariable_GetValueFunc read FNumbersVariable_GetValueFunc; property NumbersVariable_SetValueFunc: TNumbersVariable_SetValueFunc read FNumbersVariable_SetValueFunc; property NumbersCreateVariableFunc: TNumbersCreateVariableFunc read FNumbersCreateVariableFunc; @@ -258,10 +270,38 @@ TNumbersWrapper = class(TObject) function GetSymbolLookupMethod(): Pointer; end; + TNumbersPolymorphicFactory<_T:class; _B> = record + class function Make(Wrapper: TNumbersWrapper; Handle: TNumbersHandle): _T; static; + end; implementation +(************************************************************************************************************************* + PolymorficFactory implementation +**************************************************************************************************************************) + + (** + * IMPORTANT: PolymorphicFactory method should not be used by application directly. + * It's designed to be used on NumbersHandle object only once. + * If it's used on any existing object as a form of dynamic cast then + * TNUMBERSWrapper::AcquireInstance(object: TNUMBERSBase) must be called after instantiating new object. + * This is important to keep reference count matching between application and library sides. + *) + class function TNumbersPolymorphicFactory<_T, _B>.Make(Wrapper: TNumbersWrapper; Handle: TNumbersHandle): _T; + var + ClassTypeId: QWord; + Obj: TNUMBERSBase; + begin + Result := nil; + Wrapper.CheckError(nil, Wrapper.NumbersBase_ClassTypeIdFunc(handle, ClassTypeId)); + case (ClassTypeId) of + QWord($27799F69B3FD1C9E): begin Obj := TNUMBERSBase.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "Numbers::Base" + QWord($23934EDF762423EA): begin Obj := TNUMBERSVariable.Create(Wrapper, Handle); if Obj.inheritsFrom(_T) then Result := Obj as _T; end; // First 64 bits of SHA1 of a string: "Numbers::Variable" + end; + if Result = nil then Result := _B.Create(Wrapper, Handle); + end; + (************************************************************************************************************************* Exception implementation **************************************************************************************************************************) @@ -316,6 +356,11 @@ implementation inherited; end; + function TNumbersBase.ClassTypeId(): QWord; + begin + FWrapper.CheckError(Self, FWrapper.NumbersBase_ClassTypeIdFunc(FHandle, Result)); + end; + (************************************************************************************************************************* Class implementation for Variable **************************************************************************************************************************) @@ -362,6 +407,7 @@ implementation if FModule = 0 then raise ENumbersException.Create(NUMBERS_ERROR_COULDNOTLOADLIBRARY, ''); + FNumbersBase_ClassTypeIdFunc := LoadFunction('numbers_base_classtypeid'); FNumbersVariable_GetValueFunc := LoadFunction('numbers_variable_getvalue'); FNumbersVariable_SetValueFunc := LoadFunction('numbers_variable_setvalue'); FNumbersCreateVariableFunc := LoadFunction('numbers_createvariable'); @@ -381,6 +427,9 @@ implementation inherited Create; + AResult := ALookupMethod(PAnsiChar('numbers_base_classtypeid'), @FNumbersBase_ClassTypeIdFunc); + if AResult <> NUMBERS_SUCCESS then + raise ENumbersException.CreateCustomMessage(NUMBERS_ERROR_COULDNOTLOADLIBRARY, ''); AResult := ALookupMethod(PAnsiChar('numbers_variable_getvalue'), @FNumbersVariable_GetValueFunc); if AResult <> NUMBERS_SUCCESS then raise ENumbersException.CreateCustomMessage(NUMBERS_ERROR_COULDNOTLOADLIBRARY, ''); @@ -470,7 +519,7 @@ implementation HInstance := nil; CheckError(nil, NumbersCreateVariableFunc(AInitialValue, HInstance)); if Assigned(HInstance) then - Result := TNumbersVariable.Create(Self, HInstance); + Result := TNumbersPolymorphicFactory<TNumbersVariable, TNumbersVariable>.Make(Self, HInstance); end; procedure TNumbersWrapper.GetVersion(out AMajor: Cardinal; out AMinor: Cardinal; out AMicro: Cardinal); diff --git a/Examples/Injection/Numbers_component/Bindings/Python/Numbers.py b/Examples/Injection/Numbers_component/Bindings/Python/Numbers.py index 7f290147..dfde04d7 100644 --- a/Examples/Injection/Numbers_component/Bindings/Python/Numbers.py +++ b/Examples/Injection/Numbers_component/Bindings/Python/Numbers.py @@ -4,7 +4,7 @@ All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated Python file in order to allow an easy use of Numbers library @@ -62,6 +62,7 @@ class FunctionTable: numbers_releaseinstance = None numbers_acquireinstance = None numbers_getsymbollookupmethod = None + numbers_base_classtypeid = None numbers_variable_getvalue = None numbers_variable_setvalue = None @@ -143,6 +144,12 @@ def _loadFunctionTableFromMethod(self, symbolLookupMethodAddress): methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.POINTER(ctypes.c_void_p)) self.lib.numbers_getsymbollookupmethod = methodType(int(methodAddress.value)) + err = symbolLookupMethod(ctypes.c_char_p(str.encode("numbers_base_classtypeid")), methodAddress) + if err != 0: + raise ENumbersException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.POINTER(ctypes.c_uint64)) + self.lib.numbers_base_classtypeid = methodType(int(methodAddress.value)) + err = symbolLookupMethod(ctypes.c_char_p(str.encode("numbers_variable_getvalue")), methodAddress) if err != 0: raise ENumbersException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) @@ -178,6 +185,9 @@ def _loadFunctionTable(self): self.lib.numbers_getsymbollookupmethod.restype = ctypes.c_int32 self.lib.numbers_getsymbollookupmethod.argtypes = [ctypes.POINTER(ctypes.c_void_p)] + self.lib.numbers_base_classtypeid.restype = ctypes.c_int32 + self.lib.numbers_base_classtypeid.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_uint64)] + self.lib.numbers_variable_getvalue.restype = ctypes.c_int32 self.lib.numbers_variable_getvalue.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_double)] @@ -205,7 +215,7 @@ def CreateVariable(self, InitialValue): InstanceHandle = ctypes.c_void_p() self.checkError(None, self.lib.numbers_createvariable(dInitialValue, InstanceHandle)) if InstanceHandle: - InstanceObject = Variable(InstanceHandle, self) + InstanceObject = self._polymorphicFactory(InstanceHandle) else: raise ENumbersException(ErrorCodes.INVALIDCAST, 'Invalid return/output value') @@ -260,6 +270,30 @@ def GetSymbolLookupMethod(self): return pSymbolLookupMethod.value + '''IMPORTANT: PolymorphicFactory method should not be used by application directly. + It's designed to be used on NumbersHandle object only once. + If it's used on any existing object as a form of dynamic cast then + Wrapper.AcquireInstance(object) must be called after instantiating new object. + This is important to keep reference count matching between application and library sides. + ''' + def _polymorphicFactory(self, handle): + class PolymorphicFactory(): + def getObjectById(self, classtypeid, handle, wrapper): + methodName = 'getObjectById_' + format(classtypeid.value, '016X') + method = getattr(self, methodName, lambda: 'Invalid class type id') + return method(handle, wrapper) + def getObjectById_27799F69B3FD1C9E(self, handle, wrapper): # First 64 bits of SHA1 of a string: "Numbers::Base" + return Base(handle, wrapper) + def getObjectById_23934EDF762423EA(self, handle, wrapper): # First 64 bits of SHA1 of a string: "Numbers::Variable" + return Variable(handle, wrapper) + + if not handle: + return None + pClassTypeId = ctypes.c_uint64() + self.checkError(None, self.lib.numbers_base_classtypeid(handle, pClassTypeId)) + factory = PolymorphicFactory() + return factory.getObjectById(pClassTypeId, handle, self) + ''' Class Implementation for Base @@ -273,6 +307,12 @@ def __init__(self, handle, wrapper): def __del__(self): self._wrapper.ReleaseInstance(self) + def ClassTypeId(self): + pClassTypeId = ctypes.c_uint64() + self._wrapper.checkError(self, self._wrapper.lib.numbers_base_classtypeid(self._handle, pClassTypeId)) + + return pClassTypeId.value + ''' Class Implementation for Variable diff --git a/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_abi.hpp b/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_abi.hpp index 95771945..8b8efed6 100644 --- a/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_abi.hpp +++ b/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_abi.hpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Numbers developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of Numbers library @@ -29,94 +29,107 @@ Interface version: 1.0.0 #include "numbers_types.hpp" +#ifdef __cplusplus extern "C" { +#endif + +/************************************************************************************************************************* + Class definition for Base +**************************************************************************************************************************/ + +/** +* Get Class Type Id +* +* @param[in] pBase - Base instance. +* @param[out] pClassTypeId - Class type as a 64 bits integer +* @return error code or 0 (success) +*/ +NUMBERS_DECLSPEC NumbersResult numbers_base_classtypeid(Numbers_Base pBase, Numbers_uint64 * pClassTypeId); + +/************************************************************************************************************************* + Class definition for Variable +**************************************************************************************************************************/ + +/** +* Returns the current value of this Variable +* +* @param[in] pVariable - Variable instance. +* @param[out] pValue - The current value of this Variable +* @return error code or 0 (success) +*/ +NUMBERS_DECLSPEC NumbersResult numbers_variable_getvalue(Numbers_Variable pVariable, Numbers_double * pValue); + +/** +* Set the numerical value of this Variable +* +* @param[in] pVariable - Variable instance. +* @param[in] dValue - The new value of this Variable +* @return error code or 0 (success) +*/ +NUMBERS_DECLSPEC NumbersResult numbers_variable_setvalue(Numbers_Variable pVariable, Numbers_double dValue); + +/************************************************************************************************************************* + Global functions +**************************************************************************************************************************/ + +/** +* Creates a new Variable instance +* +* @param[in] dInitialValue - Initial value of the new Variable +* @param[out] pInstance - New Variable instance +* @return error code or 0 (success) +*/ +NUMBERS_DECLSPEC NumbersResult numbers_createvariable(Numbers_double dInitialValue, Numbers_Variable * pInstance); + +/** +* retrieves the binary version of this library. +* +* @param[out] pMajor - returns the major version of this library +* @param[out] pMinor - returns the minor version of this library +* @param[out] pMicro - returns the micro version of this library +* @return error code or 0 (success) +*/ +NUMBERS_DECLSPEC NumbersResult numbers_getversion(Numbers_uint32 * pMajor, Numbers_uint32 * pMinor, Numbers_uint32 * pMicro); + +/** +* Returns the last error recorded on this object +* +* @param[in] pInstance - Instance Handle +* @param[in] nErrorMessageBufferSize - size of the buffer (including trailing 0) +* @param[out] pErrorMessageNeededChars - will be filled with the count of the written bytes, or needed buffer size. +* @param[out] pErrorMessageBuffer - buffer of Message of the last error, may be NULL +* @param[out] pHasError - Is there a last error to query +* @return error code or 0 (success) +*/ +NUMBERS_DECLSPEC NumbersResult numbers_getlasterror(Numbers_Base pInstance, const Numbers_uint32 nErrorMessageBufferSize, Numbers_uint32* pErrorMessageNeededChars, char * pErrorMessageBuffer, bool * pHasError); - /************************************************************************************************************************* - Class definition for Base - **************************************************************************************************************************/ - - /************************************************************************************************************************* - Class definition for Variable - **************************************************************************************************************************/ - - /** - * Returns the current value of this Variable - * - * @param[in] pVariable - Variable instance. - * @param[out] pValue - The current value of this Variable - * @return error code or 0 (success) - */ - NUMBERS_DECLSPEC NumbersResult numbers_variable_getvalue(Numbers_Variable pVariable, Numbers_double * pValue); - - /** - * Set the numerical value of this Variable - * - * @param[in] pVariable - Variable instance. - * @param[in] dValue - The new value of this Variable - * @return error code or 0 (success) - */ - NUMBERS_DECLSPEC NumbersResult numbers_variable_setvalue(Numbers_Variable pVariable, Numbers_double dValue); - - /************************************************************************************************************************* - Global functions - **************************************************************************************************************************/ - - /** - * Creates a new Variable instance - * - * @param[in] dInitialValue - Initial value of the new Variable - * @param[out] pInstance - New Variable instance - * @return error code or 0 (success) - */ - NUMBERS_DECLSPEC NumbersResult numbers_createvariable(Numbers_double dInitialValue, Numbers_Variable * pInstance); - - /** - * retrieves the binary version of this library. - * - * @param[out] pMajor - returns the major version of this library - * @param[out] pMinor - returns the minor version of this library - * @param[out] pMicro - returns the micro version of this library - * @return error code or 0 (success) - */ - NUMBERS_DECLSPEC NumbersResult numbers_getversion(Numbers_uint32 * pMajor, Numbers_uint32 * pMinor, Numbers_uint32 * pMicro); - - /** - * Returns the last error recorded on this object - * - * @param[in] pInstance - Instance Handle - * @param[in] nErrorMessageBufferSize - size of the buffer (including trailing 0) - * @param[out] pErrorMessageNeededChars - will be filled with the count of the written bytes, or needed buffer size. - * @param[out] pErrorMessageBuffer - buffer of Message of the last error, may be NULL - * @param[out] pHasError - Is there a last error to query - * @return error code or 0 (success) - */ - NUMBERS_DECLSPEC NumbersResult numbers_getlasterror(Numbers_Base pInstance, const Numbers_uint32 nErrorMessageBufferSize, Numbers_uint32* pErrorMessageNeededChars, char * pErrorMessageBuffer, bool * pHasError); - - /** - * Releases shared ownership of an Instance - * - * @param[in] pInstance - Instance Handle - * @return error code or 0 (success) - */ - NUMBERS_DECLSPEC NumbersResult numbers_releaseinstance(Numbers_Base pInstance); - - /** - * Acquires shared ownership of an Instance - * - * @param[in] pInstance - Instance Handle - * @return error code or 0 (success) - */ - NUMBERS_DECLSPEC NumbersResult numbers_acquireinstance(Numbers_Base pInstance); - - /** - * Returns the address of the SymbolLookupMethod - * - * @param[out] pSymbolLookupMethod - Address of the SymbolAddressMethod - * @return error code or 0 (success) - */ - NUMBERS_DECLSPEC NumbersResult numbers_getsymbollookupmethod(Numbers_pvoid * pSymbolLookupMethod); +/** +* Releases shared ownership of an Instance +* +* @param[in] pInstance - Instance Handle +* @return error code or 0 (success) +*/ +NUMBERS_DECLSPEC NumbersResult numbers_releaseinstance(Numbers_Base pInstance); + +/** +* Acquires shared ownership of an Instance +* +* @param[in] pInstance - Instance Handle +* @return error code or 0 (success) +*/ +NUMBERS_DECLSPEC NumbersResult numbers_acquireinstance(Numbers_Base pInstance); + +/** +* Returns the address of the SymbolLookupMethod +* +* @param[out] pSymbolLookupMethod - Address of the SymbolAddressMethod +* @return error code or 0 (success) +*/ +NUMBERS_DECLSPEC NumbersResult numbers_getsymbollookupmethod(Numbers_pvoid * pSymbolLookupMethod); +#ifdef __cplusplus } +#endif #endif // __NUMBERS_HEADER_CPP diff --git a/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfaceexception.cpp b/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfaceexception.cpp index 750c77de..28c14250 100644 --- a/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfaceexception.cpp +++ b/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfaceexception.cpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Numbers developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++ Implementation file with the basic internal exception type in order to allow an easy use of Numbers library @@ -22,7 +22,7 @@ Interface version: 1.0.0 Class ENumbersInterfaceException **************************************************************************************************************************/ ENumbersInterfaceException::ENumbersInterfaceException(NumbersResult errorCode) - : m_errorMessage("Numbers Error " + std::to_string (errorCode)) + : m_errorMessage(NUMBERS_GETERRORSTRING (errorCode)) { m_errorCode = errorCode; } diff --git a/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfaceexception.hpp b/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfaceexception.hpp index deb3f453..3396348b 100644 --- a/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfaceexception.hpp +++ b/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfaceexception.hpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Numbers developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++ Header file with the basic internal exception type in order to allow an easy use of Numbers library @@ -25,8 +25,7 @@ Interface version: 1.0.0 **************************************************************************************************************************/ -class ENumbersInterfaceException : public std::exception -{ +class ENumbersInterfaceException : public std::exception { protected: /** * Error code for the Exception. diff --git a/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfaces.hpp b/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfaces.hpp index 207fc8c6..516b97f3 100644 --- a/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfaces.hpp +++ b/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfaces.hpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Numbers developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++ header file in order to allow easy development of Numbers library. The implementer of Numbers library needs to @@ -37,7 +37,68 @@ class IVariable; /************************************************************************************************************************* - Class interface for Base + Parameter Cache definitions +**************************************************************************************************************************/ + +class ParameterCache { + public: + virtual ~ParameterCache() {} +}; + +template <class T1> class ParameterCache_1 : public ParameterCache { + private: + T1 m_param1; + public: + ParameterCache_1 (const T1 & param1) + : m_param1 (param1) + { + } + + void retrieveData (T1 & param1) + { + param1 = m_param1; + } +}; + +template <class T1, class T2> class ParameterCache_2 : public ParameterCache { + private: + T1 m_param1; + T2 m_param2; + public: + ParameterCache_2 (const T1 & param1, const T2 & param2) + : m_param1 (param1), m_param2 (param2) + { + } + + void retrieveData (T1 & param1, T2 & param2) + { + param1 = m_param1; + param2 = m_param2; + } +}; + +template <class T1, class T2, class T3> class ParameterCache_3 : public ParameterCache { + private: + T1 m_param1; + T2 m_param2; + T3 m_param3; + public: + ParameterCache_3 (const T1 & param1, const T2 & param2, const T3 & param3) + : m_param1 (param1), m_param2 (param2), m_param3 (param3) + { + } + + void retrieveData (T1 & param1, T2 & param2, T3 & param3) + { + param1 = m_param1; + param2 = m_param2; + param3 = m_param3; + } +}; + + +/************************************************************************************************************************* + Class interface for Base **************************************************************************************************************************/ class IBase { @@ -98,6 +159,11 @@ class IBase { * @return Has the object been released */ virtual bool DecRefCount() = 0; + /** + * IBase::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + virtual Numbers_uint64 ClassTypeId() = 0; }; @@ -134,11 +200,22 @@ typedef IBaseSharedPtr<IBase> PIBase; /************************************************************************************************************************* - Class interface for Variable + Class interface for Variable **************************************************************************************************************************/ class IVariable : public virtual IBase { public: + /** + * IVariable::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + Numbers_uint64 ClassTypeId() override + { + // First 64 bits of SHA1 of a string: "Numbers::Variable" + static const Numbers_uint64 s_VariableTypeId = 0x23934EDF762423EAUL; + return s_VariableTypeId; + } + /** * IVariable::GetValue - Returns the current value of this Variable * @return The current value of this Variable @@ -198,6 +275,8 @@ class CWrapper { }; +NumbersResult Numbers_GetProcAddress (const char * pProcName, void ** ppProcAddress); + } // namespace Impl } // namespace Numbers diff --git a/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfacewrapper.cpp b/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfacewrapper.cpp index 7341553e..a7b73135 100644 --- a/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfacewrapper.cpp +++ b/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfacewrapper.cpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Numbers developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++ implementation file in order to allow easy development of Numbers library. The functions in this file need to be implemented. It needs to be generated only once. @@ -56,6 +56,32 @@ NumbersResult handleUnhandledException(IBase * pIBaseClass) /************************************************************************************************************************* Class implementation for Base **************************************************************************************************************************/ +NumbersResult numbers_base_classtypeid(Numbers_Base pBase, Numbers_uint64 * pClassTypeId) +{ + IBase* pIBaseClass = (IBase *)pBase; + + try { + if (pClassTypeId == nullptr) + throw ENumbersInterfaceException (NUMBERS_ERROR_INVALIDPARAM); + IBase* pIBase = dynamic_cast<IBase*>(pIBaseClass); + if (!pIBase) + throw ENumbersInterfaceException(NUMBERS_ERROR_INVALIDCAST); + + *pClassTypeId = pIBase->ClassTypeId(); + + return NUMBERS_SUCCESS; + } + catch (ENumbersInterfaceException & Exception) { + return handleNumbersException(pIBaseClass, Exception); + } + catch (std::exception & StdException) { + return handleStdException(pIBaseClass, StdException); + } + catch (...) { + return handleUnhandledException(pIBaseClass); + } +} + /************************************************************************************************************************* Class implementation for Variable @@ -116,22 +142,8 @@ NumbersResult numbers_variable_setvalue(Numbers_Variable pVariable, Numbers_doub Function table lookup implementation **************************************************************************************************************************/ -NumbersResult _numbers_getprocaddress_internal(const char * pProcName, void ** ppProcAddress) +NumbersResult Numbers::Impl::Numbers_GetProcAddress (const char * pProcName, void ** ppProcAddress) { - static bool sbProcAddressMapHasBeenInitialized = false; - static std::map<std::string, void*> sProcAddressMap; - if (!sbProcAddressMapHasBeenInitialized) { - sProcAddressMap["numbers_variable_getvalue"] = (void*)&numbers_variable_getvalue; - sProcAddressMap["numbers_variable_setvalue"] = (void*)&numbers_variable_setvalue; - sProcAddressMap["numbers_createvariable"] = (void*)&numbers_createvariable; - sProcAddressMap["numbers_getversion"] = (void*)&numbers_getversion; - sProcAddressMap["numbers_getlasterror"] = (void*)&numbers_getlasterror; - sProcAddressMap["numbers_releaseinstance"] = (void*)&numbers_releaseinstance; - sProcAddressMap["numbers_acquireinstance"] = (void*)&numbers_acquireinstance; - sProcAddressMap["numbers_getsymbollookupmethod"] = (void*)&numbers_getsymbollookupmethod; - - sbProcAddressMapHasBeenInitialized = true; - } if (pProcName == nullptr) return NUMBERS_ERROR_INVALIDPARAM; if (ppProcAddress == nullptr) @@ -139,15 +151,28 @@ NumbersResult _numbers_getprocaddress_internal(const char * pProcName, void ** p *ppProcAddress = nullptr; std::string sProcName (pProcName); - auto procPair = sProcAddressMap.find(sProcName); - if (procPair == sProcAddressMap.end()) { - return NUMBERS_ERROR_COULDNOTFINDLIBRARYEXPORT; - } - else { - *ppProcAddress = procPair->second; - return NUMBERS_SUCCESS; - } + if (sProcName == "numbers_base_classtypeid") + *ppProcAddress = (void*) &numbers_base_classtypeid; + if (sProcName == "numbers_variable_getvalue") + *ppProcAddress = (void*) &numbers_variable_getvalue; + if (sProcName == "numbers_variable_setvalue") + *ppProcAddress = (void*) &numbers_variable_setvalue; + if (sProcName == "numbers_createvariable") + *ppProcAddress = (void*) &numbers_createvariable; + if (sProcName == "numbers_getversion") + *ppProcAddress = (void*) &numbers_getversion; + if (sProcName == "numbers_getlasterror") + *ppProcAddress = (void*) &numbers_getlasterror; + if (sProcName == "numbers_releaseinstance") + *ppProcAddress = (void*) &numbers_releaseinstance; + if (sProcName == "numbers_acquireinstance") + *ppProcAddress = (void*) &numbers_acquireinstance; + if (sProcName == "numbers_getsymbollookupmethod") + *ppProcAddress = (void*) &numbers_getsymbollookupmethod; + if (*ppProcAddress == nullptr) + return NUMBERS_ERROR_COULDNOTFINDLIBRARYEXPORT; + return NUMBERS_SUCCESS; } /************************************************************************************************************************* @@ -299,7 +324,7 @@ NumbersResult numbers_getsymbollookupmethod(Numbers_pvoid * pSymbolLookupMethod) try { if (pSymbolLookupMethod == nullptr) throw ENumbersInterfaceException (NUMBERS_ERROR_INVALIDPARAM); - *pSymbolLookupMethod = (void*)&_numbers_getprocaddress_internal; + *pSymbolLookupMethod = (void*)&Numbers::Impl::Numbers_GetProcAddress; return NUMBERS_SUCCESS; } catch (ENumbersInterfaceException & Exception) { diff --git a/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_types.hpp b/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_types.hpp index 2983e190..eda05a8a 100644 --- a/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_types.hpp +++ b/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_types.hpp @@ -4,7 +4,7 @@ Copyright (C) 2019 Numbers developers All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated C++-Header file with basic types in order to allow an easy use of Numbers library @@ -73,17 +73,36 @@ typedef void * Numbers_pvoid; **************************************************************************************************************************/ #define NUMBERS_SUCCESS 0 -#define NUMBERS_ERROR_NOTIMPLEMENTED 1 -#define NUMBERS_ERROR_INVALIDPARAM 2 -#define NUMBERS_ERROR_INVALIDCAST 3 -#define NUMBERS_ERROR_BUFFERTOOSMALL 4 -#define NUMBERS_ERROR_GENERICEXCEPTION 5 -#define NUMBERS_ERROR_COULDNOTLOADLIBRARY 6 -#define NUMBERS_ERROR_COULDNOTFINDLIBRARYEXPORT 7 -#define NUMBERS_ERROR_INCOMPATIBLEBINARYVERSION 8 +#define NUMBERS_ERROR_NOTIMPLEMENTED 1 /** functionality not implemented */ +#define NUMBERS_ERROR_INVALIDPARAM 2 /** an invalid parameter was passed */ +#define NUMBERS_ERROR_INVALIDCAST 3 /** a type cast failed */ +#define NUMBERS_ERROR_BUFFERTOOSMALL 4 /** a provided buffer is too small */ +#define NUMBERS_ERROR_GENERICEXCEPTION 5 /** a generic exception occurred */ +#define NUMBERS_ERROR_COULDNOTLOADLIBRARY 6 /** the library could not be loaded */ +#define NUMBERS_ERROR_COULDNOTFINDLIBRARYEXPORT 7 /** a required exported symbol could not be found in the library */ +#define NUMBERS_ERROR_INCOMPATIBLEBINARYVERSION 8 /** the version of the binary interface does not match the bindings interface */ /************************************************************************************************************************* - Declaration of handle classes + Error strings for Numbers +**************************************************************************************************************************/ + +inline const char * NUMBERS_GETERRORSTRING (NumbersResult nErrorCode) { + switch (nErrorCode) { + case NUMBERS_SUCCESS: return "no error"; + case NUMBERS_ERROR_NOTIMPLEMENTED: return "functionality not implemented"; + case NUMBERS_ERROR_INVALIDPARAM: return "an invalid parameter was passed"; + case NUMBERS_ERROR_INVALIDCAST: return "a type cast failed"; + case NUMBERS_ERROR_BUFFERTOOSMALL: return "a provided buffer is too small"; + case NUMBERS_ERROR_GENERICEXCEPTION: return "a generic exception occurred"; + case NUMBERS_ERROR_COULDNOTLOADLIBRARY: return "the library could not be loaded"; + case NUMBERS_ERROR_COULDNOTFINDLIBRARYEXPORT: return "a required exported symbol could not be found in the library"; + case NUMBERS_ERROR_INCOMPATIBLEBINARYVERSION: return "the version of the binary interface does not match the bindings interface"; + default: return "unknown error"; + } +} + +/************************************************************************************************************************* + Declaration of handle classes **************************************************************************************************************************/ typedef NumbersHandle Numbers_Base; diff --git a/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers.lpr b/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers.lpr index d07f9cc0..79ec22cb 100644 --- a/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers.lpr +++ b/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers.lpr @@ -4,7 +4,7 @@ All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated Pascal project file in order to allow easy development of Numbers library. @@ -27,6 +27,7 @@ sysutils; exports + numbers_base_classtypeid, numbers_variable_getvalue, numbers_variable_setvalue, numbers_createvariable, @@ -36,6 +37,10 @@ numbers_acquireinstance, numbers_getsymbollookupmethod; +{$IFDEF NUMBERS_INCLUDE_RES_FILE} +{$R *.res} +{$ENDIF NUMBERS_INCLUDE_RES_FILE} + begin end. diff --git a/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers_exception.pas b/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers_exception.pas index a9f0591f..2d35f06a 100644 --- a/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers_exception.pas +++ b/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers_exception.pas @@ -4,7 +4,7 @@ All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated Pascal exception class definition file in order to allow easy development of Numbers library. The functions in this file need to be implemented. It needs to be generated only once. diff --git a/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers_exports.pas b/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers_exports.pas index 69f3fd84..3f71da29 100644 --- a/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers_exports.pas +++ b/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers_exports.pas @@ -4,7 +4,7 @@ All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated Pascal export implementation file in order to allow easy development of Numbers library. The functions in this file need to be implemented. It needs to be generated only once. @@ -30,6 +30,15 @@ interface Class export definition of Base **************************************************************************************************************************) +(** +* Get Class Type Id +* +* @param[in] pBase - Base instance. +* @param[out] pClassTypeId - Class type as a 64 bits integer +* @return error code or 0 (success) +*) +function numbers_base_classtypeid(pBase: TNumbersHandle; pClassTypeId: PQWord): TNumbersResult; cdecl; + (************************************************************************************************************************* Class export definition of Variable **************************************************************************************************************************) @@ -120,6 +129,41 @@ function _numbers_getprocaddress_internal(pProcName: PAnsiChar; out ppProcAddres implementation +function numbers_base_classtypeid(pBase: TNumbersHandle; pClassTypeId: PQWord): TNumbersResult; cdecl; +var + ResultClassTypeId: QWord; + ObjectBase: TObject; + IntfBase: INumbersBase; +begin + try + if not Assigned(pClassTypeId) then + raise ENumbersException.Create(NUMBERS_ERROR_INVALIDPARAM); + if not Assigned(pBase) then + raise ENumbersException.Create(NUMBERS_ERROR_INVALIDPARAM); + + ObjectBase := TObject(pBase); + if Supports(ObjectBase, INumbersBase) then begin + IntfBase := ObjectBase as INumbersBase; + ResultClassTypeId := IntfBase.ClassTypeId(); + + pClassTypeId^ := ResultClassTypeId; + end else + raise ENumbersException.Create(NUMBERS_ERROR_INVALIDCAST); + + Result := NUMBERS_SUCCESS; + except + On E: ENumbersException do begin + Result := HandleNumbersException(ObjectBase , E); + end; + On E: Exception do begin + Result := HandleStdException(ObjectBase , E); + end + else begin + Result := HandleUnhandledException(ObjectBase); + end; + end; +end; + function numbers_variable_getvalue(pVariable: TNumbersHandle; pValue: PDouble): TNumbersResult; cdecl; var ResultValue: Double; @@ -350,7 +394,9 @@ function _numbers_getprocaddress_internal(pProcName: PAnsiChar; out ppProcAddres result := NUMBERS_SUCCESS; ppProcAddress := nil; - if (pProcName = 'numbers_variable_getvalue') then + if (pProcName = 'numbers_base_classtypeid') then + ppProcAddress := @numbers_base_classtypeid + else if (pProcName = 'numbers_variable_getvalue') then ppProcAddress := @numbers_variable_getvalue else if (pProcName = 'numbers_variable_setvalue') then ppProcAddress := @numbers_variable_setvalue diff --git a/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers_interfaces.pas b/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers_interfaces.pas index b94de2ad..504a9162 100644 --- a/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers_interfaces.pas +++ b/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers_interfaces.pas @@ -4,7 +4,7 @@ All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated Pascal interface definition file in order to allow easy development of Numbers library. The functions in this file need to be implemented. It needs to be generated only once. @@ -39,6 +39,7 @@ interface procedure RegisterErrorMessage(const AErrorMessage: String); procedure IncRefCount(); function DecRefCount(): Boolean; + function ClassTypeId(): QWord; end; diff --git a/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers_types.pas b/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers_types.pas index 17c593e8..67d0ffed 100644 --- a/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers_types.pas +++ b/Examples/Injection/Numbers_component/Implementations/Pascal/Interfaces/numbers_types.pas @@ -4,7 +4,7 @@ All rights reserved. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. Abstract: This is an autogenerated Pascal type definition file in order to allow easy development of Numbers library. The functions in this file need to be implemented. It needs to be generated only once. From 8c416eb6e7e0418ba35e600b399f254a7ab6ae47 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 19:50:45 -0700 Subject: [PATCH 090/143] Add ClassTypeId descriptpion to documentation --- Documentation/IDL.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/IDL.md b/Documentation/IDL.md index f0faa3bc..2a9b8447 100644 --- a/Documentation/IDL.md +++ b/Documentation/IDL.md @@ -183,6 +183,7 @@ Element **\<global>** of type **CT\_Global** | errormethod | **ST\_Name** | required | | Specifies the name of the method used to query the last error that occured during the call of class's method. | | versionmethod | **ST\_Name** | required | | Specifies the name of the method used to obtain the major, minor and micro version of the component. | | prereleasemethod | **ST\_Name** | required | | Specifies the name of the method used to obtain the prerelease information of the component. | +| classtypeidmethod | **ST\_Name** | required | | Specifies the name of the method in base class used to get class type id of an object. | | buildinfomethod | **ST\_Name** | optional | | Specifies the name of the method used to obtain the build information of the component. | | injectionmethod | **ST\_Name** | optional | | Specifies the name of the method used to inject the symbollookupmethod another ACT component into this component at runtime. | | symbollookupmethod | **ST\_Name** | optional | | Specifies the name of the method that returns the address of a given symbol exported by this component. | @@ -198,6 +199,7 @@ The `acquiremethod`- and `releasemethod`-attributes must each be the name of a \ The `versionmethod`-attribute must be the name of a \<method> within the \<global> element of a component that has exactly three parameters. The three parameters MUST be of type `type="uint32"` and `pass="out"`. The `prereleasemethod`-attribute is optional an can be the name of a \<method> within the \<global> element of a component that has two parameters. The first parameter MUST be of type `type="bool"` and `pass="return"`, the second parameter MUST be of type `type="string"` and `pass="out"`. +The `classtypeidmethod`- must be the name of a \<method> within baseclassname \<class> element of a component that has exactly one parameter with `type="uint64"` and `pass="return"`. The `buildinfomethod`-attribute is optional an can be the name of a \<method> within the \<global> element of a component that has two parameters. The first parameter MUST be of type `type="bool"` and `pass="return"`, the second parameter MUST be of type `type="string"` and `pass="out"`. From 19b02a77a6e63d47b453dd4410317fcaa6c5dcf5 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 19:51:09 -0700 Subject: [PATCH 091/143] Fix style --- Source/buildbindingpython.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/Source/buildbindingpython.go b/Source/buildbindingpython.go index ef5e5898..1837f9db 100644 --- a/Source/buildbindingpython.go +++ b/Source/buildbindingpython.go @@ -750,13 +750,11 @@ func generateCTypesParameter(param ComponentDefinitionParam, className string, m func writePythonClass(component ComponentDefinition, class ComponentDefinitionClass, w LanguageWriter, NameSpace string) error { pythonBaseClassName := fmt.Sprintf("%s", component.Global.BaseClassName) - w.Writeln("''' Class Implementation for %s", class.ClassName) w.Writeln("'''") parentClass := "" - if (!component.isBaseClass(class)) { if (class.ParentClass != "") { parentClass = fmt.Sprintf("%s", class.ParentClass) From 121f8bd5ed820142b8df7a464c1cd68469d4f4e1 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 19:51:40 -0700 Subject: [PATCH 092/143] Return ClassTypeId explicitely --- Source/buildimplementationcpp.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Source/buildimplementationcpp.go b/Source/buildimplementationcpp.go index d16bf26a..35b743a7 100644 --- a/Source/buildimplementationcpp.go +++ b/Source/buildimplementationcpp.go @@ -430,9 +430,7 @@ func writeCPPClassInterface(component ComponentDefinition, class ComponentDefini classTypeId, chashHashString := class.classTypeId(NameSpace) w.Writeln("%s", methodstring) w.Writeln(" {") - w.Writeln(" // First 64 bits of SHA1 of a string: \"%s\"", chashHashString) - w.Writeln(" static const %s_uint64 s_%sTypeId = 0x%XUL;", NameSpace, class.ClassName, classTypeId) - w.Writeln(" return s_%sTypeId;", class.ClassName) + w.Writeln(" return 0x%XUL; // First 64 bits of SHA1 of a string: \"%s\"", classTypeId, chashHashString) w.Writeln(" }") w.Writeln("") } From 45c5d1132b76a33737dea8c54591466b6d565ee4 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 22:04:45 -0700 Subject: [PATCH 093/143] Update docker.sh helper script --- Build/docker.sh | 29 +++++++++++++++++++++++++++-- Build/run-docker.sh | 8 -------- 2 files changed, 27 insertions(+), 10 deletions(-) delete mode 100755 Build/run-docker.sh diff --git a/Build/docker.sh b/Build/docker.sh index 2889cab3..158d36c3 100755 --- a/Build/docker.sh +++ b/Build/docker.sh @@ -4,5 +4,30 @@ set -euxo pipefail cd "$(dirname "$0")" -echo "Build Docker image" -docker build -t act-build --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) . +case "$1" in + build) + docker build -t act-build --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) . + ;; + act) + docker run -it --rm -v $PWD/..:/data act-build /data/Build/build.sh + ;; + examples) + docker run -it --rm -v $PWD/..:/data act-build /data/Examples/build.sh + ;; + all) + docker run -it --rm -v $PWD/..:/data act-build /data/Build/build.sh + docker run -it --rm -v $PWD/..:/data act-build /data/Examples/build.sh + ;; + cli) + docker run -it --rm -v $PWD/..:/data --entrypoint bash act-build -l + ;; + *) + echo "Use one of availbale commands:" + echo " ./docker.sh build - build docker image" + echo " ./docker.sh act - build ACT binaries" + echo " ./docker.sh examples - build and run projects in Examples folder" + echo " ./docker.sh all - build ACT binaries and then build and run projects in Examples folder" + echo " ./docker.sh cli - open bash session inside Docker with source code mapped to '/data' directory" + exit 1 + ;; +esac diff --git a/Build/run-docker.sh b/Build/run-docker.sh deleted file mode 100755 index 6300fc7b..00000000 --- a/Build/run-docker.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -set -euxo pipefail - -cd "$(dirname "$0")" - -docker run -it --rm -v $PWD/..:/data act-build /data/Build/build.sh -docker run -it --rm -v $PWD/..:/data act-build /data/Examples/build.sh From f29ab2317a8e90171c8d2f1dd6854663f761dc5c Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 22:41:27 -0700 Subject: [PATCH 094/143] Update documentation --- Build/Readme.md | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/Build/Readme.md b/Build/Readme.md index f83fc921..b9244315 100644 --- a/Build/Readme.md +++ b/Build/Readme.md @@ -37,4 +37,44 @@ https://github.com/pavel-a/ddverpatch/releases Call like this ``` verpatch.exe ..\act.exe /high /va 1.5.0 /pv "1.5.0-RC1+buildnumber-5" /s copyright "(c) 2018-2019 ACT Developers" /s desc "ACT is a code generator for software components" /s productName "Automatic Component Toolkit" -``` \ No newline at end of file +``` + +## Docker + +Docker image can be used to build ACT and all its example. + +**Build Docker image:** +``` +./Build/build.sh +``` + +**Build ACT and all examples** +``` +# go into root folder of this repo +docker run -it --rm -v $PWD:/data act-build +``` + +**Run Docker image interactively:** +``` +# go into root folder of this repo +docker run -it --rm -v $PWD:/data --entrypoint bash act-build -l +``` +Source code is available in `/data` directory. + +**Useful scripts** +| Script | Description| +|--------|------------| +| `./Build/docker.sh build` | build docker image | +| `./Build/docker.sh act` | build ACT binaries | +| `./Build/docker.sh examples` | build and run projects in Examples folder | +| `./Build/docker.sh all` | build ACT binaries and then build and run projects in Examples folder" | +| `./Build/docker.sh cli` | open bash session inside Docker with source code mapped to '/data' directory" | +| Command to run in Docker cli mode (sources are mapped to `/data` directory): | +| `./Build/build.sh` | build ACT binaries | +| `./Examples/build.sh` | build and run projects in Examples folder (including updating Bindings and Interfaces) | +| `./Examples/RTTI/build.sh` | build and run projects in Examples/RTTI folder (including updating Bindings and Interfaces) | +| `./Examples/Injection/build.sh` | build and run projects in Examples/RTTI folder (including updating Bindings and Interfaces) | +| `./Examples/RTTI/RTTI_component/Implementations/Cpp/build.sh` | build RTTI C++ library implementation | +| `./Examples/RTTI/RTTI_component/Implementations/Pascal/build.sh` | build RTTI Pascal library implementation | +| `./Examples/RTTI/RTTI_component/Examples/CppDynamic/build.sh` | build and run RTTI C++ Example (requres C++ and Pascal libraries) | +| `./Examples/RTTI/RTTI_component/Examples/Python/build.sh` | build and run RTTI Python Example (requres C++ and Pascal libraries) | From dc1a68fbf5b34bfc4d4866aeba07b701273dbe57 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 22:42:10 -0700 Subject: [PATCH 095/143] Better support for FPC 3.0.4 --- Build/build.inc | 5 ++++- .../Injection/Calculation_component/Examples/Pascal/build.sh | 2 +- .../Calculation_component/Implementations/Pascal/build.sh | 3 ++- .../Numbers_component/Implementations/Pascal/build.sh | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Build/build.inc b/Build/build.inc index 54da1599..a4a18347 100644 --- a/Build/build.inc +++ b/Build/build.inc @@ -34,18 +34,21 @@ case $OS in OSEXT='.linux' OSLIBEXT='.so' OSEXEEXT= + FPC_TARGET='linux' ;; Windows*) OSEXT='.exe' OSLIBEXT='.dll' OSEXEEXT='.exe' + FPC_TARGET='win64' ;; Darwin*) OSEXT='.darwin' OSLIBEXT='.dylib' OSEXEEXT= + FPC_TARGET='darwin' ;; - *) ;; + *) echo "[Failed] Can't detect OS. Only Windows, Linux and MacOS are supported."; exit 1; ;; esac export ACT=act$OSEXT diff --git a/Examples/Injection/Calculation_component/Examples/Pascal/build.sh b/Examples/Injection/Calculation_component/Examples/Pascal/build.sh index 0b94a90d..46928434 100755 --- a/Examples/Injection/Calculation_component/Examples/Pascal/build.sh +++ b/Examples/Injection/Calculation_component/Examples/Pascal/build.sh @@ -8,7 +8,7 @@ source ../../../../../Build/build.inc echo "Build Pascal example" rm -rf build mkdir build -fpc -Fu../../../Calculation_component/Bindings/Pascal -Fu../../../Numbers_component/Bindings/Pascal -FU./build -o./build/Calculation_Example$OSEXEEXT Calculation_Example.lpr +fpc -Fu../../../Calculation_component/Bindings/Pascal -Fu../../../Numbers_component/Bindings/Pascal -fPIC -T$FPC_TARGET -FU./build -o./build/Calculation_Example$OSEXEEXT Calculation_Example.lpr pushd build diff --git a/Examples/Injection/Calculation_component/Implementations/Pascal/build.sh b/Examples/Injection/Calculation_component/Implementations/Pascal/build.sh index d7b63da6..874d254d 100755 --- a/Examples/Injection/Calculation_component/Implementations/Pascal/build.sh +++ b/Examples/Injection/Calculation_component/Implementations/Pascal/build.sh @@ -8,4 +8,5 @@ source ../../../../../Build/build.inc echo "Build Pascal implementation" [ -d build ] && rm -rf build mkdir build -fpc -Fu../../Bindings/Pascal -Fu../../../Numbers_component/Bindings/Pascal -FuInterfaces -FuStub -FU./build -o./build/calculation$OSLIBEXT Interfaces/calculation.lpr +fpc -Fu../../Bindings/Pascal -Fu../../../Numbers_component/Bindings/Pascal -FuInterfaces -FuStub -fPIC -T$FPC_TARGET -FU./build -o./build/calculation$OSLIBEXT Interfaces/calculation.lpr +echo $OS \ No newline at end of file diff --git a/Examples/Injection/Numbers_component/Implementations/Pascal/build.sh b/Examples/Injection/Numbers_component/Implementations/Pascal/build.sh index ac2e58d0..52913406 100755 --- a/Examples/Injection/Numbers_component/Implementations/Pascal/build.sh +++ b/Examples/Injection/Numbers_component/Implementations/Pascal/build.sh @@ -8,4 +8,4 @@ source ../../../../../Build/build.inc echo "Build Pascal implementation" [ -d build ] && rm -rf build mkdir build -fpc -Fu../../Bindings/Pascal -FuInterfaces -FuStub -FU./build -o./build/numbers$OSLIBEXT Interfaces/numbers.lpr +fpc -Fu../../Bindings/Pascal -FuInterfaces -FuStub -fPIC -T$FPC_TARGET -FU./build -o./build/numbers$OSLIBEXT Interfaces/numbers.lpr From f186d0566ba87528898721f4e5c2dc5089465322 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 22:42:28 -0700 Subject: [PATCH 096/143] Save stub code for FPC 3.0.4 --- Build/Dockerfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Build/Dockerfile b/Build/Dockerfile index b02442d7..c1d88bd9 100644 --- a/Build/Dockerfile +++ b/Build/Dockerfile @@ -28,6 +28,10 @@ RUN dnf -y install cmake RUN dnf -y install ninja-build # Free Pascal +# 3.0.4 should be used for validating compiler base compatibility. +# RUN (cd /opt && curl -O -L 'http://downloads.sourceforge.net/project/freepascal/Linux/3.0.4/fpc-3.0.4-1.x86_64.rpm' \ +# && rpm -i fpc-3.0.4-1.x86_64.rpm) +# Using 3.2.2 until PolymorphicFactory is reworked to not using generics that are not full functional in 3.0.4. RUN (cd /opt && curl -O -L 'http://downloads.sourceforge.net/project/freepascal/Linux/3.2.2/fpc-3.2.2-1.x86_64.rpm' \ && rpm -i fpc-3.2.2-1.x86_64.rpm) From f258f7cb7fc96bfcb73cdf73da049a7040c76bb0 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Tue, 26 Oct 2021 22:43:10 -0700 Subject: [PATCH 097/143] Return ClassTypeId without intermediate variables --- .../Cpp/Interfaces/calculation_interfaces.hpp | 4 +-- .../Cpp/Interfaces/numbers_interfaces.hpp | 4 +-- .../Cpp/Interfaces/rtti_interfaces.hpp | 36 +++++-------------- 3 files changed, 11 insertions(+), 33 deletions(-) diff --git a/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfaces.hpp b/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfaces.hpp index 73076d44..95ffc645 100644 --- a/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfaces.hpp +++ b/Examples/Injection/Calculation_component/Implementations/Cpp/Interfaces/calculation_interfaces.hpp @@ -212,9 +212,7 @@ class ICalculator : public virtual IBase { */ Calculation_uint64 ClassTypeId() override { - // First 64 bits of SHA1 of a string: "Calculation::Calculator" - static const Calculation_uint64 s_CalculatorTypeId = 0xB23F514353D0C606UL; - return s_CalculatorTypeId; + return 0xB23F514353D0C606UL; // First 64 bits of SHA1 of a string: "Calculation::Calculator" } /** diff --git a/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfaces.hpp b/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfaces.hpp index 516b97f3..c1cc9128 100644 --- a/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfaces.hpp +++ b/Examples/Injection/Numbers_component/Implementations/Cpp/Interfaces/numbers_interfaces.hpp @@ -211,9 +211,7 @@ class IVariable : public virtual IBase { */ Numbers_uint64 ClassTypeId() override { - // First 64 bits of SHA1 of a string: "Numbers::Variable" - static const Numbers_uint64 s_VariableTypeId = 0x23934EDF762423EAUL; - return s_VariableTypeId; + return 0x23934EDF762423EAUL; // First 64 bits of SHA1 of a string: "Numbers::Variable" } /** diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp index bf317fee..a4abcb20 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp @@ -238,9 +238,7 @@ class IAnimal : public virtual IBase { */ RTTI_uint64 ClassTypeId() override { - // First 64 bits of SHA1 of a string: "RTTI::Animal" - static const RTTI_uint64 s_AnimalTypeId = 0x8B40467DA6D327AFUL; - return s_AnimalTypeId; + return 0x8B40467DA6D327AFUL; // First 64 bits of SHA1 of a string: "RTTI::Animal" } /** @@ -266,9 +264,7 @@ class IMammal : public virtual IAnimal { */ RTTI_uint64 ClassTypeId() override { - // First 64 bits of SHA1 of a string: "RTTI::Mammal" - static const RTTI_uint64 s_MammalTypeId = 0xBC9D5FA7750C1020UL; - return s_MammalTypeId; + return 0xBC9D5FA7750C1020UL; // First 64 bits of SHA1 of a string: "RTTI::Mammal" } }; @@ -288,9 +284,7 @@ class IReptile : public virtual IAnimal { */ RTTI_uint64 ClassTypeId() override { - // First 64 bits of SHA1 of a string: "RTTI::Reptile" - static const RTTI_uint64 s_ReptileTypeId = 0x6756AA8EA5802EC3UL; - return s_ReptileTypeId; + return 0x6756AA8EA5802EC3UL; // First 64 bits of SHA1 of a string: "RTTI::Reptile" } }; @@ -310,9 +304,7 @@ class IGiraffe : public virtual IMammal { */ RTTI_uint64 ClassTypeId() override { - // First 64 bits of SHA1 of a string: "RTTI::Giraffe" - static const RTTI_uint64 s_GiraffeTypeId = 0x9751971BD2C2D958UL; - return s_GiraffeTypeId; + return 0x9751971BD2C2D958UL; // First 64 bits of SHA1 of a string: "RTTI::Giraffe" } }; @@ -332,9 +324,7 @@ class ITiger : public virtual IMammal { */ RTTI_uint64 ClassTypeId() override { - // First 64 bits of SHA1 of a string: "RTTI::Tiger" - static const RTTI_uint64 s_TigerTypeId = 0x8D007E7B5F7BAF4UL; - return s_TigerTypeId; + return 0x8D007E7B5F7BAF4UL; // First 64 bits of SHA1 of a string: "RTTI::Tiger" } /** @@ -359,9 +349,7 @@ class ISnake : public virtual IReptile { */ RTTI_uint64 ClassTypeId() override { - // First 64 bits of SHA1 of a string: "RTTI::Snake" - static const RTTI_uint64 s_SnakeTypeId = 0x5F6826EF909803B2UL; - return s_SnakeTypeId; + return 0x5F6826EF909803B2UL; // First 64 bits of SHA1 of a string: "RTTI::Snake" } }; @@ -381,9 +369,7 @@ class ITurtle : public virtual IReptile { */ RTTI_uint64 ClassTypeId() override { - // First 64 bits of SHA1 of a string: "RTTI::Turtle" - static const RTTI_uint64 s_TurtleTypeId = 0x8E551B208A2E8321UL; - return s_TurtleTypeId; + return 0x8E551B208A2E8321UL; // First 64 bits of SHA1 of a string: "RTTI::Turtle" } }; @@ -403,9 +389,7 @@ class IAnimalIterator : public virtual IBase { */ RTTI_uint64 ClassTypeId() override { - // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" - static const RTTI_uint64 s_AnimalIteratorTypeId = 0xF1917FE6BBE77831UL; - return s_AnimalIteratorTypeId; + return 0xF1917FE6BBE77831UL; // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" } /** @@ -431,9 +415,7 @@ class IZoo : public virtual IBase { */ RTTI_uint64 ClassTypeId() override { - // First 64 bits of SHA1 of a string: "RTTI::Zoo" - static const RTTI_uint64 s_ZooTypeId = 0x2262ABE80A5E7878UL; - return s_ZooTypeId; + return 0x2262ABE80A5E7878UL; // First 64 bits of SHA1 of a string: "RTTI::Zoo" } /** From 81ea4d24c2b84a80a3d155156ce0a0a79eb61e09 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Wed, 27 Oct 2021 11:42:13 -0700 Subject: [PATCH 098/143] Specialized PolymorphicFactories for FPC 3.0.4 --- Source/buildbindingpascal.go | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/Source/buildbindingpascal.go b/Source/buildbindingpascal.go index 5fa01b9c..33b387a5 100644 --- a/Source/buildbindingpascal.go +++ b/Source/buildbindingpascal.go @@ -417,6 +417,12 @@ func buildDynamicPascalImplementation(component ComponentDefinition, w LanguageW w.Writeln(" class function Make(Wrapper: T%sWrapper; Handle: T%sHandle): _T; static;", NameSpace, NameSpace) w.Writeln(" end;") + for i := 0; i < len(component.Classes); i++ { + class := component.Classes[i] + fullClassName := fmt.Sprintf("T%s%s", strings.ToUpper(NameSpace), class.ClassName) + w.Writeln(" function T%sPolymorphicFactoryMake%s(Wrapper: T%sWrapper; Handle: T%sHandle): %s;", NameSpace, class.ClassName, NameSpace, NameSpace, fullClassName) + } + w.Writeln("") w.Writeln("implementation") w.Writeln("") @@ -449,7 +455,14 @@ func buildDynamicPascalImplementation(component ComponentDefinition, w LanguageW w.Writeln(" end;") w.Writeln(" if Result = nil then Result := _B.Create(Wrapper, Handle);") w.Writeln(" end;") - + for i := 0; i < len(component.Classes); i++ { + class := component.Classes[i] + fullClassName := fmt.Sprintf("T%s%s", strings.ToUpper(NameSpace), class.ClassName) + w.Writeln(" function T%sPolymorphicFactoryMake%s(Wrapper: T%sWrapper; Handle: T%sHandle): %s;", NameSpace, class.ClassName, NameSpace, NameSpace, fullClassName) + w.Writeln(" begin") + w.Writeln(" Result := T%sPolymorphicFactory<%s, %s>.Make(Wrapper, Handle);", NameSpace, fullClassName, fullClassName) + w.Writeln(" end;") + } w.Writeln("") w.Writeln("(*************************************************************************************************************************") w.Writeln(" Exception implementation") @@ -1067,7 +1080,11 @@ func writePascalClassMethodImplementation(method ComponentDefinitionMethod, w La initCommands = append(initCommands, "H"+param.ParamName+" := nil;") callFunctionParameters = callFunctionParameters + "H" + param.ParamName resultCommands = append(resultCommands, fmt.Sprintf(" if Assigned(H%s) then", param.ParamName)) - resultCommands = append(resultCommands, fmt.Sprintf(" Result := T%sPolymorphicFactory<T%s%s, T%s%s>.Make(%s, H%s);", theNameSpace, theNameSpace, theParamClass, theNameSpace, theParamClass, theWrapperInstance, param.ParamName)) + if NameSpace == theNameSpace { + resultCommands = append(resultCommands, fmt.Sprintf(" Result := T%sPolymorphicFactory<T%s%s, T%s%s>.Make(%s, H%s);", theNameSpace, theNameSpace, theParamClass, theNameSpace, theParamClass, theWrapperInstance, param.ParamName)) + } else { + resultCommands = append(resultCommands, fmt.Sprintf(" Result := T%sPolymorphicFactoryMake%s(%s, H%s);", theNameSpace, theParamClass, theWrapperInstance, param.ParamName)) + } default: return fmt.Errorf("invalid method parameter type \"%s\" for %s.%s (%s)", param.ParamType, ClassName, method.MethodName, param.ParamName) From 80e36d04dc9d7c9d7bdb0c9a91e730c9798be343 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Wed, 27 Oct 2021 11:42:29 -0700 Subject: [PATCH 099/143] Update bindings for FPC 3.0.4 --- .../Bindings/Pascal/Unit_Calculation.pas | 16 ++++-- .../Bindings/Pascal/Unit_Numbers.pas | 10 ++++ .../Bindings/Pascal/Unit_RTTI.pas | 50 +++++++++++++++++++ 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/Examples/Injection/Calculation_component/Bindings/Pascal/Unit_Calculation.pas b/Examples/Injection/Calculation_component/Bindings/Pascal/Unit_Calculation.pas index af3fcd35..e5ee03d6 100644 --- a/Examples/Injection/Calculation_component/Bindings/Pascal/Unit_Calculation.pas +++ b/Examples/Injection/Calculation_component/Bindings/Pascal/Unit_Calculation.pas @@ -330,6 +330,8 @@ TCalculationWrapper = class(TObject) TCalculationPolymorphicFactory<_T:class; _B> = record class function Make(Wrapper: TCalculationWrapper; Handle: TCalculationHandle): _T; static; end; + function TCalculationPolymorphicFactoryMakeBase(Wrapper: TCalculationWrapper; Handle: TCalculationHandle): TCALCULATIONBase; + function TCalculationPolymorphicFactoryMakeCalculator(Wrapper: TCalculationWrapper; Handle: TCalculationHandle): TCALCULATIONCalculator; implementation @@ -358,6 +360,14 @@ implementation end; if Result = nil then Result := _B.Create(Wrapper, Handle); end; + function TCalculationPolymorphicFactoryMakeBase(Wrapper: TCalculationWrapper; Handle: TCalculationHandle): TCALCULATIONBase; + begin + Result := TCalculationPolymorphicFactory<TCALCULATIONBase, TCALCULATIONBase>.Make(Wrapper, Handle); + end; + function TCalculationPolymorphicFactoryMakeCalculator(Wrapper: TCalculationWrapper; Handle: TCalculationHandle): TCALCULATIONCalculator; + begin + Result := TCalculationPolymorphicFactory<TCALCULATIONCalculator, TCALCULATIONCalculator>.Make(Wrapper, Handle); + end; (************************************************************************************************************************* Exception implementation @@ -451,7 +461,7 @@ implementation HVariable := nil; FWrapper.CheckError(Self, FWrapper.CalculationCalculator_GetEnlistedVariableFunc(FHandle, AIndex, HVariable)); if Assigned(HVariable) then - Result := TNumbersPolymorphicFactory<TNumbersVariable, TNumbersVariable>.Make(FWrapper.NumbersWrapper, HVariable); + Result := TNumbersPolymorphicFactoryMakeVariable(FWrapper.NumbersWrapper, HVariable); end; procedure TCalculationCalculator.ClearVariables(); @@ -467,7 +477,7 @@ implementation HInstance := nil; FWrapper.CheckError(Self, FWrapper.CalculationCalculator_MultiplyFunc(FHandle, HInstance)); if Assigned(HInstance) then - Result := TNumbersPolymorphicFactory<TNumbersVariable, TNumbersVariable>.Make(FWrapper.NumbersWrapper, HInstance); + Result := TNumbersPolymorphicFactoryMakeVariable(FWrapper.NumbersWrapper, HInstance); end; function TCalculationCalculator.Add(): TNumbersVariable; @@ -478,7 +488,7 @@ implementation HInstance := nil; FWrapper.CheckError(Self, FWrapper.CalculationCalculator_AddFunc(FHandle, HInstance)); if Assigned(HInstance) then - Result := TNumbersPolymorphicFactory<TNumbersVariable, TNumbersVariable>.Make(FWrapper.NumbersWrapper, HInstance); + Result := TNumbersPolymorphicFactoryMakeVariable(FWrapper.NumbersWrapper, HInstance); end; (************************************************************************************************************************* diff --git a/Examples/Injection/Numbers_component/Bindings/Pascal/Unit_Numbers.pas b/Examples/Injection/Numbers_component/Bindings/Pascal/Unit_Numbers.pas index 21387fac..6c995006 100644 --- a/Examples/Injection/Numbers_component/Bindings/Pascal/Unit_Numbers.pas +++ b/Examples/Injection/Numbers_component/Bindings/Pascal/Unit_Numbers.pas @@ -273,6 +273,8 @@ TNumbersWrapper = class(TObject) TNumbersPolymorphicFactory<_T:class; _B> = record class function Make(Wrapper: TNumbersWrapper; Handle: TNumbersHandle): _T; static; end; + function TNumbersPolymorphicFactoryMakeBase(Wrapper: TNumbersWrapper; Handle: TNumbersHandle): TNUMBERSBase; + function TNumbersPolymorphicFactoryMakeVariable(Wrapper: TNumbersWrapper; Handle: TNumbersHandle): TNUMBERSVariable; implementation @@ -301,6 +303,14 @@ implementation end; if Result = nil then Result := _B.Create(Wrapper, Handle); end; + function TNumbersPolymorphicFactoryMakeBase(Wrapper: TNumbersWrapper; Handle: TNumbersHandle): TNUMBERSBase; + begin + Result := TNumbersPolymorphicFactory<TNUMBERSBase, TNUMBERSBase>.Make(Wrapper, Handle); + end; + function TNumbersPolymorphicFactoryMakeVariable(Wrapper: TNumbersWrapper; Handle: TNumbersHandle): TNUMBERSVariable; + begin + Result := TNumbersPolymorphicFactory<TNUMBERSVariable, TNUMBERSVariable>.Make(Wrapper, Handle); + end; (************************************************************************************************************************* Exception implementation diff --git a/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas b/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas index 70172e7d..52b4c6be 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas +++ b/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas @@ -445,6 +445,16 @@ TRTTIWrapper = class(TObject) TRTTIPolymorphicFactory<_T:class; _B> = record class function Make(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): _T; static; end; + function TRTTIPolymorphicFactoryMakeBase(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIBase; + function TRTTIPolymorphicFactoryMakeAnimal(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIAnimal; + function TRTTIPolymorphicFactoryMakeMammal(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIMammal; + function TRTTIPolymorphicFactoryMakeReptile(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIReptile; + function TRTTIPolymorphicFactoryMakeGiraffe(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIGiraffe; + function TRTTIPolymorphicFactoryMakeTiger(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTITiger; + function TRTTIPolymorphicFactoryMakeSnake(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTISnake; + function TRTTIPolymorphicFactoryMakeTurtle(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTITurtle; + function TRTTIPolymorphicFactoryMakeAnimalIterator(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIAnimalIterator; + function TRTTIPolymorphicFactoryMakeZoo(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIZoo; implementation @@ -481,6 +491,46 @@ implementation end; if Result = nil then Result := _B.Create(Wrapper, Handle); end; + function TRTTIPolymorphicFactoryMakeBase(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIBase; + begin + Result := TRTTIPolymorphicFactory<TRTTIBase, TRTTIBase>.Make(Wrapper, Handle); + end; + function TRTTIPolymorphicFactoryMakeAnimal(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIAnimal; + begin + Result := TRTTIPolymorphicFactory<TRTTIAnimal, TRTTIAnimal>.Make(Wrapper, Handle); + end; + function TRTTIPolymorphicFactoryMakeMammal(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIMammal; + begin + Result := TRTTIPolymorphicFactory<TRTTIMammal, TRTTIMammal>.Make(Wrapper, Handle); + end; + function TRTTIPolymorphicFactoryMakeReptile(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIReptile; + begin + Result := TRTTIPolymorphicFactory<TRTTIReptile, TRTTIReptile>.Make(Wrapper, Handle); + end; + function TRTTIPolymorphicFactoryMakeGiraffe(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIGiraffe; + begin + Result := TRTTIPolymorphicFactory<TRTTIGiraffe, TRTTIGiraffe>.Make(Wrapper, Handle); + end; + function TRTTIPolymorphicFactoryMakeTiger(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTITiger; + begin + Result := TRTTIPolymorphicFactory<TRTTITiger, TRTTITiger>.Make(Wrapper, Handle); + end; + function TRTTIPolymorphicFactoryMakeSnake(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTISnake; + begin + Result := TRTTIPolymorphicFactory<TRTTISnake, TRTTISnake>.Make(Wrapper, Handle); + end; + function TRTTIPolymorphicFactoryMakeTurtle(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTITurtle; + begin + Result := TRTTIPolymorphicFactory<TRTTITurtle, TRTTITurtle>.Make(Wrapper, Handle); + end; + function TRTTIPolymorphicFactoryMakeAnimalIterator(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIAnimalIterator; + begin + Result := TRTTIPolymorphicFactory<TRTTIAnimalIterator, TRTTIAnimalIterator>.Make(Wrapper, Handle); + end; + function TRTTIPolymorphicFactoryMakeZoo(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIZoo; + begin + Result := TRTTIPolymorphicFactory<TRTTIZoo, TRTTIZoo>.Make(Wrapper, Handle); + end; (************************************************************************************************************************* Exception implementation From 5956f2597a140596aaa703b6d73e12c5ddbba558 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Wed, 27 Oct 2021 11:42:42 -0700 Subject: [PATCH 100/143] Switch to FPC 3.0.4 in Docker --- Build/Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Build/Dockerfile b/Build/Dockerfile index c1d88bd9..f1159ced 100644 --- a/Build/Dockerfile +++ b/Build/Dockerfile @@ -29,11 +29,11 @@ RUN dnf -y install ninja-build # Free Pascal # 3.0.4 should be used for validating compiler base compatibility. -# RUN (cd /opt && curl -O -L 'http://downloads.sourceforge.net/project/freepascal/Linux/3.0.4/fpc-3.0.4-1.x86_64.rpm' \ -# && rpm -i fpc-3.0.4-1.x86_64.rpm) +RUN (cd /opt && curl -O -L 'http://downloads.sourceforge.net/project/freepascal/Linux/3.0.4/fpc-3.0.4-1.x86_64.rpm' \ + && rpm -i fpc-3.0.4-1.x86_64.rpm) # Using 3.2.2 until PolymorphicFactory is reworked to not using generics that are not full functional in 3.0.4. -RUN (cd /opt && curl -O -L 'http://downloads.sourceforge.net/project/freepascal/Linux/3.2.2/fpc-3.2.2-1.x86_64.rpm' \ - && rpm -i fpc-3.2.2-1.x86_64.rpm) +# RUN (cd /opt && curl -O -L 'http://downloads.sourceforge.net/project/freepascal/Linux/3.2.2/fpc-3.2.2-1.x86_64.rpm' \ +# && rpm -i fpc-3.2.2-1.x86_64.rpm) # Golang RUN (cd /opt && curl -O -L https://golang.org/dl/go1.17.2.linux-amd64.tar.gz \ From ffe8e4126b299c34a111adfd1da2c014710cf1cb Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Wed, 27 Oct 2021 12:23:18 -0700 Subject: [PATCH 101/143] Fix hardcodded namespace --- Source/buildbindingcsharp.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Source/buildbindingcsharp.go b/Source/buildbindingcsharp.go index 3717079d..40cde0d7 100644 --- a/Source/buildbindingcsharp.go +++ b/Source/buildbindingcsharp.go @@ -521,7 +521,9 @@ func writeCSharpClassMethodImplementation(method ComponentDefinitionMethod, w La defineCommands = append(defineCommands, fmt.Sprintf(" IntPtr new%s = IntPtr.Zero;", param.ParamName)) callFunctionParameter = "out new" + param.ParamName initCallParameter = callFunctionParameter - resultCommands = append(resultCommands, fmt.Sprintf(" A%s = Internal.RTTIWrapper.PolymorphicFactory<C%s>(new%s);", param.ParamName, param.ParamClass, param.ParamName)) + // TODO: Using plain NameSpace here for calling PolymorphicFactory is most likely incorrect. + // It should be extracted from param.ClassName. + resultCommands = append(resultCommands, fmt.Sprintf(" A%s = Internal.%sWrapper.PolymorphicFactory<C%s>(new%s);", param.ParamName, NameSpace, param.ParamClass, param.ParamName)) default: return fmt.Errorf("invalid method parameter type \"%s\" for %s.%s (%s)", param.ParamType, ClassName, method.MethodName, param.ParamName) @@ -580,7 +582,9 @@ func writeCSharpClassMethodImplementation(method ComponentDefinitionMethod, w La if (ParamTypeName == "IntPtr") { returnCodeLines = append(returnCodeLines, fmt.Sprintf(" return new%s;", param.ParamName)) } else { - returnCodeLines = append(returnCodeLines, fmt.Sprintf(" return Internal.RTTIWrapper.PolymorphicFactory<%s>(new%s);", ParamTypeName, param.ParamName)) + // TODO: Using plain NameSpace here for calling PolymorphicFactory is most likely incorrect. + // It should be extracted from param.ClassName. + returnCodeLines = append(returnCodeLines, fmt.Sprintf(" return Internal.%sWrapper.PolymorphicFactory<%s>(new%s);", NameSpace, ParamTypeName, param.ParamName)) } default: From 81c1db41aba8fbe21e874a3520e9628cbc2a086a Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Wed, 27 Oct 2021 12:31:37 -0700 Subject: [PATCH 102/143] Mono requires netstandard2.0 --- Source/buildbindingcsharp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/buildbindingcsharp.go b/Source/buildbindingcsharp.go index 40cde0d7..1f831452 100644 --- a/Source/buildbindingcsharp.go +++ b/Source/buildbindingcsharp.go @@ -1231,7 +1231,7 @@ func buildCSharpExampleProject(componentdefinition ComponentDefinition, w Langua w.Writeln("<Project Sdk=\"Microsoft.NET.Sdk\">") w.Writeln(" <PropertyGroup>") w.Writeln(" <OutputType>Exe</OutputType>") - w.Writeln(" <TargetFramework>netcoreapp2.0</TargetFramework>") + w.Writeln(" <TargetFramework>netstandard2.0</TargetFramework>") w.Writeln(" <StartupObject>%s.%s</StartupObject>", exampleName, exampleName) w.Writeln(" <ApplicationIcon />") w.Writeln(" <Platforms>x64</Platforms>") From 9bdf0802feda1124c6e73bace7388ad5c5cd9988 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Wed, 27 Oct 2021 12:47:43 -0700 Subject: [PATCH 103/143] Add CSharp example --- Examples/Injection/Calculation.xml | 1 + .../Bindings/CSharp/Calculation.cs | 255 ++++++++++++++++++ .../Examples/CSharp/Calculation_Example.cs | 52 ++++ .../CSharp/Calculation_Example.csproj | 20 ++ .../Examples/CSharp/Calculation_Example.sln | 25 ++ .../Examples/CSharp/build.sh | 28 ++ Examples/Injection/Numbers.xml | 1 + .../Bindings/CSharp/Numbers.cs | 216 +++++++++++++++ Examples/Injection/build.sh | 2 +- 9 files changed, 599 insertions(+), 1 deletion(-) create mode 100644 Examples/Injection/Calculation_component/Bindings/CSharp/Calculation.cs create mode 100644 Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.cs create mode 100644 Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.csproj create mode 100644 Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.sln create mode 100755 Examples/Injection/Calculation_component/Examples/CSharp/build.sh create mode 100644 Examples/Injection/Numbers_component/Bindings/CSharp/Numbers.cs diff --git a/Examples/Injection/Calculation.xml b/Examples/Injection/Calculation.xml index 02e20152..35e03a28 100644 --- a/Examples/Injection/Calculation.xml +++ b/Examples/Injection/Calculation.xml @@ -13,6 +13,7 @@ <bindings> <binding language="Cpp" indentation="tabs" /> <binding language="CppDynamic" indentation="tabs" /> + <binding language="CSharp" indentation="tabs" /> <binding language="Pascal" indentation="2spaces" /> <binding language="Python" indentation="tabs" /> </bindings> diff --git a/Examples/Injection/Calculation_component/Bindings/CSharp/Calculation.cs b/Examples/Injection/Calculation_component/Bindings/CSharp/Calculation.cs new file mode 100644 index 00000000..f453459a --- /dev/null +++ b/Examples/Injection/Calculation_component/Bindings/CSharp/Calculation.cs @@ -0,0 +1,255 @@ +using System; +using System.Text; +using System.Runtime.InteropServices; + +namespace Calculation { + + + namespace Internal { + + + public class CalculationWrapper + { + [DllImport("calculation.dll", EntryPoint = "calculation_base_classtypeid", CallingConvention=CallingConvention.Cdecl)] + public unsafe extern static Int32 Base_ClassTypeId (IntPtr Handle, out UInt64 AClassTypeId); + + [DllImport("calculation.dll", EntryPoint = "calculation_calculator_enlistvariable", CallingConvention=CallingConvention.Cdecl)] + public unsafe extern static Int32 Calculator_EnlistVariable (IntPtr Handle, IntPtr AVariable); + + [DllImport("calculation.dll", EntryPoint = "calculation_calculator_getenlistedvariable", CallingConvention=CallingConvention.Cdecl)] + public unsafe extern static Int32 Calculator_GetEnlistedVariable (IntPtr Handle, UInt32 AIndex, out IntPtr AVariable); + + [DllImport("calculation.dll", EntryPoint = "calculation_calculator_clearvariables", CallingConvention=CallingConvention.Cdecl)] + public unsafe extern static Int32 Calculator_ClearVariables (IntPtr Handle); + + [DllImport("calculation.dll", EntryPoint = "calculation_calculator_multiply", CallingConvention=CallingConvention.Cdecl)] + public unsafe extern static Int32 Calculator_Multiply (IntPtr Handle, out IntPtr AInstance); + + [DllImport("calculation.dll", EntryPoint = "calculation_calculator_add", CallingConvention=CallingConvention.Cdecl)] + public unsafe extern static Int32 Calculator_Add (IntPtr Handle, out IntPtr AInstance); + + [DllImport("calculation.dll", EntryPoint = "calculation_createcalculator", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 CreateCalculator (out IntPtr AInstance); + + [DllImport("calculation.dll", EntryPoint = "calculation_getversion", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 GetVersion (out UInt32 AMajor, out UInt32 AMinor, out UInt32 AMicro); + + [DllImport("calculation.dll", EntryPoint = "calculation_getlasterror", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 GetLastError (IntPtr AInstance, UInt32 sizeErrorMessage, out UInt32 neededErrorMessage, IntPtr dataErrorMessage, out Byte AHasError); + + [DllImport("calculation.dll", EntryPoint = "calculation_releaseinstance", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 ReleaseInstance (IntPtr AInstance); + + [DllImport("calculation.dll", EntryPoint = "calculation_acquireinstance", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 AcquireInstance (IntPtr AInstance); + + [DllImport("calculation.dll", EntryPoint = "calculation_injectcomponent", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 InjectComponent (byte[] ANameSpace, UInt64 ASymbolAddressMethod); + + [DllImport("calculation.dll", EntryPoint = "calculation_getsymbollookupmethod", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 GetSymbolLookupMethod (out UInt64 ASymbolLookupMethod); + + public static void ThrowError(IntPtr Handle, Int32 errorCode) + { + String sMessage = "Calculation Error"; + if (Handle != IntPtr.Zero) { + UInt32 sizeMessage = 0; + UInt32 neededMessage = 0; + Byte hasLastError = 0; + Int32 resultCode1 = GetLastError (Handle, sizeMessage, out neededMessage, IntPtr.Zero, out hasLastError); + if ((resultCode1 == 0) && (hasLastError != 0)) { + sizeMessage = neededMessage; + byte[] bytesMessage = new byte[sizeMessage]; + + GCHandle dataMessage = GCHandle.Alloc(bytesMessage, GCHandleType.Pinned); + Int32 resultCode2 = GetLastError(Handle, sizeMessage, out neededMessage, dataMessage.AddrOfPinnedObject(), out hasLastError); + dataMessage.Free(); + + if ((resultCode2 == 0) && (hasLastError != 0)) { + sMessage = sMessage + ": " + Encoding.UTF8.GetString(bytesMessage).TrimEnd(char.MinValue); + } + } + } + + throw new Exception(sMessage + "(# " + errorCode + ")"); + } + + /** + * IMPORTANT: PolymorphicFactory method should not be used by application directly. + * It's designed to be used on Handle object only once. + * If it's used on any existing object as a form of dynamic cast then + * CalculationWrapper::AcquireInstance(CBase object) must be called after instantiating new object. + * This is important to keep reference count matching between application and library sides. + */ + public static T PolymorphicFactory<T>(IntPtr Handle) where T : class + { + T Object; + if (Handle == IntPtr.Zero) + return System.Activator.CreateInstance(typeof(T), Handle) as T; + + UInt64 resultClassTypeId = 0; + Int32 errorCode = Base_ClassTypeId (Handle, out resultClassTypeId); + if (errorCode != 0) + ThrowError (IntPtr.Zero, errorCode); + switch (resultClassTypeId) { + case 0x3BA5271BAB410E5D: Object = new CBase(Handle) as T; break; // First 64 bits of SHA1 of a string: "Calculation::Base" + case 0xB23F514353D0C606: Object = new CCalculator(Handle) as T; break; // First 64 bits of SHA1 of a string: "Calculation::Calculator" + default: Object = System.Activator.CreateInstance(typeof(T), Handle) as T; break; + } + return Object; + } + + } + } + + + public class CBase + { + protected IntPtr Handle; + + public CBase (IntPtr NewHandle) + { + Handle = NewHandle; + } + + ~CBase () + { + if (Handle != IntPtr.Zero) { + Internal.CalculationWrapper.ReleaseInstance (Handle); + Handle = IntPtr.Zero; + } + } + + protected void CheckError (Int32 errorCode) + { + if (errorCode != 0) { + Internal.CalculationWrapper.ThrowError (Handle, errorCode); + } + } + + public IntPtr GetHandle () + { + return Handle; + } + + public UInt64 ClassTypeId () + { + UInt64 resultClassTypeId = 0; + + CheckError(Internal.CalculationWrapper.Base_ClassTypeId (Handle, out resultClassTypeId)); + return resultClassTypeId; + } + + } + + public class CCalculator : CBase + { + public CCalculator (IntPtr NewHandle) : base (NewHandle) + { + } + + public void EnlistVariable (IntPtr AVariable) + { + + CheckError(Internal.CalculationWrapper.Calculator_EnlistVariable (Handle, AVariable)); + } + + public IntPtr GetEnlistedVariable (UInt32 AIndex) + { + IntPtr newVariable = IntPtr.Zero; + + CheckError(Internal.CalculationWrapper.Calculator_GetEnlistedVariable (Handle, AIndex, out newVariable)); + return newVariable; + } + + public void ClearVariables () + { + + CheckError(Internal.CalculationWrapper.Calculator_ClearVariables (Handle)); + } + + public IntPtr Multiply () + { + IntPtr newInstance = IntPtr.Zero; + + CheckError(Internal.CalculationWrapper.Calculator_Multiply (Handle, out newInstance)); + return newInstance; + } + + public IntPtr Add () + { + IntPtr newInstance = IntPtr.Zero; + + CheckError(Internal.CalculationWrapper.Calculator_Add (Handle, out newInstance)); + return newInstance; + } + + } + + class Wrapper + { + private static void CheckError (Int32 errorCode) + { + if (errorCode != 0) { + Internal.CalculationWrapper.ThrowError (IntPtr.Zero, errorCode); + } + } + + public static CCalculator CreateCalculator () + { + IntPtr newInstance = IntPtr.Zero; + + CheckError(Internal.CalculationWrapper.CreateCalculator (out newInstance)); + return Internal.CalculationWrapper.PolymorphicFactory<CCalculator>(newInstance); + } + + public static void GetVersion (out UInt32 AMajor, out UInt32 AMinor, out UInt32 AMicro) + { + + CheckError(Internal.CalculationWrapper.GetVersion (out AMajor, out AMinor, out AMicro)); + } + + public static bool GetLastError (CBase AInstance, out String AErrorMessage) + { + Byte resultHasError = 0; + UInt32 sizeErrorMessage = 0; + UInt32 neededErrorMessage = 0; + CheckError(Internal.CalculationWrapper.GetLastError (AInstance.GetHandle(), sizeErrorMessage, out neededErrorMessage, IntPtr.Zero, out resultHasError)); + sizeErrorMessage = neededErrorMessage; + byte[] bytesErrorMessage = new byte[sizeErrorMessage]; + GCHandle dataErrorMessage = GCHandle.Alloc(bytesErrorMessage, GCHandleType.Pinned); + + CheckError(Internal.CalculationWrapper.GetLastError (AInstance.GetHandle(), sizeErrorMessage, out neededErrorMessage, dataErrorMessage.AddrOfPinnedObject(), out resultHasError)); + dataErrorMessage.Free(); + AErrorMessage = Encoding.UTF8.GetString(bytesErrorMessage).TrimEnd(char.MinValue); + return (resultHasError != 0); + } + + public static void ReleaseInstance (CBase AInstance) + { + + CheckError(Internal.CalculationWrapper.ReleaseInstance (AInstance.GetHandle())); + } + + public static void AcquireInstance (CBase AInstance) + { + + CheckError(Internal.CalculationWrapper.AcquireInstance (AInstance.GetHandle())); + } + + public static void InjectComponent (String ANameSpace, UInt64 ASymbolAddressMethod) + { + throw new Exception("Component injection is not supported in CSharp."); + } + + public static UInt64 GetSymbolLookupMethod () + { + UInt64 resultSymbolLookupMethod = 0; + + CheckError(Internal.CalculationWrapper.GetSymbolLookupMethod (out resultSymbolLookupMethod)); + return resultSymbolLookupMethod; + } + + } + +} diff --git a/Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.cs b/Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.cs new file mode 100644 index 00000000..979397a9 --- /dev/null +++ b/Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.cs @@ -0,0 +1,52 @@ +/*++ + +Copyright (C) 2019 Calculation developers + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated CSharp application that demonstrates the + usage of the CSharp bindings of Calculation library + +Interface version: 1.0.0 + +*/ + + +using System; +namespace Calculation_Example +{ + class Calculation_Example + { + static void Main() + { + try + { + UInt32 nMajor, nMinor, nMicro; + Calculation.Wrapper.GetVersion(out nMajor, out nMinor, out nMicro); + string versionString = string.Format("Calculation.version = {0}.{1}.{2}", nMajor, nMinor, nMicro); + Console.WriteLine(versionString); + + Numbers.Wrapper.GetVersion(out nMajor, out nMinor, out nMicro); + versionString = string.Format("Numbers.version = {0}.{1}.{2}", nMajor, nMinor, nMicro); + Console.WriteLine(versionString); + + try + { + Calculation.Wrapper.InjectComponent("Numbers", Numbers.Wrapper.GetSymbolLookupMethod()); + } + catch (Exception e) + { + if (!e.Message.Equals("Component injection is not supported in CSharp.")) + throw new Exception("CSharp must throw correct exception here!"); + } + } + catch (Exception e) + { + Console.WriteLine("Exception: \"" + e.Message + "\""); + } + } + } +} + diff --git a/Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.csproj b/Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.csproj new file mode 100644 index 00000000..5081066a --- /dev/null +++ b/Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.csproj @@ -0,0 +1,20 @@ + +<Project Sdk="Microsoft.NET.Sdk"> + <PropertyGroup> + <OutputType>Exe</OutputType> + <TargetFramework>netstandard2.0</TargetFramework> + <StartupObject>Calculation_Example.Calculation_Example</StartupObject> + <ApplicationIcon /> + <Platforms>x64</Platforms> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + </PropertyGroup> + <ItemGroup> + <Compile Include="..\..\..\Calculation_component\Bindings\CSharp\Calculation.cs" Link="Calculation.cs" /> + <Compile Include="..\..\..\Numbers_component\Bindings\CSharp\Numbers.cs" Link="Numbers.cs" /> + </ItemGroup> +</Project> diff --git a/Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.sln b/Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.sln new file mode 100644 index 00000000..b632dab1 --- /dev/null +++ b/Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.539 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("45c3ad66-1592-4cee-bfef-8a882bf392aa") = "Calculation_Example", "Calculation_Example.csproj", "b1261bbe-ddc3-4a19-af8e-957f5c39eadc" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + b1261bbe-ddc3-4a19-af8e-957f5c39eadc.Debug|x64.ActiveCfg = Debug|x64 + b1261bbe-ddc3-4a19-af8e-957f5c39eadc.Debug|x64.Build.0 = Debug|x64 + b1261bbe-ddc3-4a19-af8e-957f5c39eadc.Release|x64.ActiveCfg = Release|x64 + b1261bbe-ddc3-4a19-af8e-957f5c39eadc.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = fc7c62d7-4c16-4553-bd1e-fb64a195606b + EndGlobalSection +EndGlobal diff --git a/Examples/Injection/Calculation_component/Examples/CSharp/build.sh b/Examples/Injection/Calculation_component/Examples/CSharp/build.sh new file mode 100755 index 00000000..8f174a8b --- /dev/null +++ b/Examples/Injection/Calculation_component/Examples/CSharp/build.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../../../../Build/build.inc + +echo "Build Go example" + +[ -d bin ] && rm -rf bin +[ -d obj ] && rm -rf obj +msbuild /p:Configuration=Debug /t:Restore Calculation_Example.csproj +msbuild /p:Configuration=Debug /p:AllowUnsafeBlocks=true Calculation_Example.csproj + +pushd bin/Debug/netstandard2.0 +echo "Test C++ library" +rm -f calculation.dll numbers.dll +ln -s ../../../../../../Calculation_component/Implementations/Cpp/build/calculation$OSLIBEXT calculation.dll +ln -s ../../../../../../Numbers_component/Implementations/Cpp/build/numbers$OSLIBEXT numbers.dll +RUN "mono Calculation_Example.dll" . + +echo "Test Pascal library" +rm -f calculation.dll numbers.dll +ln -s ../../../../../../Calculation_component/Implementations/Pascal/build/calculation$OSLIBEXT calculation.dll +ln -s ../../../../../../Numbers_component/Implementations/Pascal/build/numbers$OSLIBEXT numbers.dll +RUN "mono Calculation_Example.dll" . + +popd \ No newline at end of file diff --git a/Examples/Injection/Numbers.xml b/Examples/Injection/Numbers.xml index 0c49fcf4..a70149f9 100644 --- a/Examples/Injection/Numbers.xml +++ b/Examples/Injection/Numbers.xml @@ -8,6 +8,7 @@ <bindings> <binding language="CppDynamic" indentation="tabs" /> + <binding language="CSharp" indentation="tabs" /> <binding language="Pascal" indentation="2spaces" /> <binding language="Python" indentation="tabs" /> </bindings> diff --git a/Examples/Injection/Numbers_component/Bindings/CSharp/Numbers.cs b/Examples/Injection/Numbers_component/Bindings/CSharp/Numbers.cs new file mode 100644 index 00000000..a7988a89 --- /dev/null +++ b/Examples/Injection/Numbers_component/Bindings/CSharp/Numbers.cs @@ -0,0 +1,216 @@ +using System; +using System.Text; +using System.Runtime.InteropServices; + +namespace Numbers { + + + namespace Internal { + + + public class NumbersWrapper + { + [DllImport("numbers.dll", EntryPoint = "numbers_base_classtypeid", CallingConvention=CallingConvention.Cdecl)] + public unsafe extern static Int32 Base_ClassTypeId (IntPtr Handle, out UInt64 AClassTypeId); + + [DllImport("numbers.dll", EntryPoint = "numbers_variable_getvalue", CallingConvention=CallingConvention.Cdecl)] + public unsafe extern static Int32 Variable_GetValue (IntPtr Handle, out Double AValue); + + [DllImport("numbers.dll", EntryPoint = "numbers_variable_setvalue", CallingConvention=CallingConvention.Cdecl)] + public unsafe extern static Int32 Variable_SetValue (IntPtr Handle, Double AValue); + + [DllImport("numbers.dll", EntryPoint = "numbers_createvariable", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 CreateVariable (Double AInitialValue, out IntPtr AInstance); + + [DllImport("numbers.dll", EntryPoint = "numbers_getversion", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 GetVersion (out UInt32 AMajor, out UInt32 AMinor, out UInt32 AMicro); + + [DllImport("numbers.dll", EntryPoint = "numbers_getlasterror", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 GetLastError (IntPtr AInstance, UInt32 sizeErrorMessage, out UInt32 neededErrorMessage, IntPtr dataErrorMessage, out Byte AHasError); + + [DllImport("numbers.dll", EntryPoint = "numbers_releaseinstance", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 ReleaseInstance (IntPtr AInstance); + + [DllImport("numbers.dll", EntryPoint = "numbers_acquireinstance", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 AcquireInstance (IntPtr AInstance); + + [DllImport("numbers.dll", EntryPoint = "numbers_getsymbollookupmethod", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + public extern static Int32 GetSymbolLookupMethod (out UInt64 ASymbolLookupMethod); + + public static void ThrowError(IntPtr Handle, Int32 errorCode) + { + String sMessage = "Numbers Error"; + if (Handle != IntPtr.Zero) { + UInt32 sizeMessage = 0; + UInt32 neededMessage = 0; + Byte hasLastError = 0; + Int32 resultCode1 = GetLastError (Handle, sizeMessage, out neededMessage, IntPtr.Zero, out hasLastError); + if ((resultCode1 == 0) && (hasLastError != 0)) { + sizeMessage = neededMessage; + byte[] bytesMessage = new byte[sizeMessage]; + + GCHandle dataMessage = GCHandle.Alloc(bytesMessage, GCHandleType.Pinned); + Int32 resultCode2 = GetLastError(Handle, sizeMessage, out neededMessage, dataMessage.AddrOfPinnedObject(), out hasLastError); + dataMessage.Free(); + + if ((resultCode2 == 0) && (hasLastError != 0)) { + sMessage = sMessage + ": " + Encoding.UTF8.GetString(bytesMessage).TrimEnd(char.MinValue); + } + } + } + + throw new Exception(sMessage + "(# " + errorCode + ")"); + } + + /** + * IMPORTANT: PolymorphicFactory method should not be used by application directly. + * It's designed to be used on Handle object only once. + * If it's used on any existing object as a form of dynamic cast then + * NumbersWrapper::AcquireInstance(CBase object) must be called after instantiating new object. + * This is important to keep reference count matching between application and library sides. + */ + public static T PolymorphicFactory<T>(IntPtr Handle) where T : class + { + T Object; + if (Handle == IntPtr.Zero) + return System.Activator.CreateInstance(typeof(T), Handle) as T; + + UInt64 resultClassTypeId = 0; + Int32 errorCode = Base_ClassTypeId (Handle, out resultClassTypeId); + if (errorCode != 0) + ThrowError (IntPtr.Zero, errorCode); + switch (resultClassTypeId) { + case 0x27799F69B3FD1C9E: Object = new CBase(Handle) as T; break; // First 64 bits of SHA1 of a string: "Numbers::Base" + case 0x23934EDF762423EA: Object = new CVariable(Handle) as T; break; // First 64 bits of SHA1 of a string: "Numbers::Variable" + default: Object = System.Activator.CreateInstance(typeof(T), Handle) as T; break; + } + return Object; + } + + } + } + + + public class CBase + { + protected IntPtr Handle; + + public CBase (IntPtr NewHandle) + { + Handle = NewHandle; + } + + ~CBase () + { + if (Handle != IntPtr.Zero) { + Internal.NumbersWrapper.ReleaseInstance (Handle); + Handle = IntPtr.Zero; + } + } + + protected void CheckError (Int32 errorCode) + { + if (errorCode != 0) { + Internal.NumbersWrapper.ThrowError (Handle, errorCode); + } + } + + public IntPtr GetHandle () + { + return Handle; + } + + public UInt64 ClassTypeId () + { + UInt64 resultClassTypeId = 0; + + CheckError(Internal.NumbersWrapper.Base_ClassTypeId (Handle, out resultClassTypeId)); + return resultClassTypeId; + } + + } + + public class CVariable : CBase + { + public CVariable (IntPtr NewHandle) : base (NewHandle) + { + } + + public Double GetValue () + { + Double resultValue = 0; + + CheckError(Internal.NumbersWrapper.Variable_GetValue (Handle, out resultValue)); + return resultValue; + } + + public void SetValue (Double AValue) + { + + CheckError(Internal.NumbersWrapper.Variable_SetValue (Handle, AValue)); + } + + } + + class Wrapper + { + private static void CheckError (Int32 errorCode) + { + if (errorCode != 0) { + Internal.NumbersWrapper.ThrowError (IntPtr.Zero, errorCode); + } + } + + public static CVariable CreateVariable (Double AInitialValue) + { + IntPtr newInstance = IntPtr.Zero; + + CheckError(Internal.NumbersWrapper.CreateVariable (AInitialValue, out newInstance)); + return Internal.NumbersWrapper.PolymorphicFactory<CVariable>(newInstance); + } + + public static void GetVersion (out UInt32 AMajor, out UInt32 AMinor, out UInt32 AMicro) + { + + CheckError(Internal.NumbersWrapper.GetVersion (out AMajor, out AMinor, out AMicro)); + } + + public static bool GetLastError (CBase AInstance, out String AErrorMessage) + { + Byte resultHasError = 0; + UInt32 sizeErrorMessage = 0; + UInt32 neededErrorMessage = 0; + CheckError(Internal.NumbersWrapper.GetLastError (AInstance.GetHandle(), sizeErrorMessage, out neededErrorMessage, IntPtr.Zero, out resultHasError)); + sizeErrorMessage = neededErrorMessage; + byte[] bytesErrorMessage = new byte[sizeErrorMessage]; + GCHandle dataErrorMessage = GCHandle.Alloc(bytesErrorMessage, GCHandleType.Pinned); + + CheckError(Internal.NumbersWrapper.GetLastError (AInstance.GetHandle(), sizeErrorMessage, out neededErrorMessage, dataErrorMessage.AddrOfPinnedObject(), out resultHasError)); + dataErrorMessage.Free(); + AErrorMessage = Encoding.UTF8.GetString(bytesErrorMessage).TrimEnd(char.MinValue); + return (resultHasError != 0); + } + + public static void ReleaseInstance (CBase AInstance) + { + + CheckError(Internal.NumbersWrapper.ReleaseInstance (AInstance.GetHandle())); + } + + public static void AcquireInstance (CBase AInstance) + { + + CheckError(Internal.NumbersWrapper.AcquireInstance (AInstance.GetHandle())); + } + + public static UInt64 GetSymbolLookupMethod () + { + UInt64 resultSymbolLookupMethod = 0; + + CheckError(Internal.NumbersWrapper.GetSymbolLookupMethod (out resultSymbolLookupMethod)); + return resultSymbolLookupMethod; + } + + } + +} diff --git a/Examples/Injection/build.sh b/Examples/Injection/build.sh index ea37dc45..624f93a9 100755 --- a/Examples/Injection/build.sh +++ b/Examples/Injection/build.sh @@ -23,5 +23,5 @@ echo "Build and test bindings examples with C++ library" ./Calculation_component/Examples/CppDynamic/build.sh ./Calculation_component/Examples/Python/build.sh ./Calculation_component/Examples/Pascal/build.sh - +./Calculation_component/Examples/CSharp/build.sh echo "Build and test are done and successful" \ No newline at end of file From 8798e924091819f34d94ab01dbc8502d2d2ca830 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Wed, 27 Oct 2021 12:47:55 -0700 Subject: [PATCH 104/143] Suppress examples --- Examples/Injection/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/Injection/build.sh b/Examples/Injection/build.sh index 624f93a9..e20b593b 100755 --- a/Examples/Injection/build.sh +++ b/Examples/Injection/build.sh @@ -6,7 +6,7 @@ cd "$(dirname "$0")" source ../../Build/build.inc echo "Generate IDL" -../../$ACT Numbers.xml +../../$ACT Numbers.xml -suppressexamples ../../$ACT Calculation.xml echo "Build C++ libraries" From 1372903087280eb942a972ea5691c16e660a4acc Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Wed, 27 Oct 2021 12:48:07 -0700 Subject: [PATCH 105/143] Fix mistype --- Examples/RTTI/RTTI_component/Examples/CSharp/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/RTTI/RTTI_component/Examples/CSharp/build.sh b/Examples/RTTI/RTTI_component/Examples/CSharp/build.sh index e1b070d0..6cdcb8c5 100755 --- a/Examples/RTTI/RTTI_component/Examples/CSharp/build.sh +++ b/Examples/RTTI/RTTI_component/Examples/CSharp/build.sh @@ -8,7 +8,7 @@ source ../../../../../Build/build.inc echo "Build Go example" [ -d bin ] && rm -rf bin -[ -d obj ] && rm -rf ob +[ -d obj ] && rm -rf obj msbuild /p:Configuration=Debug /t:Restore RTTI_Example.csproj msbuild /p:Configuration=Debug /p:AllowUnsafeBlocks=true RTTI_Example.csproj From 5b535af8695be3d05e1c2cb9eaaf4ee0616fb611 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Thu, 28 Oct 2021 14:36:52 -0700 Subject: [PATCH 106/143] Fix hardcoded namespace --- Source/buildbindinggo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/buildbindinggo.go b/Source/buildbindinggo.go index a978aa45..5bd64970 100644 --- a/Source/buildbindinggo.go +++ b/Source/buildbindinggo.go @@ -729,7 +729,7 @@ func getGoType(paramType, namespace, paramClass, paramName string, isPtr bool) ( tp.Empty = "\"\"" case "pointer": tp.Type = "uintptr" - tp.CType = fmt.Sprintf("C.RTTI_pvoid") + tp.CType = fmt.Sprintf("C.%s_pvoid", namespace) tp.CToGo = fmt.Sprintf("%s(%s)", tp.Type, paramName) tp.GoToC = fmt.Sprintf("(%s)(%s)", tp.CType, paramName) tp.Empty = "0" From ee9ca3c66d4043238da51f817902e046c9884f27 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Thu, 28 Oct 2021 14:37:17 -0700 Subject: [PATCH 107/143] Add Java example --- .../Bindings/Java9/build_jar.sh | 12 + .../Bindings/Java9/calculation/Base.java | 82 +++++ .../calculation/CalculationException.java | 76 +++++ .../Java9/calculation/CalculationWrapper.java | 314 ++++++++++++++++++ .../Java9/calculation/Calculator.java | 118 +++++++ .../Examples/Java9/Calculation_Example.java | 63 ++++ .../Examples/Java9/build.sh | 33 ++ .../Bindings/Java9/build_jar.sh | 12 + .../Bindings/Java9/numbers/Base.java | 81 +++++ .../Java9/numbers/NumbersException.java | 76 +++++ .../Java9/numbers/NumbersWrapper.java | 269 +++++++++++++++ .../Bindings/Java9/numbers/Variable.java | 59 ++++ Examples/Injection/build.sh | 2 + 13 files changed, 1197 insertions(+) create mode 100644 Examples/Injection/Calculation_component/Bindings/Java9/build_jar.sh create mode 100644 Examples/Injection/Calculation_component/Bindings/Java9/calculation/Base.java create mode 100644 Examples/Injection/Calculation_component/Bindings/Java9/calculation/CalculationException.java create mode 100644 Examples/Injection/Calculation_component/Bindings/Java9/calculation/CalculationWrapper.java create mode 100644 Examples/Injection/Calculation_component/Bindings/Java9/calculation/Calculator.java create mode 100644 Examples/Injection/Calculation_component/Examples/Java9/Calculation_Example.java create mode 100755 Examples/Injection/Calculation_component/Examples/Java9/build.sh create mode 100644 Examples/Injection/Numbers_component/Bindings/Java9/build_jar.sh create mode 100644 Examples/Injection/Numbers_component/Bindings/Java9/numbers/Base.java create mode 100644 Examples/Injection/Numbers_component/Bindings/Java9/numbers/NumbersException.java create mode 100644 Examples/Injection/Numbers_component/Bindings/Java9/numbers/NumbersWrapper.java create mode 100644 Examples/Injection/Numbers_component/Bindings/Java9/numbers/Variable.java diff --git a/Examples/Injection/Calculation_component/Bindings/Java9/build_jar.sh b/Examples/Injection/Calculation_component/Bindings/Java9/build_jar.sh new file mode 100644 index 00000000..82ada26c --- /dev/null +++ b/Examples/Injection/Calculation_component/Bindings/Java9/build_jar.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -euxo pipefail + +cd "$(dirname "$0")" +echo "Download JNA" +[ -f jna-5.5.0.jar ] || curl -O https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar + +echo "Compile Java Bindings" +javac -classpath *.jar calculation/* numbers/* + +echo "Create JAR" +jar cvf calculation-1.0.0.jar calculation diff --git a/Examples/Injection/Calculation_component/Bindings/Java9/calculation/Base.java b/Examples/Injection/Calculation_component/Bindings/Java9/calculation/Base.java new file mode 100644 index 00000000..cd44fe53 --- /dev/null +++ b/Examples/Injection/Calculation_component/Bindings/Java9/calculation/Base.java @@ -0,0 +1,82 @@ +/*++ + +Copyright (C) 2019 Calculation developers + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of Calculation library + +Interface version: 1.0.0 + +*/ + +package calculation; + +import com.sun.jna.Library; +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import java.lang.ref.Cleaner; + +import numbers.*; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; + +public class Base { + + protected static final Cleaner mCleaner = Cleaner.create(); + + protected Pointer mHandle; + + protected CalculationWrapper mWrapper; + + public Base(CalculationWrapper wrapper, Pointer handle) { + mHandle = handle; + mWrapper = wrapper; + mCleaner.register(this, new InstanceReleaser(this)); + } + + public Pointer getHandle() { + return mHandle; + } + + protected static class InstanceReleaser implements Runnable{ + + protected Pointer mHandle; + + protected CalculationWrapper mWrapper; + + protected InstanceReleaser(Base instance) { + mHandle = instance.mHandle; + mWrapper = instance.mWrapper; + } + + @Override + public void run() { + try { + mWrapper.checkError(null, mWrapper.calculation_releaseinstance.invokeInt(new java.lang.Object[]{mHandle})); + } catch (CalculationException e) { + e.printStackTrace(); + } + } + } + /** + * Get Class Type Id + * + * @return Class type as a 64 bits integer + * @throws CalculationException + */ + public long classTypeId() throws CalculationException { + Pointer bufferClassTypeId = new Memory(8); + mWrapper.checkError(this, mWrapper.calculation_base_classtypeid.invokeInt(new java.lang.Object[]{mHandle, bufferClassTypeId})); + return bufferClassTypeId.getLong(0); + } + + +} + diff --git a/Examples/Injection/Calculation_component/Bindings/Java9/calculation/CalculationException.java b/Examples/Injection/Calculation_component/Bindings/Java9/calculation/CalculationException.java new file mode 100644 index 00000000..018c2e6d --- /dev/null +++ b/Examples/Injection/Calculation_component/Bindings/Java9/calculation/CalculationException.java @@ -0,0 +1,76 @@ +/*++ + +Copyright (C) 2019 Calculation developers + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of Calculation library + +Interface version: 1.0.0 + +*/ + +package calculation; + +import java.util.HashMap; +import java.util.Map; + +public class CalculationException extends Exception { + + // Error Constants for Calculation + public static final int CALCULATION_SUCCESS = 0; + public static final int CALCULATION_ERROR_NOTIMPLEMENTED = 1; + public static final int CALCULATION_ERROR_INVALIDPARAM = 2; + public static final int CALCULATION_ERROR_INVALIDCAST = 3; + public static final int CALCULATION_ERROR_BUFFERTOOSMALL = 4; + public static final int CALCULATION_ERROR_GENERICEXCEPTION = 5; + public static final int CALCULATION_ERROR_COULDNOTLOADLIBRARY = 6; + public static final int CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT = 7; + public static final int CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION = 8; + + public static final Map<Integer, String> ErrorCodeMap = new HashMap<Integer, String>(); + public static final Map<Integer, String> ErrorDescriptionMap = new HashMap<Integer, String>(); + + static { + ErrorCodeMap.put(CALCULATION_ERROR_NOTIMPLEMENTED, "CALCULATION_ERROR_NOTIMPLEMENTED"); + ErrorDescriptionMap.put(CALCULATION_ERROR_NOTIMPLEMENTED, "functionality not implemented"); + ErrorCodeMap.put(CALCULATION_ERROR_INVALIDPARAM, "CALCULATION_ERROR_INVALIDPARAM"); + ErrorDescriptionMap.put(CALCULATION_ERROR_INVALIDPARAM, "an invalid parameter was passed"); + ErrorCodeMap.put(CALCULATION_ERROR_INVALIDCAST, "CALCULATION_ERROR_INVALIDCAST"); + ErrorDescriptionMap.put(CALCULATION_ERROR_INVALIDCAST, "a type cast failed"); + ErrorCodeMap.put(CALCULATION_ERROR_BUFFERTOOSMALL, "CALCULATION_ERROR_BUFFERTOOSMALL"); + ErrorDescriptionMap.put(CALCULATION_ERROR_BUFFERTOOSMALL, "a provided buffer is too small"); + ErrorCodeMap.put(CALCULATION_ERROR_GENERICEXCEPTION, "CALCULATION_ERROR_GENERICEXCEPTION"); + ErrorDescriptionMap.put(CALCULATION_ERROR_GENERICEXCEPTION, "a generic exception occurred"); + ErrorCodeMap.put(CALCULATION_ERROR_COULDNOTLOADLIBRARY, "CALCULATION_ERROR_COULDNOTLOADLIBRARY"); + ErrorDescriptionMap.put(CALCULATION_ERROR_COULDNOTLOADLIBRARY, "the library could not be loaded"); + ErrorCodeMap.put(CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT, "CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT"); + ErrorDescriptionMap.put(CALCULATION_ERROR_COULDNOTFINDLIBRARYEXPORT, "a required exported symbol could not be found in the library"); + ErrorCodeMap.put(CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION, "CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION"); + ErrorDescriptionMap.put(CALCULATION_ERROR_INCOMPATIBLEBINARYVERSION, "the version of the binary interface does not match the bindings interface"); + } + + protected int mErrorCode; + + protected String mErrorString; + + protected String mErrorDescription; + + public CalculationException(int errorCode, String message){ + super(message); + mErrorCode = errorCode; + mErrorString = ErrorCodeMap.get(errorCode); + mErrorString = (mErrorString != null) ? mErrorString : "Unknown error code"; + mErrorDescription = ErrorDescriptionMap.get(errorCode); + mErrorDescription = (mErrorDescription != null) ? mErrorDescription : ""; + } + + @Override + public String toString() { + return mErrorCode + ": " + mErrorString + " (" + mErrorDescription + " - " + getMessage() + ")"; + } +} + diff --git a/Examples/Injection/Calculation_component/Bindings/Java9/calculation/CalculationWrapper.java b/Examples/Injection/Calculation_component/Bindings/Java9/calculation/CalculationWrapper.java new file mode 100644 index 00000000..6006c2e1 --- /dev/null +++ b/Examples/Injection/Calculation_component/Bindings/Java9/calculation/CalculationWrapper.java @@ -0,0 +1,314 @@ +/*++ + +Copyright (C) 2019 Calculation developers + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of Calculation library + +Interface version: 1.0.0 + +*/ + +package calculation; + +import com.sun.jna.*; + +import java.nio.charset.StandardCharsets; + +import numbers.*; + +public class CalculationWrapper { + + public static class EnumConversion { + } + + protected Function calculation_createcalculator; + protected Function calculation_getversion; + protected Function calculation_getlasterror; + protected Function calculation_releaseinstance; + protected Function calculation_acquireinstance; + protected Function calculation_injectcomponent; + protected Function calculation_getsymbollookupmethod; + protected Function calculation_base_classtypeid; + protected Function calculation_calculator_enlistvariable; + protected Function calculation_calculator_getenlistedvariable; + protected Function calculation_calculator_clearvariables; + protected Function calculation_calculator_multiply; + protected Function calculation_calculator_add; + + protected NativeLibrary mLibrary; + + protected NumbersWrapper mNumbersWrapper; + + public CalculationWrapper(String libraryPath) { + mLibrary = NativeLibrary.getInstance(libraryPath); + calculation_createcalculator = mLibrary.getFunction("calculation_createcalculator"); + calculation_getversion = mLibrary.getFunction("calculation_getversion"); + calculation_getlasterror = mLibrary.getFunction("calculation_getlasterror"); + calculation_releaseinstance = mLibrary.getFunction("calculation_releaseinstance"); + calculation_acquireinstance = mLibrary.getFunction("calculation_acquireinstance"); + calculation_injectcomponent = mLibrary.getFunction("calculation_injectcomponent"); + calculation_getsymbollookupmethod = mLibrary.getFunction("calculation_getsymbollookupmethod"); + calculation_base_classtypeid = mLibrary.getFunction("calculation_base_classtypeid"); + calculation_calculator_enlistvariable = mLibrary.getFunction("calculation_calculator_enlistvariable"); + calculation_calculator_getenlistedvariable = mLibrary.getFunction("calculation_calculator_getenlistedvariable"); + calculation_calculator_clearvariables = mLibrary.getFunction("calculation_calculator_clearvariables"); + calculation_calculator_multiply = mLibrary.getFunction("calculation_calculator_multiply"); + calculation_calculator_add = mLibrary.getFunction("calculation_calculator_add"); + } + + public CalculationWrapper(Pointer lookupPointer) throws CalculationException { + Function lookupMethod = Function.getFunction(lookupPointer); + calculation_createcalculator = loadFunctionByLookup(lookupMethod, "calculation_createcalculator"); + calculation_getversion = loadFunctionByLookup(lookupMethod, "calculation_getversion"); + calculation_getlasterror = loadFunctionByLookup(lookupMethod, "calculation_getlasterror"); + calculation_releaseinstance = loadFunctionByLookup(lookupMethod, "calculation_releaseinstance"); + calculation_acquireinstance = loadFunctionByLookup(lookupMethod, "calculation_acquireinstance"); + calculation_injectcomponent = loadFunctionByLookup(lookupMethod, "calculation_injectcomponent"); + calculation_getsymbollookupmethod = loadFunctionByLookup(lookupMethod, "calculation_getsymbollookupmethod"); + calculation_base_classtypeid = loadFunctionByLookup(lookupMethod, "calculation_base_classtypeid"); + calculation_calculator_enlistvariable = loadFunctionByLookup(lookupMethod, "calculation_calculator_enlistvariable"); + calculation_calculator_getenlistedvariable = loadFunctionByLookup(lookupMethod, "calculation_calculator_getenlistedvariable"); + calculation_calculator_clearvariables = loadFunctionByLookup(lookupMethod, "calculation_calculator_clearvariables"); + calculation_calculator_multiply = loadFunctionByLookup(lookupMethod, "calculation_calculator_multiply"); + calculation_calculator_add = loadFunctionByLookup(lookupMethod, "calculation_calculator_add"); + } + + protected void checkError(Base instance, int errorCode) throws CalculationException { + if (instance != null && instance.mWrapper != this) { + throw new CalculationException(CalculationException.CALCULATION_ERROR_INVALIDCAST, "invalid wrapper call"); + } + if (errorCode != CalculationException.CALCULATION_SUCCESS) { + if (instance != null) { + GetLastErrorResult result = getLastError(instance); + throw new CalculationException(errorCode, result.ErrorMessage); + } else { + throw new CalculationException(errorCode, ""); + } + } + } + + private Function loadFunctionByLookup(Function lookupMethod, String functionName) throws CalculationException { + byte[] bytes = functionName.getBytes(StandardCharsets.UTF_8); + Memory name = new Memory(bytes.length+1); + name.write(0, bytes, 0, bytes.length); + name.setByte(bytes.length, (byte)0); + Pointer address = new Memory(8); + java.lang.Object[] addressParam = new java.lang.Object[]{name, address}; + checkError(null, lookupMethod.invokeInt(addressParam)); + return Function.getFunction(address.getPointer(0)); + } + + public NumbersWrapper getNumbersWrapper() { + return mNumbersWrapper; + } + + /** + * Creates a new Calculator instance + * + * @return New Calculator instance + * @throws CalculationException + */ + public Calculator createCalculator() throws CalculationException { + Pointer bufferInstance = new Memory(8); + checkError(null, calculation_createcalculator.invokeInt(new java.lang.Object[]{bufferInstance})); + Pointer valueInstance = bufferInstance.getPointer(0); + Calculator instance = null; + if (valueInstance == Pointer.NULL) { + throw new CalculationException(CalculationException.CALCULATION_ERROR_INVALIDPARAM, "Instance was a null pointer"); + } + instance = this.PolymorphicFactory(valueInstance, Calculator.class); + return instance; + } + + /** + * retrieves the binary version of this library. + * + * @return GetVersion Result Tuple + * @throws CalculationException + */ + public GetVersionResult getVersion() throws CalculationException { + Pointer bufferMajor = new Memory(4); + Pointer bufferMinor = new Memory(4); + Pointer bufferMicro = new Memory(4); + checkError(null, calculation_getversion.invokeInt(new java.lang.Object[]{bufferMajor, bufferMinor, bufferMicro})); + GetVersionResult returnTuple = new GetVersionResult(); + returnTuple.Major = bufferMajor.getInt(0); + returnTuple.Minor = bufferMinor.getInt(0); + returnTuple.Micro = bufferMicro.getInt(0); + return returnTuple; + } + + public static class GetVersionResult { + /** + * returns the major version of this library + */ + public int Major; + + /** + * returns the minor version of this library + */ + public int Minor; + + /** + * returns the micro version of this library + */ + public int Micro; + + } + /** + * Returns the last error recorded on this object + * + * @param instance Instance Handle + * @return GetLastError Result Tuple + * @throws CalculationException + */ + public GetLastErrorResult getLastError(Base instance) throws CalculationException { + Pointer instanceHandle = null; + if (instance != null) { + instanceHandle = instance.getHandle(); + } else { + throw new CalculationException(CalculationException.CALCULATION_ERROR_INVALIDPARAM, "Instance is a null value."); + } + Pointer bytesNeededErrorMessage = new Memory(4); + Pointer bufferHasError = new Memory(1); + checkError(null, calculation_getlasterror.invokeInt(new java.lang.Object[]{instanceHandle, 0, bytesNeededErrorMessage, null, bufferHasError})); + int sizeErrorMessage = bytesNeededErrorMessage.getInt(0); + Pointer bufferErrorMessage = new Memory(sizeErrorMessage); + checkError(null, calculation_getlasterror.invokeInt(new java.lang.Object[]{instanceHandle, sizeErrorMessage, bytesNeededErrorMessage, bufferErrorMessage, bufferHasError})); + GetLastErrorResult returnTuple = new GetLastErrorResult(); + returnTuple.ErrorMessage = new String(bufferErrorMessage.getByteArray(0, sizeErrorMessage - 1), StandardCharsets.UTF_8); + returnTuple.HasError = bufferHasError.getByte(0) != 0; + return returnTuple; + } + + public static class GetLastErrorResult { + /** + * Message of the last error + */ + public String ErrorMessage; + + /** + * Is there a last error to query + */ + public boolean HasError; + + } + /** + * Releases shared ownership of an Instance + * + * @param instance Instance Handle + * @throws CalculationException + */ + public void releaseInstance(Base instance) throws CalculationException { + Pointer instanceHandle = null; + if (instance != null) { + instanceHandle = instance.getHandle(); + } else { + throw new CalculationException(CalculationException.CALCULATION_ERROR_INVALIDPARAM, "Instance is a null value."); + } + checkError(null, calculation_releaseinstance.invokeInt(new java.lang.Object[]{instanceHandle})); + } + + /** + * Acquires shared ownership of an Instance + * + * @param instance Instance Handle + * @throws CalculationException + */ + public void acquireInstance(Base instance) throws CalculationException { + Pointer instanceHandle = null; + if (instance != null) { + instanceHandle = instance.getHandle(); + } else { + throw new CalculationException(CalculationException.CALCULATION_ERROR_INVALIDPARAM, "Instance is a null value."); + } + checkError(null, calculation_acquireinstance.invokeInt(new java.lang.Object[]{instanceHandle})); + } + + /** + * Injects an imported component for usage within this component + * + * @param nameSpace NameSpace of the injected component + * @param symbolAddressMethod Address of the SymbolAddressMethod of the injected component + * @throws CalculationException + */ + public void injectComponent(String nameSpace, Pointer symbolAddressMethod) throws CalculationException, NumbersException { + byte[] bytesNameSpace = nameSpace.getBytes(StandardCharsets.UTF_8); + Memory bufferNameSpace = new Memory(bytesNameSpace.length + 1); + bufferNameSpace.write(0, bytesNameSpace, 0, bytesNameSpace.length); + bufferNameSpace.setByte(bytesNameSpace.length, (byte)0); + checkError(null, calculation_injectcomponent.invokeInt(new java.lang.Object[]{bufferNameSpace, symbolAddressMethod})); + + boolean nameSpaceFound = false; + if ("Numbers".equals(nameSpace)) { + if (mNumbersWrapper != null) { + throw new CalculationException(CalculationException.CALCULATION_ERROR_COULDNOTLOADLIBRARY, "Library with namespace ' + nameSpace + ' is already registered."); + } + mNumbersWrapper = new NumbersWrapper(symbolAddressMethod); + nameSpaceFound = true; + } + if (!nameSpaceFound) { + throw new CalculationException(CalculationException.CALCULATION_ERROR_COULDNOTLOADLIBRARY, "Unknown namespace " + nameSpace); + } + } + + /** + * Returns the address of the SymbolLookupMethod + * + * @return Address of the SymbolAddressMethod + * @throws CalculationException + */ + public Pointer getSymbolLookupMethod() throws CalculationException { + Pointer bufferSymbolLookupMethod = new Memory(8); + checkError(null, calculation_getsymbollookupmethod.invokeInt(new java.lang.Object[]{bufferSymbolLookupMethod})); + return bufferSymbolLookupMethod.getPointer(0); + } + + /** + * IMPORTANT: PolymorphicFactory method should not be used by application directly. + * It's designed to be used on CalculationHandle object only once. + * If it's used on any existing object as a form of dynamic cast then + * CalculationWrapper::acquireInstance(Base object) must be called after instantiating new object. + * This is important to keep reference count matching between application and library sides. + */ + public <T> T PolymorphicFactory(Pointer handle, Class<T> cls) { + if (handle == Pointer.NULL) + return null; + Class[] cArg = new Class[2]; + cArg[0] = CalculationWrapper.class; + cArg[1] = Pointer.class; + + try { + T obj = null; + Pointer bufferClassTypeId = new Memory(8); + checkError(null, calculation_base_classtypeid.invokeInt(new java.lang.Object[]{handle, bufferClassTypeId})); + long classTypeId = bufferClassTypeId.getLong(0); + + int msbId = (int)(classTypeId >> 32); + int lsbId = (int)classTypeId; + switch(msbId) { + case 0x3BA5271B: + switch(lsbId) { + case 0xAB410E5D: obj = (T)(new Base(this, handle)); break; // First 64 bits of SHA1 of a string: "Calculation::Base" + } + break; + case 0xB23F5143: + switch(lsbId) { + case 0x53D0C606: obj = (T)(new Calculator(this, handle)); break; // First 64 bits of SHA1 of a string: "Calculation::Calculator" + } + break; + default: obj = cls.getDeclaredConstructor(cArg).newInstance(this, handle); break; + } + return obj; + } + catch(Exception e) { + return null; + } + } +} + diff --git a/Examples/Injection/Calculation_component/Bindings/Java9/calculation/Calculator.java b/Examples/Injection/Calculation_component/Bindings/Java9/calculation/Calculator.java new file mode 100644 index 00000000..6f261d36 --- /dev/null +++ b/Examples/Injection/Calculation_component/Bindings/Java9/calculation/Calculator.java @@ -0,0 +1,118 @@ +/*++ + +Copyright (C) 2019 Calculation developers + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of Calculation library + +Interface version: 1.0.0 + +*/ + +package calculation; + +import com.sun.jna.Library; +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import java.lang.ref.Cleaner; + +import numbers.*; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; + +public class Calculator extends Base { + + public Calculator(CalculationWrapper wrapper, Pointer handle) { + super(wrapper, handle); + } + + /** + * Adds a Variable to the list of Variables this calculator works on + * + * @param variable The new variable in this calculator + * @throws CalculationException + */ + public void enlistVariable(Variable variable) throws CalculationException { + Pointer variableHandle = null; + if (variable != null) { + variableHandle = variable.getHandle(); + } else { + throw new CalculationException(CalculationException.CALCULATION_ERROR_INVALIDPARAM, "Variable is a null value."); + } + mWrapper.checkError(this, mWrapper.calculation_calculator_enlistvariable.invokeInt(new java.lang.Object[]{mHandle, variableHandle})); + } + + /** + * Returns an instance of a enlisted variable + * + * @param index The index of the variable to query + * @return The Index-th variable in this calculator + * @throws CalculationException + */ + public Variable getEnlistedVariable(int index) throws CalculationException { + Pointer bufferVariable = new Memory(8); + mWrapper.checkError(this, mWrapper.calculation_calculator_getenlistedvariable.invokeInt(new java.lang.Object[]{mHandle, index, bufferVariable})); + Pointer valueVariable = bufferVariable.getPointer(0); + Variable variable = null; + if (valueVariable == Pointer.NULL) { + throw new CalculationException(CalculationException.CALCULATION_ERROR_INVALIDPARAM, "Variable was a null pointer"); + } + variable = mWrapper.getNumbersWrapper().PolymorphicFactory(valueVariable, Variable.class); + return variable; + } + + /** + * Clears all variables in enlisted in this calculator + * + * @throws CalculationException + */ + public void clearVariables() throws CalculationException { + mWrapper.checkError(this, mWrapper.calculation_calculator_clearvariables.invokeInt(new java.lang.Object[]{mHandle})); + } + + /** + * Multiplies all enlisted variables + * + * @return Variable that holds the product of all enlisted Variables + * @throws CalculationException + */ + public Variable multiply() throws CalculationException { + Pointer bufferInstance = new Memory(8); + mWrapper.checkError(this, mWrapper.calculation_calculator_multiply.invokeInt(new java.lang.Object[]{mHandle, bufferInstance})); + Pointer valueInstance = bufferInstance.getPointer(0); + Variable instance = null; + if (valueInstance == Pointer.NULL) { + throw new CalculationException(CalculationException.CALCULATION_ERROR_INVALIDPARAM, "Instance was a null pointer"); + } + instance = mWrapper.getNumbersWrapper().PolymorphicFactory(valueInstance, Variable.class); + return instance; + } + + /** + * Sums all enlisted variables + * + * @return Variable that holds the sum of all enlisted Variables + * @throws CalculationException + */ + public Variable add() throws CalculationException { + Pointer bufferInstance = new Memory(8); + mWrapper.checkError(this, mWrapper.calculation_calculator_add.invokeInt(new java.lang.Object[]{mHandle, bufferInstance})); + Pointer valueInstance = bufferInstance.getPointer(0); + Variable instance = null; + if (valueInstance == Pointer.NULL) { + throw new CalculationException(CalculationException.CALCULATION_ERROR_INVALIDPARAM, "Instance was a null pointer"); + } + instance = mWrapper.getNumbersWrapper().PolymorphicFactory(valueInstance, Variable.class); + return instance; + } + + +} + diff --git a/Examples/Injection/Calculation_component/Examples/Java9/Calculation_Example.java b/Examples/Injection/Calculation_component/Examples/Java9/Calculation_Example.java new file mode 100644 index 00000000..3c0a05ab --- /dev/null +++ b/Examples/Injection/Calculation_component/Examples/Java9/Calculation_Example.java @@ -0,0 +1,63 @@ +/*++ + +Copyright (C) 2019 Calculation developers + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java application that demonstrates the + usage of the Java bindings of Calculation library + +Interface version: 1.0.0 + +*/ + + +import calculation.*; +import numbers.*; + +public class Calculation_Example { + + public static String libpath = ""; // TODO add the location of the shared library binary here + + public static void main(String[] args) throws CalculationException { + try { + String libpathCalculation = args[0]; + CalculationWrapper wrapperCalculation = new CalculationWrapper(libpathCalculation); + + CalculationWrapper.GetVersionResult versionCalculation = wrapperCalculation.getVersion(); + System.out.print("Calculation version: " + versionCalculation.Major + "." + versionCalculation.Minor + "." + versionCalculation.Micro); + System.out.println(); + + String libpathNumbers = args[1]; + NumbersWrapper wrapperNumbers = new NumbersWrapper(libpathNumbers); + + NumbersWrapper.GetVersionResult versionNumbers = wrapperNumbers.getVersion(); + System.out.print("Numbers version: " + versionNumbers.Major + "." + versionNumbers.Minor + "." + versionNumbers.Micro); + System.out.println(); + + wrapperCalculation.injectComponent("Numbers", wrapperNumbers.getSymbolLookupMethod()); + Calculator calculator = wrapperCalculation.createCalculator(); + Variable v1 = wrapperNumbers.createVariable(10.0); + calculator.enlistVariable(v1); + + calculator.enlistVariable(wrapperNumbers.createVariable(5.0)); + + Variable pSum = calculator.add(); + System.out.printf(" sum = %f", pSum.getValue()); + System.out.println(); + + { + Variable v2New = calculator.getEnlistedVariable(1); + v2New.setValue(15.0); + } + System.out.printf(" sum = %f", calculator.add().getValue()); + System.out.println(); + } + catch(Exception e) { + System.out.print("Exception!"); + } + } +} + diff --git a/Examples/Injection/Calculation_component/Examples/Java9/build.sh b/Examples/Injection/Calculation_component/Examples/Java9/build.sh new file mode 100755 index 00000000..5f5ec6bc --- /dev/null +++ b/Examples/Injection/Calculation_component/Examples/Java9/build.sh @@ -0,0 +1,33 @@ +#!/bin/bash +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../../../../Build/build.inc + +JnaJar="jna-5.5.0.jar" +Classpath=".:${JnaJar}:../../../Calculation_component/Bindings/Java9/:../../../Numbers_component/Bindings/Java9" +if [[ "$OSTYPE" == "linux-gnu" ]]; then + Classpath=".:${JnaJar}:../../../Calculation_component/Bindings/Java9/:../../../Numbers_component/Bindings/Java9" +elif [[ "$OSTYPE" == "darwin"* ]]; then + Classpath=".:${JnaJar}:../../../Calculation_component/Bindings/Java9/:../../../Numbers_component/Bindings/Java9" +elif [[ "$OSTYPE" == "cygwin" ]]; then + Classpath=".;${JnaJar};../../../Calculation_component/Bindings/Java9/:../../../Numbers_component/Bindings/Java9" +elif [[ "$OSTYPE" == "msys" ]]; then + Classpath=".;${JnaJar};../../../Calculation_component/Bindings/Java9/:../../../Numbers_component/Bindings/Java9" +elif [[ "$OSTYPE" == "win32" ]]; then + Classpath=".;${JnaJar};../../../Calculation_component/Bindings/Java9/:../../../Numbers_component/Bindings/Java9" +else + echo "Unknown system: "$OSTYPE + exit 1 +fi + +echo "Download JNA" +[ -f jna-5.5.0.jar ] || curl -O https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar + +echo "Compile Java bindings" +javac -encoding UTF8 -classpath "${JnaJar}" ../../../Calculation_component/Bindings/Java9/calculation/*.java ../../../Numbers_component/Bindings/Java9/numbers/*.java +echo "Compile Java example" +javac -encoding UTF8 -classpath $Classpath Calculation_Example.java + +echo "Test C++ library" +java -ea -classpath $Classpath Calculation_Example $PWD/../../../Calculation_component/Implementations/Cpp/build/calculation$OSLIBEXT $PWD/../../../Numbers_component/Implementations/Cpp/build/numbers$OSLIBEXT diff --git a/Examples/Injection/Numbers_component/Bindings/Java9/build_jar.sh b/Examples/Injection/Numbers_component/Bindings/Java9/build_jar.sh new file mode 100644 index 00000000..94445224 --- /dev/null +++ b/Examples/Injection/Numbers_component/Bindings/Java9/build_jar.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -euxo pipefail + +cd "$(dirname "$0")" +echo "Download JNA" +[ -f jna-5.5.0.jar ] || curl -O https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar + +echo "Compile Java Bindings" +javac -classpath *.jar numbers/* + +echo "Create JAR" +jar cvf numbers-1.0.0.jar numbers diff --git a/Examples/Injection/Numbers_component/Bindings/Java9/numbers/Base.java b/Examples/Injection/Numbers_component/Bindings/Java9/numbers/Base.java new file mode 100644 index 00000000..2bf0baee --- /dev/null +++ b/Examples/Injection/Numbers_component/Bindings/Java9/numbers/Base.java @@ -0,0 +1,81 @@ +/*++ + +Copyright (C) 2019 Numbers developers + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of Numbers library + +Interface version: 1.0.0 + +*/ + +package numbers; + +import com.sun.jna.Library; +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import java.lang.ref.Cleaner; + + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; + +public class Base { + + protected static final Cleaner mCleaner = Cleaner.create(); + + protected Pointer mHandle; + + protected NumbersWrapper mWrapper; + + public Base(NumbersWrapper wrapper, Pointer handle) { + mHandle = handle; + mWrapper = wrapper; + mCleaner.register(this, new InstanceReleaser(this)); + } + + public Pointer getHandle() { + return mHandle; + } + + protected static class InstanceReleaser implements Runnable{ + + protected Pointer mHandle; + + protected NumbersWrapper mWrapper; + + protected InstanceReleaser(Base instance) { + mHandle = instance.mHandle; + mWrapper = instance.mWrapper; + } + + @Override + public void run() { + try { + mWrapper.checkError(null, mWrapper.numbers_releaseinstance.invokeInt(new java.lang.Object[]{mHandle})); + } catch (NumbersException e) { + e.printStackTrace(); + } + } + } + /** + * Get Class Type Id + * + * @return Class type as a 64 bits integer + * @throws NumbersException + */ + public long classTypeId() throws NumbersException { + Pointer bufferClassTypeId = new Memory(8); + mWrapper.checkError(this, mWrapper.numbers_base_classtypeid.invokeInt(new java.lang.Object[]{mHandle, bufferClassTypeId})); + return bufferClassTypeId.getLong(0); + } + + +} + diff --git a/Examples/Injection/Numbers_component/Bindings/Java9/numbers/NumbersException.java b/Examples/Injection/Numbers_component/Bindings/Java9/numbers/NumbersException.java new file mode 100644 index 00000000..57c16f9f --- /dev/null +++ b/Examples/Injection/Numbers_component/Bindings/Java9/numbers/NumbersException.java @@ -0,0 +1,76 @@ +/*++ + +Copyright (C) 2019 Numbers developers + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of Numbers library + +Interface version: 1.0.0 + +*/ + +package numbers; + +import java.util.HashMap; +import java.util.Map; + +public class NumbersException extends Exception { + + // Error Constants for Numbers + public static final int NUMBERS_SUCCESS = 0; + public static final int NUMBERS_ERROR_NOTIMPLEMENTED = 1; + public static final int NUMBERS_ERROR_INVALIDPARAM = 2; + public static final int NUMBERS_ERROR_INVALIDCAST = 3; + public static final int NUMBERS_ERROR_BUFFERTOOSMALL = 4; + public static final int NUMBERS_ERROR_GENERICEXCEPTION = 5; + public static final int NUMBERS_ERROR_COULDNOTLOADLIBRARY = 6; + public static final int NUMBERS_ERROR_COULDNOTFINDLIBRARYEXPORT = 7; + public static final int NUMBERS_ERROR_INCOMPATIBLEBINARYVERSION = 8; + + public static final Map<Integer, String> ErrorCodeMap = new HashMap<Integer, String>(); + public static final Map<Integer, String> ErrorDescriptionMap = new HashMap<Integer, String>(); + + static { + ErrorCodeMap.put(NUMBERS_ERROR_NOTIMPLEMENTED, "NUMBERS_ERROR_NOTIMPLEMENTED"); + ErrorDescriptionMap.put(NUMBERS_ERROR_NOTIMPLEMENTED, "functionality not implemented"); + ErrorCodeMap.put(NUMBERS_ERROR_INVALIDPARAM, "NUMBERS_ERROR_INVALIDPARAM"); + ErrorDescriptionMap.put(NUMBERS_ERROR_INVALIDPARAM, "an invalid parameter was passed"); + ErrorCodeMap.put(NUMBERS_ERROR_INVALIDCAST, "NUMBERS_ERROR_INVALIDCAST"); + ErrorDescriptionMap.put(NUMBERS_ERROR_INVALIDCAST, "a type cast failed"); + ErrorCodeMap.put(NUMBERS_ERROR_BUFFERTOOSMALL, "NUMBERS_ERROR_BUFFERTOOSMALL"); + ErrorDescriptionMap.put(NUMBERS_ERROR_BUFFERTOOSMALL, "a provided buffer is too small"); + ErrorCodeMap.put(NUMBERS_ERROR_GENERICEXCEPTION, "NUMBERS_ERROR_GENERICEXCEPTION"); + ErrorDescriptionMap.put(NUMBERS_ERROR_GENERICEXCEPTION, "a generic exception occurred"); + ErrorCodeMap.put(NUMBERS_ERROR_COULDNOTLOADLIBRARY, "NUMBERS_ERROR_COULDNOTLOADLIBRARY"); + ErrorDescriptionMap.put(NUMBERS_ERROR_COULDNOTLOADLIBRARY, "the library could not be loaded"); + ErrorCodeMap.put(NUMBERS_ERROR_COULDNOTFINDLIBRARYEXPORT, "NUMBERS_ERROR_COULDNOTFINDLIBRARYEXPORT"); + ErrorDescriptionMap.put(NUMBERS_ERROR_COULDNOTFINDLIBRARYEXPORT, "a required exported symbol could not be found in the library"); + ErrorCodeMap.put(NUMBERS_ERROR_INCOMPATIBLEBINARYVERSION, "NUMBERS_ERROR_INCOMPATIBLEBINARYVERSION"); + ErrorDescriptionMap.put(NUMBERS_ERROR_INCOMPATIBLEBINARYVERSION, "the version of the binary interface does not match the bindings interface"); + } + + protected int mErrorCode; + + protected String mErrorString; + + protected String mErrorDescription; + + public NumbersException(int errorCode, String message){ + super(message); + mErrorCode = errorCode; + mErrorString = ErrorCodeMap.get(errorCode); + mErrorString = (mErrorString != null) ? mErrorString : "Unknown error code"; + mErrorDescription = ErrorDescriptionMap.get(errorCode); + mErrorDescription = (mErrorDescription != null) ? mErrorDescription : ""; + } + + @Override + public String toString() { + return mErrorCode + ": " + mErrorString + " (" + mErrorDescription + " - " + getMessage() + ")"; + } +} + diff --git a/Examples/Injection/Numbers_component/Bindings/Java9/numbers/NumbersWrapper.java b/Examples/Injection/Numbers_component/Bindings/Java9/numbers/NumbersWrapper.java new file mode 100644 index 00000000..4fc302bf --- /dev/null +++ b/Examples/Injection/Numbers_component/Bindings/Java9/numbers/NumbersWrapper.java @@ -0,0 +1,269 @@ +/*++ + +Copyright (C) 2019 Numbers developers + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of Numbers library + +Interface version: 1.0.0 + +*/ + +package numbers; + +import com.sun.jna.*; + +import java.nio.charset.StandardCharsets; + + +public class NumbersWrapper { + + public static class EnumConversion { + } + + protected Function numbers_createvariable; + protected Function numbers_getversion; + protected Function numbers_getlasterror; + protected Function numbers_releaseinstance; + protected Function numbers_acquireinstance; + protected Function numbers_getsymbollookupmethod; + protected Function numbers_base_classtypeid; + protected Function numbers_variable_getvalue; + protected Function numbers_variable_setvalue; + + protected NativeLibrary mLibrary; + + public NumbersWrapper(String libraryPath) { + mLibrary = NativeLibrary.getInstance(libraryPath); + numbers_createvariable = mLibrary.getFunction("numbers_createvariable"); + numbers_getversion = mLibrary.getFunction("numbers_getversion"); + numbers_getlasterror = mLibrary.getFunction("numbers_getlasterror"); + numbers_releaseinstance = mLibrary.getFunction("numbers_releaseinstance"); + numbers_acquireinstance = mLibrary.getFunction("numbers_acquireinstance"); + numbers_getsymbollookupmethod = mLibrary.getFunction("numbers_getsymbollookupmethod"); + numbers_base_classtypeid = mLibrary.getFunction("numbers_base_classtypeid"); + numbers_variable_getvalue = mLibrary.getFunction("numbers_variable_getvalue"); + numbers_variable_setvalue = mLibrary.getFunction("numbers_variable_setvalue"); + } + + public NumbersWrapper(Pointer lookupPointer) throws NumbersException { + Function lookupMethod = Function.getFunction(lookupPointer); + numbers_createvariable = loadFunctionByLookup(lookupMethod, "numbers_createvariable"); + numbers_getversion = loadFunctionByLookup(lookupMethod, "numbers_getversion"); + numbers_getlasterror = loadFunctionByLookup(lookupMethod, "numbers_getlasterror"); + numbers_releaseinstance = loadFunctionByLookup(lookupMethod, "numbers_releaseinstance"); + numbers_acquireinstance = loadFunctionByLookup(lookupMethod, "numbers_acquireinstance"); + numbers_getsymbollookupmethod = loadFunctionByLookup(lookupMethod, "numbers_getsymbollookupmethod"); + numbers_base_classtypeid = loadFunctionByLookup(lookupMethod, "numbers_base_classtypeid"); + numbers_variable_getvalue = loadFunctionByLookup(lookupMethod, "numbers_variable_getvalue"); + numbers_variable_setvalue = loadFunctionByLookup(lookupMethod, "numbers_variable_setvalue"); + } + + protected void checkError(Base instance, int errorCode) throws NumbersException { + if (instance != null && instance.mWrapper != this) { + throw new NumbersException(NumbersException.NUMBERS_ERROR_INVALIDCAST, "invalid wrapper call"); + } + if (errorCode != NumbersException.NUMBERS_SUCCESS) { + if (instance != null) { + GetLastErrorResult result = getLastError(instance); + throw new NumbersException(errorCode, result.ErrorMessage); + } else { + throw new NumbersException(errorCode, ""); + } + } + } + + private Function loadFunctionByLookup(Function lookupMethod, String functionName) throws NumbersException { + byte[] bytes = functionName.getBytes(StandardCharsets.UTF_8); + Memory name = new Memory(bytes.length+1); + name.write(0, bytes, 0, bytes.length); + name.setByte(bytes.length, (byte)0); + Pointer address = new Memory(8); + java.lang.Object[] addressParam = new java.lang.Object[]{name, address}; + checkError(null, lookupMethod.invokeInt(addressParam)); + return Function.getFunction(address.getPointer(0)); + } + + /** + * Creates a new Variable instance + * + * @param initialValue Initial value of the new Variable + * @return New Variable instance + * @throws NumbersException + */ + public Variable createVariable(double initialValue) throws NumbersException { + Pointer bufferInstance = new Memory(8); + checkError(null, numbers_createvariable.invokeInt(new java.lang.Object[]{initialValue, bufferInstance})); + Pointer valueInstance = bufferInstance.getPointer(0); + Variable instance = null; + if (valueInstance == Pointer.NULL) { + throw new NumbersException(NumbersException.NUMBERS_ERROR_INVALIDPARAM, "Instance was a null pointer"); + } + instance = this.PolymorphicFactory(valueInstance, Variable.class); + return instance; + } + + /** + * retrieves the binary version of this library. + * + * @return GetVersion Result Tuple + * @throws NumbersException + */ + public GetVersionResult getVersion() throws NumbersException { + Pointer bufferMajor = new Memory(4); + Pointer bufferMinor = new Memory(4); + Pointer bufferMicro = new Memory(4); + checkError(null, numbers_getversion.invokeInt(new java.lang.Object[]{bufferMajor, bufferMinor, bufferMicro})); + GetVersionResult returnTuple = new GetVersionResult(); + returnTuple.Major = bufferMajor.getInt(0); + returnTuple.Minor = bufferMinor.getInt(0); + returnTuple.Micro = bufferMicro.getInt(0); + return returnTuple; + } + + public static class GetVersionResult { + /** + * returns the major version of this library + */ + public int Major; + + /** + * returns the minor version of this library + */ + public int Minor; + + /** + * returns the micro version of this library + */ + public int Micro; + + } + /** + * Returns the last error recorded on this object + * + * @param instance Instance Handle + * @return GetLastError Result Tuple + * @throws NumbersException + */ + public GetLastErrorResult getLastError(Base instance) throws NumbersException { + Pointer instanceHandle = null; + if (instance != null) { + instanceHandle = instance.getHandle(); + } else { + throw new NumbersException(NumbersException.NUMBERS_ERROR_INVALIDPARAM, "Instance is a null value."); + } + Pointer bytesNeededErrorMessage = new Memory(4); + Pointer bufferHasError = new Memory(1); + checkError(null, numbers_getlasterror.invokeInt(new java.lang.Object[]{instanceHandle, 0, bytesNeededErrorMessage, null, bufferHasError})); + int sizeErrorMessage = bytesNeededErrorMessage.getInt(0); + Pointer bufferErrorMessage = new Memory(sizeErrorMessage); + checkError(null, numbers_getlasterror.invokeInt(new java.lang.Object[]{instanceHandle, sizeErrorMessage, bytesNeededErrorMessage, bufferErrorMessage, bufferHasError})); + GetLastErrorResult returnTuple = new GetLastErrorResult(); + returnTuple.ErrorMessage = new String(bufferErrorMessage.getByteArray(0, sizeErrorMessage - 1), StandardCharsets.UTF_8); + returnTuple.HasError = bufferHasError.getByte(0) != 0; + return returnTuple; + } + + public static class GetLastErrorResult { + /** + * Message of the last error + */ + public String ErrorMessage; + + /** + * Is there a last error to query + */ + public boolean HasError; + + } + /** + * Releases shared ownership of an Instance + * + * @param instance Instance Handle + * @throws NumbersException + */ + public void releaseInstance(Base instance) throws NumbersException { + Pointer instanceHandle = null; + if (instance != null) { + instanceHandle = instance.getHandle(); + } else { + throw new NumbersException(NumbersException.NUMBERS_ERROR_INVALIDPARAM, "Instance is a null value."); + } + checkError(null, numbers_releaseinstance.invokeInt(new java.lang.Object[]{instanceHandle})); + } + + /** + * Acquires shared ownership of an Instance + * + * @param instance Instance Handle + * @throws NumbersException + */ + public void acquireInstance(Base instance) throws NumbersException { + Pointer instanceHandle = null; + if (instance != null) { + instanceHandle = instance.getHandle(); + } else { + throw new NumbersException(NumbersException.NUMBERS_ERROR_INVALIDPARAM, "Instance is a null value."); + } + checkError(null, numbers_acquireinstance.invokeInt(new java.lang.Object[]{instanceHandle})); + } + + /** + * Returns the address of the SymbolLookupMethod + * + * @return Address of the SymbolAddressMethod + * @throws NumbersException + */ + public Pointer getSymbolLookupMethod() throws NumbersException { + Pointer bufferSymbolLookupMethod = new Memory(8); + checkError(null, numbers_getsymbollookupmethod.invokeInt(new java.lang.Object[]{bufferSymbolLookupMethod})); + return bufferSymbolLookupMethod.getPointer(0); + } + + /** + * IMPORTANT: PolymorphicFactory method should not be used by application directly. + * It's designed to be used on NumbersHandle object only once. + * If it's used on any existing object as a form of dynamic cast then + * NumbersWrapper::acquireInstance(Base object) must be called after instantiating new object. + * This is important to keep reference count matching between application and library sides. + */ + public <T> T PolymorphicFactory(Pointer handle, Class<T> cls) { + if (handle == Pointer.NULL) + return null; + Class[] cArg = new Class[2]; + cArg[0] = NumbersWrapper.class; + cArg[1] = Pointer.class; + + try { + T obj = null; + Pointer bufferClassTypeId = new Memory(8); + checkError(null, numbers_base_classtypeid.invokeInt(new java.lang.Object[]{handle, bufferClassTypeId})); + long classTypeId = bufferClassTypeId.getLong(0); + + int msbId = (int)(classTypeId >> 32); + int lsbId = (int)classTypeId; + switch(msbId) { + case 0x23934EDF: + switch(lsbId) { + case 0x762423EA: obj = (T)(new Variable(this, handle)); break; // First 64 bits of SHA1 of a string: "Numbers::Variable" + } + break; + case 0x27799F69: + switch(lsbId) { + case 0xB3FD1C9E: obj = (T)(new Base(this, handle)); break; // First 64 bits of SHA1 of a string: "Numbers::Base" + } + break; + default: obj = cls.getDeclaredConstructor(cArg).newInstance(this, handle); break; + } + return obj; + } + catch(Exception e) { + return null; + } + } +} + diff --git a/Examples/Injection/Numbers_component/Bindings/Java9/numbers/Variable.java b/Examples/Injection/Numbers_component/Bindings/Java9/numbers/Variable.java new file mode 100644 index 00000000..3c4b660f --- /dev/null +++ b/Examples/Injection/Numbers_component/Bindings/Java9/numbers/Variable.java @@ -0,0 +1,59 @@ +/*++ + +Copyright (C) 2019 Numbers developers + +All rights reserved. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. + +Abstract: This is an autogenerated Java file in order to allow an easy + use of Numbers library + +Interface version: 1.0.0 + +*/ + +package numbers; + +import com.sun.jna.Library; +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import java.lang.ref.Cleaner; + + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; + +public class Variable extends Base { + + public Variable(NumbersWrapper wrapper, Pointer handle) { + super(wrapper, handle); + } + + /** + * Returns the current value of this Variable + * + * @return The current value of this Variable + * @throws NumbersException + */ + public double getValue() throws NumbersException { + Pointer bufferValue = new Memory(8); + mWrapper.checkError(this, mWrapper.numbers_variable_getvalue.invokeInt(new java.lang.Object[]{mHandle, bufferValue})); + return bufferValue.getDouble(0); + } + + /** + * Set the numerical value of this Variable + * + * @param value The new value of this Variable + * @throws NumbersException + */ + public void setValue(double value) throws NumbersException { + mWrapper.checkError(this, mWrapper.numbers_variable_setvalue.invokeInt(new java.lang.Object[]{mHandle, value})); + } + + +} + diff --git a/Examples/Injection/build.sh b/Examples/Injection/build.sh index e20b593b..74f81125 100755 --- a/Examples/Injection/build.sh +++ b/Examples/Injection/build.sh @@ -24,4 +24,6 @@ echo "Build and test bindings examples with C++ library" ./Calculation_component/Examples/Python/build.sh ./Calculation_component/Examples/Pascal/build.sh ./Calculation_component/Examples/CSharp/build.sh +./Calculation_component/Examples/Java9/build.sh + echo "Build and test are done and successful" \ No newline at end of file From 29a236b5db357cad5dfb3953a320f6d4627f4748 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Thu, 28 Oct 2021 14:38:10 -0700 Subject: [PATCH 108/143] Use full class type for injected components --- Source/buildbindinggo.go | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/buildbindinggo.go b/Source/buildbindinggo.go index 5bd64970..8eb41843 100644 --- a/Source/buildbindinggo.go +++ b/Source/buildbindinggo.go @@ -839,6 +839,7 @@ func writeGoMethod(method ComponentDefinitionMethod, w LanguageWriter, NameSpace for _, param := range method.Params { param.ParamName = toGoParam(param.ParamName) + param.ParamClass = strings.ReplaceAll(param.ParamClass, ":", "_") tp, err := getGoType(param.ParamType, NameSpace, param.ParamClass, param.ParamName, false) if err != nil { return err From 3a4594a211a3f6731d64e46286252930c86d1025 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Thu, 28 Oct 2021 14:38:29 -0700 Subject: [PATCH 109/143] Use correct header --- Source/buildbindingccpp.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index 4c7f53ce..db5ed08f 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -189,7 +189,11 @@ func buildDynamicCCPPHeader(component ComponentDefinition, w LanguageWriter, Nam } w.Writeln("") for _, subComponent := range(component.ImportedComponentDefinitions) { - w.Writeln("#include \"%s_types.hpp\"", subComponent.BaseName) + if useCPPTypes { + w.Writeln("#include \"%s_types.hpp\"", subComponent.BaseName) + } else { + w.Writeln("#include \"%s_types.h\"", subComponent.BaseName) + } } w.Writeln("") From 75b51bddc20722fa3a7b740fdc8d4bab83e7ca3a Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Thu, 28 Oct 2021 14:58:07 -0700 Subject: [PATCH 110/143] Remove CSharp example --- .../Bindings/CSharp/Calculation.cs | 255 ------------------ .../Examples/CSharp/Calculation_Example.cs | 52 ---- .../CSharp/Calculation_Example.csproj | 20 -- .../Examples/CSharp/Calculation_Example.sln | 25 -- .../Examples/CSharp/build.sh | 28 -- .../Bindings/CSharp/Numbers.cs | 216 --------------- Examples/Injection/build.sh | 1 - 7 files changed, 597 deletions(-) delete mode 100644 Examples/Injection/Calculation_component/Bindings/CSharp/Calculation.cs delete mode 100644 Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.cs delete mode 100644 Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.csproj delete mode 100644 Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.sln delete mode 100755 Examples/Injection/Calculation_component/Examples/CSharp/build.sh delete mode 100644 Examples/Injection/Numbers_component/Bindings/CSharp/Numbers.cs diff --git a/Examples/Injection/Calculation_component/Bindings/CSharp/Calculation.cs b/Examples/Injection/Calculation_component/Bindings/CSharp/Calculation.cs deleted file mode 100644 index f453459a..00000000 --- a/Examples/Injection/Calculation_component/Bindings/CSharp/Calculation.cs +++ /dev/null @@ -1,255 +0,0 @@ -using System; -using System.Text; -using System.Runtime.InteropServices; - -namespace Calculation { - - - namespace Internal { - - - public class CalculationWrapper - { - [DllImport("calculation.dll", EntryPoint = "calculation_base_classtypeid", CallingConvention=CallingConvention.Cdecl)] - public unsafe extern static Int32 Base_ClassTypeId (IntPtr Handle, out UInt64 AClassTypeId); - - [DllImport("calculation.dll", EntryPoint = "calculation_calculator_enlistvariable", CallingConvention=CallingConvention.Cdecl)] - public unsafe extern static Int32 Calculator_EnlistVariable (IntPtr Handle, IntPtr AVariable); - - [DllImport("calculation.dll", EntryPoint = "calculation_calculator_getenlistedvariable", CallingConvention=CallingConvention.Cdecl)] - public unsafe extern static Int32 Calculator_GetEnlistedVariable (IntPtr Handle, UInt32 AIndex, out IntPtr AVariable); - - [DllImport("calculation.dll", EntryPoint = "calculation_calculator_clearvariables", CallingConvention=CallingConvention.Cdecl)] - public unsafe extern static Int32 Calculator_ClearVariables (IntPtr Handle); - - [DllImport("calculation.dll", EntryPoint = "calculation_calculator_multiply", CallingConvention=CallingConvention.Cdecl)] - public unsafe extern static Int32 Calculator_Multiply (IntPtr Handle, out IntPtr AInstance); - - [DllImport("calculation.dll", EntryPoint = "calculation_calculator_add", CallingConvention=CallingConvention.Cdecl)] - public unsafe extern static Int32 Calculator_Add (IntPtr Handle, out IntPtr AInstance); - - [DllImport("calculation.dll", EntryPoint = "calculation_createcalculator", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] - public extern static Int32 CreateCalculator (out IntPtr AInstance); - - [DllImport("calculation.dll", EntryPoint = "calculation_getversion", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] - public extern static Int32 GetVersion (out UInt32 AMajor, out UInt32 AMinor, out UInt32 AMicro); - - [DllImport("calculation.dll", EntryPoint = "calculation_getlasterror", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] - public extern static Int32 GetLastError (IntPtr AInstance, UInt32 sizeErrorMessage, out UInt32 neededErrorMessage, IntPtr dataErrorMessage, out Byte AHasError); - - [DllImport("calculation.dll", EntryPoint = "calculation_releaseinstance", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] - public extern static Int32 ReleaseInstance (IntPtr AInstance); - - [DllImport("calculation.dll", EntryPoint = "calculation_acquireinstance", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] - public extern static Int32 AcquireInstance (IntPtr AInstance); - - [DllImport("calculation.dll", EntryPoint = "calculation_injectcomponent", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] - public extern static Int32 InjectComponent (byte[] ANameSpace, UInt64 ASymbolAddressMethod); - - [DllImport("calculation.dll", EntryPoint = "calculation_getsymbollookupmethod", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] - public extern static Int32 GetSymbolLookupMethod (out UInt64 ASymbolLookupMethod); - - public static void ThrowError(IntPtr Handle, Int32 errorCode) - { - String sMessage = "Calculation Error"; - if (Handle != IntPtr.Zero) { - UInt32 sizeMessage = 0; - UInt32 neededMessage = 0; - Byte hasLastError = 0; - Int32 resultCode1 = GetLastError (Handle, sizeMessage, out neededMessage, IntPtr.Zero, out hasLastError); - if ((resultCode1 == 0) && (hasLastError != 0)) { - sizeMessage = neededMessage; - byte[] bytesMessage = new byte[sizeMessage]; - - GCHandle dataMessage = GCHandle.Alloc(bytesMessage, GCHandleType.Pinned); - Int32 resultCode2 = GetLastError(Handle, sizeMessage, out neededMessage, dataMessage.AddrOfPinnedObject(), out hasLastError); - dataMessage.Free(); - - if ((resultCode2 == 0) && (hasLastError != 0)) { - sMessage = sMessage + ": " + Encoding.UTF8.GetString(bytesMessage).TrimEnd(char.MinValue); - } - } - } - - throw new Exception(sMessage + "(# " + errorCode + ")"); - } - - /** - * IMPORTANT: PolymorphicFactory method should not be used by application directly. - * It's designed to be used on Handle object only once. - * If it's used on any existing object as a form of dynamic cast then - * CalculationWrapper::AcquireInstance(CBase object) must be called after instantiating new object. - * This is important to keep reference count matching between application and library sides. - */ - public static T PolymorphicFactory<T>(IntPtr Handle) where T : class - { - T Object; - if (Handle == IntPtr.Zero) - return System.Activator.CreateInstance(typeof(T), Handle) as T; - - UInt64 resultClassTypeId = 0; - Int32 errorCode = Base_ClassTypeId (Handle, out resultClassTypeId); - if (errorCode != 0) - ThrowError (IntPtr.Zero, errorCode); - switch (resultClassTypeId) { - case 0x3BA5271BAB410E5D: Object = new CBase(Handle) as T; break; // First 64 bits of SHA1 of a string: "Calculation::Base" - case 0xB23F514353D0C606: Object = new CCalculator(Handle) as T; break; // First 64 bits of SHA1 of a string: "Calculation::Calculator" - default: Object = System.Activator.CreateInstance(typeof(T), Handle) as T; break; - } - return Object; - } - - } - } - - - public class CBase - { - protected IntPtr Handle; - - public CBase (IntPtr NewHandle) - { - Handle = NewHandle; - } - - ~CBase () - { - if (Handle != IntPtr.Zero) { - Internal.CalculationWrapper.ReleaseInstance (Handle); - Handle = IntPtr.Zero; - } - } - - protected void CheckError (Int32 errorCode) - { - if (errorCode != 0) { - Internal.CalculationWrapper.ThrowError (Handle, errorCode); - } - } - - public IntPtr GetHandle () - { - return Handle; - } - - public UInt64 ClassTypeId () - { - UInt64 resultClassTypeId = 0; - - CheckError(Internal.CalculationWrapper.Base_ClassTypeId (Handle, out resultClassTypeId)); - return resultClassTypeId; - } - - } - - public class CCalculator : CBase - { - public CCalculator (IntPtr NewHandle) : base (NewHandle) - { - } - - public void EnlistVariable (IntPtr AVariable) - { - - CheckError(Internal.CalculationWrapper.Calculator_EnlistVariable (Handle, AVariable)); - } - - public IntPtr GetEnlistedVariable (UInt32 AIndex) - { - IntPtr newVariable = IntPtr.Zero; - - CheckError(Internal.CalculationWrapper.Calculator_GetEnlistedVariable (Handle, AIndex, out newVariable)); - return newVariable; - } - - public void ClearVariables () - { - - CheckError(Internal.CalculationWrapper.Calculator_ClearVariables (Handle)); - } - - public IntPtr Multiply () - { - IntPtr newInstance = IntPtr.Zero; - - CheckError(Internal.CalculationWrapper.Calculator_Multiply (Handle, out newInstance)); - return newInstance; - } - - public IntPtr Add () - { - IntPtr newInstance = IntPtr.Zero; - - CheckError(Internal.CalculationWrapper.Calculator_Add (Handle, out newInstance)); - return newInstance; - } - - } - - class Wrapper - { - private static void CheckError (Int32 errorCode) - { - if (errorCode != 0) { - Internal.CalculationWrapper.ThrowError (IntPtr.Zero, errorCode); - } - } - - public static CCalculator CreateCalculator () - { - IntPtr newInstance = IntPtr.Zero; - - CheckError(Internal.CalculationWrapper.CreateCalculator (out newInstance)); - return Internal.CalculationWrapper.PolymorphicFactory<CCalculator>(newInstance); - } - - public static void GetVersion (out UInt32 AMajor, out UInt32 AMinor, out UInt32 AMicro) - { - - CheckError(Internal.CalculationWrapper.GetVersion (out AMajor, out AMinor, out AMicro)); - } - - public static bool GetLastError (CBase AInstance, out String AErrorMessage) - { - Byte resultHasError = 0; - UInt32 sizeErrorMessage = 0; - UInt32 neededErrorMessage = 0; - CheckError(Internal.CalculationWrapper.GetLastError (AInstance.GetHandle(), sizeErrorMessage, out neededErrorMessage, IntPtr.Zero, out resultHasError)); - sizeErrorMessage = neededErrorMessage; - byte[] bytesErrorMessage = new byte[sizeErrorMessage]; - GCHandle dataErrorMessage = GCHandle.Alloc(bytesErrorMessage, GCHandleType.Pinned); - - CheckError(Internal.CalculationWrapper.GetLastError (AInstance.GetHandle(), sizeErrorMessage, out neededErrorMessage, dataErrorMessage.AddrOfPinnedObject(), out resultHasError)); - dataErrorMessage.Free(); - AErrorMessage = Encoding.UTF8.GetString(bytesErrorMessage).TrimEnd(char.MinValue); - return (resultHasError != 0); - } - - public static void ReleaseInstance (CBase AInstance) - { - - CheckError(Internal.CalculationWrapper.ReleaseInstance (AInstance.GetHandle())); - } - - public static void AcquireInstance (CBase AInstance) - { - - CheckError(Internal.CalculationWrapper.AcquireInstance (AInstance.GetHandle())); - } - - public static void InjectComponent (String ANameSpace, UInt64 ASymbolAddressMethod) - { - throw new Exception("Component injection is not supported in CSharp."); - } - - public static UInt64 GetSymbolLookupMethod () - { - UInt64 resultSymbolLookupMethod = 0; - - CheckError(Internal.CalculationWrapper.GetSymbolLookupMethod (out resultSymbolLookupMethod)); - return resultSymbolLookupMethod; - } - - } - -} diff --git a/Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.cs b/Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.cs deleted file mode 100644 index 979397a9..00000000 --- a/Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.cs +++ /dev/null @@ -1,52 +0,0 @@ -/*++ - -Copyright (C) 2019 Calculation developers - -All rights reserved. - -This file has been generated by the Automatic Component Toolkit (ACT) version 1.7.0-develop. - -Abstract: This is an autogenerated CSharp application that demonstrates the - usage of the CSharp bindings of Calculation library - -Interface version: 1.0.0 - -*/ - - -using System; -namespace Calculation_Example -{ - class Calculation_Example - { - static void Main() - { - try - { - UInt32 nMajor, nMinor, nMicro; - Calculation.Wrapper.GetVersion(out nMajor, out nMinor, out nMicro); - string versionString = string.Format("Calculation.version = {0}.{1}.{2}", nMajor, nMinor, nMicro); - Console.WriteLine(versionString); - - Numbers.Wrapper.GetVersion(out nMajor, out nMinor, out nMicro); - versionString = string.Format("Numbers.version = {0}.{1}.{2}", nMajor, nMinor, nMicro); - Console.WriteLine(versionString); - - try - { - Calculation.Wrapper.InjectComponent("Numbers", Numbers.Wrapper.GetSymbolLookupMethod()); - } - catch (Exception e) - { - if (!e.Message.Equals("Component injection is not supported in CSharp.")) - throw new Exception("CSharp must throw correct exception here!"); - } - } - catch (Exception e) - { - Console.WriteLine("Exception: \"" + e.Message + "\""); - } - } - } -} - diff --git a/Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.csproj b/Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.csproj deleted file mode 100644 index 5081066a..00000000 --- a/Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.csproj +++ /dev/null @@ -1,20 +0,0 @@ - -<Project Sdk="Microsoft.NET.Sdk"> - <PropertyGroup> - <OutputType>Exe</OutputType> - <TargetFramework>netstandard2.0</TargetFramework> - <StartupObject>Calculation_Example.Calculation_Example</StartupObject> - <ApplicationIcon /> - <Platforms>x64</Platforms> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <AllowUnsafeBlocks>true</AllowUnsafeBlocks> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <AllowUnsafeBlocks>true</AllowUnsafeBlocks> - </PropertyGroup> - <ItemGroup> - <Compile Include="..\..\..\Calculation_component\Bindings\CSharp\Calculation.cs" Link="Calculation.cs" /> - <Compile Include="..\..\..\Numbers_component\Bindings\CSharp\Numbers.cs" Link="Numbers.cs" /> - </ItemGroup> -</Project> diff --git a/Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.sln b/Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.sln deleted file mode 100644 index b632dab1..00000000 --- a/Examples/Injection/Calculation_component/Examples/CSharp/Calculation_Example.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.539 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("45c3ad66-1592-4cee-bfef-8a882bf392aa") = "Calculation_Example", "Calculation_Example.csproj", "b1261bbe-ddc3-4a19-af8e-957f5c39eadc" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - b1261bbe-ddc3-4a19-af8e-957f5c39eadc.Debug|x64.ActiveCfg = Debug|x64 - b1261bbe-ddc3-4a19-af8e-957f5c39eadc.Debug|x64.Build.0 = Debug|x64 - b1261bbe-ddc3-4a19-af8e-957f5c39eadc.Release|x64.ActiveCfg = Release|x64 - b1261bbe-ddc3-4a19-af8e-957f5c39eadc.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = fc7c62d7-4c16-4553-bd1e-fb64a195606b - EndGlobalSection -EndGlobal diff --git a/Examples/Injection/Calculation_component/Examples/CSharp/build.sh b/Examples/Injection/Calculation_component/Examples/CSharp/build.sh deleted file mode 100755 index 8f174a8b..00000000 --- a/Examples/Injection/Calculation_component/Examples/CSharp/build.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -set -euxo pipefail - -cd "$(dirname "$0")" -source ../../../../../Build/build.inc - -echo "Build Go example" - -[ -d bin ] && rm -rf bin -[ -d obj ] && rm -rf obj -msbuild /p:Configuration=Debug /t:Restore Calculation_Example.csproj -msbuild /p:Configuration=Debug /p:AllowUnsafeBlocks=true Calculation_Example.csproj - -pushd bin/Debug/netstandard2.0 -echo "Test C++ library" -rm -f calculation.dll numbers.dll -ln -s ../../../../../../Calculation_component/Implementations/Cpp/build/calculation$OSLIBEXT calculation.dll -ln -s ../../../../../../Numbers_component/Implementations/Cpp/build/numbers$OSLIBEXT numbers.dll -RUN "mono Calculation_Example.dll" . - -echo "Test Pascal library" -rm -f calculation.dll numbers.dll -ln -s ../../../../../../Calculation_component/Implementations/Pascal/build/calculation$OSLIBEXT calculation.dll -ln -s ../../../../../../Numbers_component/Implementations/Pascal/build/numbers$OSLIBEXT numbers.dll -RUN "mono Calculation_Example.dll" . - -popd \ No newline at end of file diff --git a/Examples/Injection/Numbers_component/Bindings/CSharp/Numbers.cs b/Examples/Injection/Numbers_component/Bindings/CSharp/Numbers.cs deleted file mode 100644 index a7988a89..00000000 --- a/Examples/Injection/Numbers_component/Bindings/CSharp/Numbers.cs +++ /dev/null @@ -1,216 +0,0 @@ -using System; -using System.Text; -using System.Runtime.InteropServices; - -namespace Numbers { - - - namespace Internal { - - - public class NumbersWrapper - { - [DllImport("numbers.dll", EntryPoint = "numbers_base_classtypeid", CallingConvention=CallingConvention.Cdecl)] - public unsafe extern static Int32 Base_ClassTypeId (IntPtr Handle, out UInt64 AClassTypeId); - - [DllImport("numbers.dll", EntryPoint = "numbers_variable_getvalue", CallingConvention=CallingConvention.Cdecl)] - public unsafe extern static Int32 Variable_GetValue (IntPtr Handle, out Double AValue); - - [DllImport("numbers.dll", EntryPoint = "numbers_variable_setvalue", CallingConvention=CallingConvention.Cdecl)] - public unsafe extern static Int32 Variable_SetValue (IntPtr Handle, Double AValue); - - [DllImport("numbers.dll", EntryPoint = "numbers_createvariable", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] - public extern static Int32 CreateVariable (Double AInitialValue, out IntPtr AInstance); - - [DllImport("numbers.dll", EntryPoint = "numbers_getversion", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] - public extern static Int32 GetVersion (out UInt32 AMajor, out UInt32 AMinor, out UInt32 AMicro); - - [DllImport("numbers.dll", EntryPoint = "numbers_getlasterror", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] - public extern static Int32 GetLastError (IntPtr AInstance, UInt32 sizeErrorMessage, out UInt32 neededErrorMessage, IntPtr dataErrorMessage, out Byte AHasError); - - [DllImport("numbers.dll", EntryPoint = "numbers_releaseinstance", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] - public extern static Int32 ReleaseInstance (IntPtr AInstance); - - [DllImport("numbers.dll", EntryPoint = "numbers_acquireinstance", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] - public extern static Int32 AcquireInstance (IntPtr AInstance); - - [DllImport("numbers.dll", EntryPoint = "numbers_getsymbollookupmethod", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] - public extern static Int32 GetSymbolLookupMethod (out UInt64 ASymbolLookupMethod); - - public static void ThrowError(IntPtr Handle, Int32 errorCode) - { - String sMessage = "Numbers Error"; - if (Handle != IntPtr.Zero) { - UInt32 sizeMessage = 0; - UInt32 neededMessage = 0; - Byte hasLastError = 0; - Int32 resultCode1 = GetLastError (Handle, sizeMessage, out neededMessage, IntPtr.Zero, out hasLastError); - if ((resultCode1 == 0) && (hasLastError != 0)) { - sizeMessage = neededMessage; - byte[] bytesMessage = new byte[sizeMessage]; - - GCHandle dataMessage = GCHandle.Alloc(bytesMessage, GCHandleType.Pinned); - Int32 resultCode2 = GetLastError(Handle, sizeMessage, out neededMessage, dataMessage.AddrOfPinnedObject(), out hasLastError); - dataMessage.Free(); - - if ((resultCode2 == 0) && (hasLastError != 0)) { - sMessage = sMessage + ": " + Encoding.UTF8.GetString(bytesMessage).TrimEnd(char.MinValue); - } - } - } - - throw new Exception(sMessage + "(# " + errorCode + ")"); - } - - /** - * IMPORTANT: PolymorphicFactory method should not be used by application directly. - * It's designed to be used on Handle object only once. - * If it's used on any existing object as a form of dynamic cast then - * NumbersWrapper::AcquireInstance(CBase object) must be called after instantiating new object. - * This is important to keep reference count matching between application and library sides. - */ - public static T PolymorphicFactory<T>(IntPtr Handle) where T : class - { - T Object; - if (Handle == IntPtr.Zero) - return System.Activator.CreateInstance(typeof(T), Handle) as T; - - UInt64 resultClassTypeId = 0; - Int32 errorCode = Base_ClassTypeId (Handle, out resultClassTypeId); - if (errorCode != 0) - ThrowError (IntPtr.Zero, errorCode); - switch (resultClassTypeId) { - case 0x27799F69B3FD1C9E: Object = new CBase(Handle) as T; break; // First 64 bits of SHA1 of a string: "Numbers::Base" - case 0x23934EDF762423EA: Object = new CVariable(Handle) as T; break; // First 64 bits of SHA1 of a string: "Numbers::Variable" - default: Object = System.Activator.CreateInstance(typeof(T), Handle) as T; break; - } - return Object; - } - - } - } - - - public class CBase - { - protected IntPtr Handle; - - public CBase (IntPtr NewHandle) - { - Handle = NewHandle; - } - - ~CBase () - { - if (Handle != IntPtr.Zero) { - Internal.NumbersWrapper.ReleaseInstance (Handle); - Handle = IntPtr.Zero; - } - } - - protected void CheckError (Int32 errorCode) - { - if (errorCode != 0) { - Internal.NumbersWrapper.ThrowError (Handle, errorCode); - } - } - - public IntPtr GetHandle () - { - return Handle; - } - - public UInt64 ClassTypeId () - { - UInt64 resultClassTypeId = 0; - - CheckError(Internal.NumbersWrapper.Base_ClassTypeId (Handle, out resultClassTypeId)); - return resultClassTypeId; - } - - } - - public class CVariable : CBase - { - public CVariable (IntPtr NewHandle) : base (NewHandle) - { - } - - public Double GetValue () - { - Double resultValue = 0; - - CheckError(Internal.NumbersWrapper.Variable_GetValue (Handle, out resultValue)); - return resultValue; - } - - public void SetValue (Double AValue) - { - - CheckError(Internal.NumbersWrapper.Variable_SetValue (Handle, AValue)); - } - - } - - class Wrapper - { - private static void CheckError (Int32 errorCode) - { - if (errorCode != 0) { - Internal.NumbersWrapper.ThrowError (IntPtr.Zero, errorCode); - } - } - - public static CVariable CreateVariable (Double AInitialValue) - { - IntPtr newInstance = IntPtr.Zero; - - CheckError(Internal.NumbersWrapper.CreateVariable (AInitialValue, out newInstance)); - return Internal.NumbersWrapper.PolymorphicFactory<CVariable>(newInstance); - } - - public static void GetVersion (out UInt32 AMajor, out UInt32 AMinor, out UInt32 AMicro) - { - - CheckError(Internal.NumbersWrapper.GetVersion (out AMajor, out AMinor, out AMicro)); - } - - public static bool GetLastError (CBase AInstance, out String AErrorMessage) - { - Byte resultHasError = 0; - UInt32 sizeErrorMessage = 0; - UInt32 neededErrorMessage = 0; - CheckError(Internal.NumbersWrapper.GetLastError (AInstance.GetHandle(), sizeErrorMessage, out neededErrorMessage, IntPtr.Zero, out resultHasError)); - sizeErrorMessage = neededErrorMessage; - byte[] bytesErrorMessage = new byte[sizeErrorMessage]; - GCHandle dataErrorMessage = GCHandle.Alloc(bytesErrorMessage, GCHandleType.Pinned); - - CheckError(Internal.NumbersWrapper.GetLastError (AInstance.GetHandle(), sizeErrorMessage, out neededErrorMessage, dataErrorMessage.AddrOfPinnedObject(), out resultHasError)); - dataErrorMessage.Free(); - AErrorMessage = Encoding.UTF8.GetString(bytesErrorMessage).TrimEnd(char.MinValue); - return (resultHasError != 0); - } - - public static void ReleaseInstance (CBase AInstance) - { - - CheckError(Internal.NumbersWrapper.ReleaseInstance (AInstance.GetHandle())); - } - - public static void AcquireInstance (CBase AInstance) - { - - CheckError(Internal.NumbersWrapper.AcquireInstance (AInstance.GetHandle())); - } - - public static UInt64 GetSymbolLookupMethod () - { - UInt64 resultSymbolLookupMethod = 0; - - CheckError(Internal.NumbersWrapper.GetSymbolLookupMethod (out resultSymbolLookupMethod)); - return resultSymbolLookupMethod; - } - - } - -} diff --git a/Examples/Injection/build.sh b/Examples/Injection/build.sh index 74f81125..97ce415c 100755 --- a/Examples/Injection/build.sh +++ b/Examples/Injection/build.sh @@ -23,7 +23,6 @@ echo "Build and test bindings examples with C++ library" ./Calculation_component/Examples/CppDynamic/build.sh ./Calculation_component/Examples/Python/build.sh ./Calculation_component/Examples/Pascal/build.sh -./Calculation_component/Examples/CSharp/build.sh ./Calculation_component/Examples/Java9/build.sh echo "Build and test are done and successful" \ No newline at end of file From ec0c1233ba34209a3321369720679c4a80570dbb Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Thu, 28 Oct 2021 16:05:53 -0700 Subject: [PATCH 111/143] Remove CSharp example --- Examples/Injection/Calculation.xml | 1 - Examples/Injection/Numbers.xml | 1 - 2 files changed, 2 deletions(-) diff --git a/Examples/Injection/Calculation.xml b/Examples/Injection/Calculation.xml index 35e03a28..02e20152 100644 --- a/Examples/Injection/Calculation.xml +++ b/Examples/Injection/Calculation.xml @@ -13,7 +13,6 @@ <bindings> <binding language="Cpp" indentation="tabs" /> <binding language="CppDynamic" indentation="tabs" /> - <binding language="CSharp" indentation="tabs" /> <binding language="Pascal" indentation="2spaces" /> <binding language="Python" indentation="tabs" /> </bindings> diff --git a/Examples/Injection/Numbers.xml b/Examples/Injection/Numbers.xml index a70149f9..0c49fcf4 100644 --- a/Examples/Injection/Numbers.xml +++ b/Examples/Injection/Numbers.xml @@ -8,7 +8,6 @@ <bindings> <binding language="CppDynamic" indentation="tabs" /> - <binding language="CSharp" indentation="tabs" /> <binding language="Pascal" indentation="2spaces" /> <binding language="Python" indentation="tabs" /> </bindings> From 24c09f131bde790f3b01bd692b6608a6d0adbc88 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Thu, 28 Oct 2021 16:35:45 -0700 Subject: [PATCH 112/143] Restore Java bindings generation --- Examples/Injection/Calculation.xml | 1 + Examples/Injection/Numbers.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/Examples/Injection/Calculation.xml b/Examples/Injection/Calculation.xml index 02e20152..b75f88b9 100644 --- a/Examples/Injection/Calculation.xml +++ b/Examples/Injection/Calculation.xml @@ -15,6 +15,7 @@ <binding language="CppDynamic" indentation="tabs" /> <binding language="Pascal" indentation="2spaces" /> <binding language="Python" indentation="tabs" /> + <binding language="Java" indentation="tabs" /> </bindings> <implementations> <implementation language="Cpp" indentation="tabs"/> diff --git a/Examples/Injection/Numbers.xml b/Examples/Injection/Numbers.xml index 0c49fcf4..bead17f0 100644 --- a/Examples/Injection/Numbers.xml +++ b/Examples/Injection/Numbers.xml @@ -10,6 +10,7 @@ <binding language="CppDynamic" indentation="tabs" /> <binding language="Pascal" indentation="2spaces" /> <binding language="Python" indentation="tabs" /> + <binding language="Java" indentation="tabs" /> </bindings> <implementations> <implementation language="Cpp" indentation="tabs"/> From aa11c6d495acb8b3271bdb6844f751cda5e47c30 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Thu, 4 Nov 2021 23:16:51 -0700 Subject: [PATCH 113/143] Add more covarage with object as a argument --- Examples/RTTI/RTTI.xml | 9 +++++++++ .../Cpp/Stub/rtti_animaliterator.cpp | 12 ++++++++++++ .../Cpp/Stub/rtti_animaliterator.hpp | 2 ++ .../Implementations/Pascal/Interfaces/rtti.lpr | 4 +++- .../Pascal/Stub/rtti_impl_animaliterator.pas | 15 +++++++++++++++ 5 files changed, 41 insertions(+), 1 deletion(-) diff --git a/Examples/RTTI/RTTI.xml b/Examples/RTTI/RTTI.xml index 5320da63..a564949d 100644 --- a/Examples/RTTI/RTTI.xml +++ b/Examples/RTTI/RTTI.xml @@ -72,6 +72,15 @@ <method name="GetNextAnimal" description="Return next animal"> <param name="Animal" pass="return" type="optionalclass" class="Animal"/> </method> + <method name="GetNextOptinalAnimal" description="Return next animal"> + <param name="Animal" pass="out" type="optionalclass" class="Animal"/> + <param name="Error" pass="return" type="bool"/> + </method> + <method name="GetNextMandatoryAnimal" description="Return next animal"> + <param name="Animal" pass="out" type="optionalclass" class="Animal"/> + <param name="Error" pass="return" type="bool"/> + </method> + </class> <class name="Zoo" description=""> diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.cpp index f7cd5cc2..ea7be6a3 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.cpp @@ -35,3 +35,15 @@ IAnimal * CAnimalIterator::GetNextAnimal() return nullptr; } } + +bool CAnimalIterator::GetNextOptinalAnimal(IAnimal*& pAnimal) +{ + pAnimal = GetNextAnimal(); + return true; +} + +bool CAnimalIterator::GetNextMandatoryAnimal(IAnimal*& pAnimal) +{ + pAnimal = GetNextAnimal(); + return true; +} diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.hpp index f7ec566b..b1cc9ec8 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.hpp @@ -59,6 +59,8 @@ class CAnimalIterator : public virtual IAnimalIterator, public virtual CBase { */ IAnimal * GetNextAnimal() override; + bool GetNextOptinalAnimal(IAnimal*& pAnimal) override; + bool GetNextMandatoryAnimal(IAnimal*& pAnimal) override; }; diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti.lpr b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti.lpr index e4df19c3..5ddfdd2a 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti.lpr +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti.lpr @@ -1,6 +1,6 @@ (*++ -Copyright (C) 2020 ADSK +Copyright (C) 2021 ADSK All rights reserved. @@ -31,6 +31,8 @@ rtti_animal_name, rtti_tiger_roar, rtti_animaliterator_getnextanimal, + rtti_animaliterator_getnextoptinalanimal, + rtti_animaliterator_getnextmandatoryanimal, rtti_zoo_iterator, rtti_getversion, rtti_getlasterror, diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animaliterator.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animaliterator.pas index 8c89c98c..c482bd90 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animaliterator.pas +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animaliterator.pas @@ -33,6 +33,9 @@ TRTTIAnimalIterator = class(TRTTIBase, IRTTIAnimalIterator) constructor Create(Animals: TList); function GetNextAnimal(): TObject; + function GetNextOptinalAnimal(out AAnimal: TObject): Boolean; + function GetNextMandatoryAnimal(out AAnimal: TObject): Boolean; + protected end; @@ -58,4 +61,16 @@ function TRTTIAnimalIterator.GetNextAnimal(): TObject; Index := Index + 1; end; +function TRTTIAnimalIterator.GetNextOptinalAnimal(out AAnimal: TObject): Boolean; +begin + AAnimal := GetNextAnimal(); + Result := true; +end; + +function TRTTIAnimalIterator.GetNextMandatoryAnimal(out AAnimal: TObject): Boolean; +begin + AAnimal := GetNextAnimal(); + Result := true; +end; + end. From 61c71945c0c9de88749ebc5b00c0092147c0ce18 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Thu, 4 Nov 2021 23:17:45 -0700 Subject: [PATCH 114/143] Fix warnings --- .../Implementations/Pascal/Stub/rtti_impl_animal.pas | 2 +- .../Implementations/Pascal/Stub/rtti_impl_animaliterator.pas | 2 +- .../Implementations/Pascal/Stub/rtti_impl_giraffe.pas | 2 +- .../Implementations/Pascal/Stub/rtti_impl_mammal.pas | 2 +- .../Implementations/Pascal/Stub/rtti_impl_tiger.pas | 2 +- .../Implementations/Pascal/Stub/rtti_impl_turtle.pas | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animal.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animal.pas index 8db65ce8..bb281235 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animal.pas +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animal.pas @@ -38,7 +38,7 @@ implementation function TRTTIAnimal.ClassTypeId(): QWord; begin - Result := $8B40467DA6D327AF; // First 64 bits of SHA1 of a string: "RTTI::Animal" + Result := QWord($8B40467DA6D327AF); // First 64 bits of SHA1 of a string: "RTTI::Animal" end; function TRTTIAnimal.Name(): String; diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animaliterator.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animaliterator.pas index c482bd90..f1aa5418 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animaliterator.pas +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animaliterator.pas @@ -43,7 +43,7 @@ implementation function TRTTIAnimalIterator.ClassTypeId(): QWord; begin - Result := $F1917FE6BBE77831; // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" + Result := QWord($F1917FE6BBE77831); // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" end; constructor TRTTIAnimalIterator.Create(Animals: TList); diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_giraffe.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_giraffe.pas index b9ce348a..37ebe69c 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_giraffe.pas +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_giraffe.pas @@ -35,7 +35,7 @@ implementation function TRTTIGiraffe.ClassTypeId(): QWord; begin - Result := $9751971BD2C2D958; // First 64 bits of SHA1 of a string: "RTTI::Giraffe" + Result := QWord($9751971BD2C2D958); // First 64 bits of SHA1 of a string: "RTTI::Giraffe" end; end. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_mammal.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_mammal.pas index 58578b7b..9f062c4c 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_mammal.pas +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_mammal.pas @@ -35,7 +35,7 @@ implementation function TRTTIMammal.ClassTypeId(): QWord; begin - Result := $BC9D5FA7750C1020; // First 64 bits of SHA1 of a string: "RTTI::Mammal" + Result := QWord($BC9D5FA7750C1020); // First 64 bits of SHA1 of a string: "RTTI::Mammal" end; end. diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_tiger.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_tiger.pas index 91888ae2..fd8b04f6 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_tiger.pas +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_tiger.pas @@ -36,7 +36,7 @@ implementation function TRTTITiger.ClassTypeId(): QWord; begin - Result := $08D007E7B5F7BAF4; // First 64 bits of SHA1 of a string: "RTTI::Tiger" + Result := QWord($08D007E7B5F7BAF4); // First 64 bits of SHA1 of a string: "RTTI::Tiger" end; procedure TRTTITiger.Roar(); diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_turtle.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_turtle.pas index 6464f76b..63c2dca9 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_turtle.pas +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_turtle.pas @@ -35,7 +35,7 @@ implementation function TRTTITurtle.ClassTypeId(): QWord; begin - Result := $8E551B208A2E8321; // First 64 bits of SHA1 of a string: "RTTI::Turtle" + Result := QWord($8E551B208A2E8321); // First 64 bits of SHA1 of a string: "RTTI::Turtle" end; end. From fb63dc1dd4f13300d3037703a4f279f9d53a78c3 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Thu, 4 Nov 2021 23:36:55 -0700 Subject: [PATCH 115/143] Don't use templates for PolymorficFactory An attempt to avoid increased memory consumption of MSVC compiler. --- Source/buildbindingccpp.go | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index db5ed08f..8aea8f74 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -699,9 +699,10 @@ func writeDynamicCPPMethod(method ComponentDefinitionMethod, w LanguageWriter, N callParameter = fmt.Sprintf("&h%s", param.ParamName) initCallParameter = callParameter + CPPClass := fmt.Sprintf("%s%s%s", cppClassPrefix, ClassIdentifier, param.ParamClass) if (param.ParamType == "optionalclass") { postCallCodeLines = append(postCallCodeLines, fmt.Sprintf("if (h%s) {", param.ParamName)) - postCallCodeLines = append(postCallCodeLines, fmt.Sprintf(" p%s = %s->polymorphicFactory<%s%s%s>(h%s);", param.ParamName, makeSharedParameter, cppClassPrefix, ClassIdentifier, param.ParamClass, param.ParamName)) + postCallCodeLines = append(postCallCodeLines, fmt.Sprintf(" p%s = std::shared_ptr<%s>(dynamic_cast<%s*>(%s->polymorphicFactory(h%s)));", param.ParamName, CPPClass, CPPClass, makeSharedParameter, param.ParamName)) postCallCodeLines = append(postCallCodeLines, fmt.Sprintf("} else {")) postCallCodeLines = append(postCallCodeLines, fmt.Sprintf(" p%s = nullptr;", param.ParamName)) postCallCodeLines = append(postCallCodeLines, fmt.Sprintf("}")) @@ -709,7 +710,7 @@ func writeDynamicCPPMethod(method ComponentDefinitionMethod, w LanguageWriter, N postCallCodeLines = append(postCallCodeLines, fmt.Sprintf("if (!h%s) {", param.ParamName)) postCallCodeLines = append(postCallCodeLines, fmt.Sprintf(" %s%s_ERROR_INVALIDPARAM%s;", checkErrorCodeBegin, strings.ToUpper(NameSpace), checkErrorCodeEnd)) postCallCodeLines = append(postCallCodeLines, fmt.Sprintf("} else {")) - postCallCodeLines = append(postCallCodeLines, fmt.Sprintf(" p%s = %s->polymorphicFactory<%s%s%s>(h%s);", param.ParamName, makeSharedParameter, cppClassPrefix, ClassIdentifier, param.ParamClass, param.ParamName)) + postCallCodeLines = append(postCallCodeLines, fmt.Sprintf(" p%s = std::shared_ptr<%s>(dynamic_cast<%s*>(%s->polymorphicFactory(h%s)));", param.ParamName, CPPClass, CPPClass, makeSharedParameter, param.ParamName)) postCallCodeLines = append(postCallCodeLines, fmt.Sprintf("}")) } @@ -779,7 +780,7 @@ func writeDynamicCPPMethod(method ComponentDefinitionMethod, w LanguageWriter, N if (param.ParamType == "optionalclass") { returnCodeLines = append(returnCodeLines, fmt.Sprintf("if (h%s) {", param.ParamName)) - returnCodeLines = append(returnCodeLines, fmt.Sprintf(" return %s->polymorphicFactory<%s>(h%s);", makeSharedParameter, CPPClass, param.ParamName)) + returnCodeLines = append(returnCodeLines, fmt.Sprintf(" return std::shared_ptr<%s>(dynamic_cast<%s*>(%s->polymorphicFactory(h%s)));", CPPClass, CPPClass, makeSharedParameter, param.ParamName)) returnCodeLines = append(returnCodeLines, fmt.Sprintf("} else {")) returnCodeLines = append(returnCodeLines, fmt.Sprintf(" return nullptr;")) returnCodeLines = append(returnCodeLines, fmt.Sprintf("}")) @@ -787,7 +788,7 @@ func writeDynamicCPPMethod(method ComponentDefinitionMethod, w LanguageWriter, N returnCodeLines = append(returnCodeLines, fmt.Sprintf("if (!h%s) {", param.ParamName)) returnCodeLines = append(returnCodeLines, fmt.Sprintf(" %s%s_ERROR_INVALIDPARAM%s;", checkErrorCodeBegin, strings.ToUpper(NameSpace), checkErrorCodeEnd)) returnCodeLines = append(returnCodeLines, fmt.Sprintf("}")) - returnCodeLines = append(returnCodeLines, fmt.Sprintf("return %s->polymorphicFactory<%s>(h%s);", makeSharedParameter, CPPClass, param.ParamName)) + returnCodeLines = append(returnCodeLines, fmt.Sprintf("return std::shared_ptr<%s>(dynamic_cast<%s*>(%s->polymorphicFactory(h%s)));", CPPClass, CPPClass, makeSharedParameter, param.ParamName)) } case "basicarray": @@ -1338,8 +1339,7 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s } } w.Writeln("") - w.Writeln(" template<class U>") - w.Writeln(" std::shared_ptr<U> polymorphicFactory(%sHandle);", NameSpace) + w.Writeln(" inline C%s* polymorphicFactory(%sHandle);", component.Global.BaseClassName, NameSpace) w.Writeln("") w.Writeln("private:") @@ -1454,8 +1454,7 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln("* %s%sWrapper::AcquireInstance(C%s object) must be called after instantiating new object.", cppClassPrefix, ClassIdentifier, component.Global.BaseClassName) w.Writeln("* This is important to keep reference count matching between application and library sides.") w.Writeln("*/") - w.Writeln("template <class T>") - w.Writeln("std::shared_ptr<T> %s%sWrapper::polymorphicFactory(%sHandle pHandle)", cppClassPrefix, ClassIdentifier, NameSpace) + w.Writeln("inline C%s* %s%sWrapper::polymorphicFactory(%sHandle pHandle)", component.Global.BaseClassName, cppClassPrefix, ClassIdentifier, NameSpace) w.Writeln("{") w.Writeln(" %s_uint64 resultClassTypeId = 0;", NameSpace) if ExplicitLinking { @@ -1467,11 +1466,11 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s for i := 0; i < len(component.Classes); i++ { class := component.Classes[i] classTypeId, chashHashString := class.classTypeId(NameSpace) - w.Writeln(" case 0x%016XUL: return std::dynamic_pointer_cast<T>(std::make_shared<C%s>(this, pHandle)); break; // First 64 bits of SHA1 of a string: \"%s\"", classTypeId, class.ClassName, chashHashString) + w.Writeln(" case 0x%016XUL: return new C%s(this, pHandle); break; // First 64 bits of SHA1 of a string: \"%s\"", classTypeId, class.ClassName, chashHashString) } w.Writeln(" }") - w.Writeln(" return std::make_shared<T>(this, pHandle);") + w.Writeln(" return new C%s(this, pHandle);", component.Global.BaseClassName) w.Writeln("}") for j := 0; j < len(global.Methods); j++ { From f08001395b6f04218947674fd99449906fc2e467 Mon Sep 17 00:00:00 2001 From: Andrii Anpilogov <andrii.anpilogov@autodesk.com> Date: Thu, 4 Nov 2021 23:40:32 -0700 Subject: [PATCH 116/143] Update examples with recent changes --- .../Bindings/Cpp/calculation_implicit.hpp | 20 ++-- .../CppDynamic/calculation_dynamic.hpp | 20 ++-- .../Bindings/CppDynamic/numbers_dynamic.hpp | 14 ++- .../Bindings/CDynamic/rtti_dynamic.cc | 20 ++++ .../Bindings/CDynamic/rtti_dynamic.h | 22 ++++ .../RTTI_component/Bindings/CSharp/RTTI.cs | 26 +++++ .../RTTI_component/Bindings/Cpp/rtti_abi.hpp | 20 ++++ .../Bindings/Cpp/rtti_implicit.hpp | 76 +++++++++---- .../Bindings/CppDynamic/rtti_dynamic.h | 22 ++++ .../Bindings/CppDynamic/rtti_dynamic.hpp | 102 ++++++++++++++---- .../RTTI/RTTI_component/Bindings/Go/rtti.go | 50 +++++++++ .../Bindings/Go/rtti_dynamic.cc | 20 ++++ .../RTTI_component/Bindings/Go/rtti_dynamic.h | 22 ++++ .../Bindings/Java9/rtti/AnimalIterator.java | 66 ++++++++++++ .../Bindings/Java9/rtti/RTTIWrapper.java | 6 ++ .../Bindings/Pascal/Unit_RTTI.pas | 62 +++++++++++ .../RTTI_component/Bindings/Python/RTTI.py | 42 ++++++++ .../Cpp/Interfaces/rtti_abi.hpp | 20 ++++ .../Cpp/Interfaces/rtti_interfaces.hpp | 14 +++ .../Cpp/Interfaces/rtti_interfacewrapper.cpp | 64 +++++++++++ .../Pascal/Interfaces/rtti_exports.pas | 102 ++++++++++++++++++ .../Pascal/Interfaces/rtti_interfaces.pas | 2 + .../Implementations/Pascal/rtti.def | 2 + 23 files changed, 747 insertions(+), 67 deletions(-) diff --git a/Examples/Injection/Calculation_component/Bindings/Cpp/calculation_implicit.hpp b/Examples/Injection/Calculation_component/Bindings/Cpp/calculation_implicit.hpp index 9d671fc1..16979853 100644 --- a/Examples/Injection/Calculation_component/Bindings/Cpp/calculation_implicit.hpp +++ b/Examples/Injection/Calculation_component/Bindings/Cpp/calculation_implicit.hpp @@ -246,8 +246,7 @@ class CWrapper { inline void InjectComponent(const std::string & sNameSpace, const Calculation_pvoid pSymbolAddressMethod); inline Calculation_pvoid GetSymbolLookupMethod(); - template<class U> - std::shared_ptr<U> polymorphicFactory(CalculationHandle); + inline CBase* polymorphicFactory(CalculationHandle); private: // Injected Components @@ -359,16 +358,15 @@ class CCalculator : public CBase { * CWrapper::AcquireInstance(CBase object) must be called after instantiating new object. * This is important to keep reference count matching between application and library sides. */ -template <class T> -std::shared_ptr<T> CWrapper::polymorphicFactory(CalculationHandle pHandle) +inline CBase* CWrapper::polymorphicFactory(CalculationHandle pHandle) { Calculation_uint64 resultClassTypeId = 0; CheckError(nullptr, calculation_base_classtypeid(pHandle, &resultClassTypeId)); switch(resultClassTypeId) { - case 0x3BA5271BAB410E5DUL: return std::dynamic_pointer_cast<T>(std::make_shared<CBase>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "Calculation::Base" - case 0xB23F514353D0C606UL: return std::dynamic_pointer_cast<T>(std::make_shared<CCalculator>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "Calculation::Calculator" + case 0x3BA5271BAB410E5DUL: return new CBase(this, pHandle); break; // First 64 bits of SHA1 of a string: "Calculation::Base" + case 0xB23F514353D0C606UL: return new CCalculator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Calculation::Calculator" } - return std::make_shared<T>(this, pHandle); + return new CBase(this, pHandle); } /** @@ -383,7 +381,7 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(CalculationHandle pHandle) if (!hInstance) { CheckError(nullptr,CALCULATION_ERROR_INVALIDPARAM); } - return this->polymorphicFactory<CCalculator>(hInstance); + return std::shared_ptr<CCalculator>(dynamic_cast<CCalculator*>(this->polymorphicFactory(hInstance))); } /** @@ -526,7 +524,7 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(CalculationHandle pHandle) if (!hVariable) { CheckError(CALCULATION_ERROR_INVALIDPARAM); } - return m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory<Numbers::CVariable>(hVariable); + return std::shared_ptr<Numbers::CVariable>(dynamic_cast<Numbers::CVariable*>(m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory(hVariable))); } /** @@ -549,7 +547,7 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(CalculationHandle pHandle) if (!hInstance) { CheckError(CALCULATION_ERROR_INVALIDPARAM); } - return m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory<Numbers::CVariable>(hInstance); + return std::shared_ptr<Numbers::CVariable>(dynamic_cast<Numbers::CVariable*>(m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory(hInstance))); } /** @@ -564,7 +562,7 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(CalculationHandle pHandle) if (!hInstance) { CheckError(CALCULATION_ERROR_INVALIDPARAM); } - return m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory<Numbers::CVariable>(hInstance); + return std::shared_ptr<Numbers::CVariable>(dynamic_cast<Numbers::CVariable*>(m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory(hInstance))); } } // namespace Calculation diff --git a/Examples/Injection/Calculation_component/Bindings/CppDynamic/calculation_dynamic.hpp b/Examples/Injection/Calculation_component/Bindings/CppDynamic/calculation_dynamic.hpp index a291acf1..2c3c0eb6 100644 --- a/Examples/Injection/Calculation_component/Bindings/CppDynamic/calculation_dynamic.hpp +++ b/Examples/Injection/Calculation_component/Bindings/CppDynamic/calculation_dynamic.hpp @@ -265,8 +265,7 @@ class CWrapper { inline void InjectComponent(const std::string & sNameSpace, const Calculation_pvoid pSymbolAddressMethod); inline Calculation_pvoid GetSymbolLookupMethod(); - template<class U> - std::shared_ptr<U> polymorphicFactory(CalculationHandle); + inline CBase* polymorphicFactory(CalculationHandle); private: sCalculationDynamicWrapperTable m_WrapperTable; @@ -383,16 +382,15 @@ class CCalculator : public CBase { * CWrapper::AcquireInstance(CBase object) must be called after instantiating new object. * This is important to keep reference count matching between application and library sides. */ -template <class T> -std::shared_ptr<T> CWrapper::polymorphicFactory(CalculationHandle pHandle) +inline CBase* CWrapper::polymorphicFactory(CalculationHandle pHandle) { Calculation_uint64 resultClassTypeId = 0; CheckError(nullptr, m_WrapperTable.m_Base_ClassTypeId(pHandle, &resultClassTypeId)); switch(resultClassTypeId) { - case 0x3BA5271BAB410E5DUL: return std::dynamic_pointer_cast<T>(std::make_shared<CBase>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "Calculation::Base" - case 0xB23F514353D0C606UL: return std::dynamic_pointer_cast<T>(std::make_shared<CCalculator>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "Calculation::Calculator" + case 0x3BA5271BAB410E5DUL: return new CBase(this, pHandle); break; // First 64 bits of SHA1 of a string: "Calculation::Base" + case 0xB23F514353D0C606UL: return new CCalculator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Calculation::Calculator" } - return std::make_shared<T>(this, pHandle); + return new CBase(this, pHandle); } /** @@ -407,7 +405,7 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(CalculationHandle pHandle) if (!hInstance) { CheckError(nullptr,CALCULATION_ERROR_INVALIDPARAM); } - return this->polymorphicFactory<CCalculator>(hInstance); + return std::shared_ptr<CCalculator>(dynamic_cast<CCalculator*>(this->polymorphicFactory(hInstance))); } /** @@ -806,7 +804,7 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(CalculationHandle pHandle) if (!hVariable) { CheckError(CALCULATION_ERROR_INVALIDPARAM); } - return m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory<Numbers::CVariable>(hVariable); + return std::shared_ptr<Numbers::CVariable>(dynamic_cast<Numbers::CVariable*>(m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory(hVariable))); } /** @@ -829,7 +827,7 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(CalculationHandle pHandle) if (!hInstance) { CheckError(CALCULATION_ERROR_INVALIDPARAM); } - return m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory<Numbers::CVariable>(hInstance); + return std::shared_ptr<Numbers::CVariable>(dynamic_cast<Numbers::CVariable*>(m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory(hInstance))); } /** @@ -844,7 +842,7 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(CalculationHandle pHandle) if (!hInstance) { CheckError(CALCULATION_ERROR_INVALIDPARAM); } - return m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory<Numbers::CVariable>(hInstance); + return std::shared_ptr<Numbers::CVariable>(dynamic_cast<Numbers::CVariable*>(m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory(hInstance))); } } // namespace Calculation diff --git a/Examples/Injection/Numbers_component/Bindings/CppDynamic/numbers_dynamic.hpp b/Examples/Injection/Numbers_component/Bindings/CppDynamic/numbers_dynamic.hpp index 991747ec..21a749ae 100644 --- a/Examples/Injection/Numbers_component/Bindings/CppDynamic/numbers_dynamic.hpp +++ b/Examples/Injection/Numbers_component/Bindings/CppDynamic/numbers_dynamic.hpp @@ -263,8 +263,7 @@ class CWrapper { inline void AcquireInstance(classParam<CBase> pInstance); inline Numbers_pvoid GetSymbolLookupMethod(); - template<class U> - std::shared_ptr<U> polymorphicFactory(NumbersHandle); + inline CBase* polymorphicFactory(NumbersHandle); private: sNumbersDynamicWrapperTable m_WrapperTable; @@ -375,16 +374,15 @@ class CVariable : public CBase { * CWrapper::AcquireInstance(CBase object) must be called after instantiating new object. * This is important to keep reference count matching between application and library sides. */ -template <class T> -std::shared_ptr<T> CWrapper::polymorphicFactory(NumbersHandle pHandle) +inline CBase* CWrapper::polymorphicFactory(NumbersHandle pHandle) { Numbers_uint64 resultClassTypeId = 0; CheckError(nullptr, m_WrapperTable.m_Base_ClassTypeId(pHandle, &resultClassTypeId)); switch(resultClassTypeId) { - case 0x27799F69B3FD1C9EUL: return std::dynamic_pointer_cast<T>(std::make_shared<CBase>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "Numbers::Base" - case 0x23934EDF762423EAUL: return std::dynamic_pointer_cast<T>(std::make_shared<CVariable>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "Numbers::Variable" + case 0x27799F69B3FD1C9EUL: return new CBase(this, pHandle); break; // First 64 bits of SHA1 of a string: "Numbers::Base" + case 0x23934EDF762423EAUL: return new CVariable(this, pHandle); break; // First 64 bits of SHA1 of a string: "Numbers::Variable" } - return std::make_shared<T>(this, pHandle); + return new CBase(this, pHandle); } /** @@ -400,7 +398,7 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(NumbersHandle pHandle) if (!hInstance) { CheckError(nullptr,NUMBERS_ERROR_INVALIDPARAM); } - return this->polymorphicFactory<CVariable>(hInstance); + return std::shared_ptr<CVariable>(dynamic_cast<CVariable*>(this->polymorphicFactory(hInstance))); } /** diff --git a/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.cc b/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.cc index 6cbe5c24..d8990f06 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.cc +++ b/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.cc @@ -32,6 +32,8 @@ RTTIResult InitRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable) pWrapperTable->m_Animal_Name = NULL; pWrapperTable->m_Tiger_Roar = NULL; pWrapperTable->m_AnimalIterator_GetNextAnimal = NULL; + pWrapperTable->m_AnimalIterator_GetNextOptinalAnimal = NULL; + pWrapperTable->m_AnimalIterator_GetNextMandatoryAnimal = NULL; pWrapperTable->m_Zoo_Iterator = NULL; pWrapperTable->m_GetVersion = NULL; pWrapperTable->m_GetLastError = NULL; @@ -128,6 +130,24 @@ RTTIResult LoadRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable, const if (pWrapperTable->m_AnimalIterator_GetNextAnimal == NULL) return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 + pWrapperTable->m_AnimalIterator_GetNextOptinalAnimal = (PRTTIAnimalIterator_GetNextOptinalAnimalPtr) GetProcAddress(hLibrary, "rtti_animaliterator_getnextoptinalanimal"); + #else // _WIN32 + pWrapperTable->m_AnimalIterator_GetNextOptinalAnimal = (PRTTIAnimalIterator_GetNextOptinalAnimalPtr) dlsym(hLibrary, "rtti_animaliterator_getnextoptinalanimal"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_AnimalIterator_GetNextOptinalAnimal == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_AnimalIterator_GetNextMandatoryAnimal = (PRTTIAnimalIterator_GetNextMandatoryAnimalPtr) GetProcAddress(hLibrary, "rtti_animaliterator_getnextmandatoryanimal"); + #else // _WIN32 + pWrapperTable->m_AnimalIterator_GetNextMandatoryAnimal = (PRTTIAnimalIterator_GetNextMandatoryAnimalPtr) dlsym(hLibrary, "rtti_animaliterator_getnextmandatoryanimal"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_AnimalIterator_GetNextMandatoryAnimal == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 pWrapperTable->m_Zoo_Iterator = (PRTTIZoo_IteratorPtr) GetProcAddress(hLibrary, "rtti_zoo_iterator"); #else // _WIN32 diff --git a/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.h b/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.h index 871f180d..3a33db2b 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.h +++ b/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.h @@ -93,6 +93,26 @@ typedef RTTIResult (*PRTTITiger_RoarPtr) (RTTI_Tiger pTiger); */ typedef RTTIResult (*PRTTIAnimalIterator_GetNextAnimalPtr) (RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal); +/** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @param[out] pError - +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIAnimalIterator_GetNextOptinalAnimalPtr) (RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal, bool * pError); + +/** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @param[out] pError - +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIAnimalIterator_GetNextMandatoryAnimalPtr) (RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal, bool * pError); + /************************************************************************************************************************* Class definition for Zoo **************************************************************************************************************************/ @@ -183,6 +203,8 @@ typedef struct { PRTTIAnimal_NamePtr m_Animal_Name; PRTTITiger_RoarPtr m_Tiger_Roar; PRTTIAnimalIterator_GetNextAnimalPtr m_AnimalIterator_GetNextAnimal; + PRTTIAnimalIterator_GetNextOptinalAnimalPtr m_AnimalIterator_GetNextOptinalAnimal; + PRTTIAnimalIterator_GetNextMandatoryAnimalPtr m_AnimalIterator_GetNextMandatoryAnimal; PRTTIZoo_IteratorPtr m_Zoo_Iterator; PRTTIGetVersionPtr m_GetVersion; PRTTIGetLastErrorPtr m_GetLastError; diff --git a/Examples/RTTI/RTTI_component/Bindings/CSharp/RTTI.cs b/Examples/RTTI/RTTI_component/Bindings/CSharp/RTTI.cs index 14dd0347..b963dd11 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CSharp/RTTI.cs +++ b/Examples/RTTI/RTTI_component/Bindings/CSharp/RTTI.cs @@ -22,6 +22,12 @@ public class RTTIWrapper [DllImport("rtti.dll", EntryPoint = "rtti_animaliterator_getnextanimal", CallingConvention=CallingConvention.Cdecl)] public unsafe extern static Int32 AnimalIterator_GetNextAnimal (IntPtr Handle, out IntPtr AAnimal); + [DllImport("rtti.dll", EntryPoint = "rtti_animaliterator_getnextoptinalanimal", CallingConvention=CallingConvention.Cdecl)] + public unsafe extern static Int32 AnimalIterator_GetNextOptinalAnimal (IntPtr Handle, out IntPtr AAnimal, out Byte AError); + + [DllImport("rtti.dll", EntryPoint = "rtti_animaliterator_getnextmandatoryanimal", CallingConvention=CallingConvention.Cdecl)] + public unsafe extern static Int32 AnimalIterator_GetNextMandatoryAnimal (IntPtr Handle, out IntPtr AAnimal, out Byte AError); + [DllImport("rtti.dll", EntryPoint = "rtti_zoo_iterator", CallingConvention=CallingConvention.Cdecl)] public unsafe extern static Int32 Zoo_Iterator (IntPtr Handle, out IntPtr AIterator); @@ -237,6 +243,26 @@ public CAnimal GetNextAnimal () return Internal.RTTIWrapper.PolymorphicFactory<CAnimal>(newAnimal); } + public bool GetNextOptinalAnimal (out CAnimal AAnimal) + { + IntPtr newAnimal = IntPtr.Zero; + Byte resultError = 0; + + CheckError(Internal.RTTIWrapper.AnimalIterator_GetNextOptinalAnimal (Handle, out newAnimal, out resultError)); + AAnimal = Internal.RTTIWrapper.PolymorphicFactory<CAnimal>(newAnimal); + return (resultError != 0); + } + + public bool GetNextMandatoryAnimal (out CAnimal AAnimal) + { + IntPtr newAnimal = IntPtr.Zero; + Byte resultError = 0; + + CheckError(Internal.RTTIWrapper.AnimalIterator_GetNextMandatoryAnimal (Handle, out newAnimal, out resultError)); + AAnimal = Internal.RTTIWrapper.PolymorphicFactory<CAnimal>(newAnimal); + return (resultError != 0); + } + } public class CZoo : CBase diff --git a/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_abi.hpp b/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_abi.hpp index cffde6e3..8654ffee 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_abi.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_abi.hpp @@ -106,6 +106,26 @@ RTTI_DECLSPEC RTTIResult rtti_tiger_roar(RTTI_Tiger pTiger); */ RTTI_DECLSPEC RTTIResult rtti_animaliterator_getnextanimal(RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal); +/** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @param[out] pError - +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_animaliterator_getnextoptinalanimal(RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal, bool * pError); + +/** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @param[out] pError - +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_animaliterator_getnextmandatoryanimal(RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal, bool * pError); + /************************************************************************************************************************* Class definition for Zoo **************************************************************************************************************************/ diff --git a/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_implicit.hpp b/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_implicit.hpp index ccfb299b..8d89403d 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_implicit.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_implicit.hpp @@ -277,8 +277,7 @@ class CWrapper { inline RTTI_pvoid GetSymbolLookupMethod(); inline PZoo CreateZoo(); - template<class U> - std::shared_ptr<U> polymorphicFactory(RTTIHandle); + inline CBase* polymorphicFactory(RTTIHandle); private: @@ -492,6 +491,8 @@ class CAnimalIterator : public CBase { } inline PAnimal GetNextAnimal(); + inline bool GetNextOptinalAnimal(PAnimal & pAnimal); + inline bool GetNextMandatoryAnimal(PAnimal & pAnimal); }; /************************************************************************************************************************* @@ -522,24 +523,23 @@ class CZoo : public CBase { * CWrapper::AcquireInstance(CBase object) must be called after instantiating new object. * This is important to keep reference count matching between application and library sides. */ -template <class T> -std::shared_ptr<T> CWrapper::polymorphicFactory(RTTIHandle pHandle) +inline CBase* CWrapper::polymorphicFactory(RTTIHandle pHandle) { RTTI_uint64 resultClassTypeId = 0; CheckError(nullptr, rtti_base_classtypeid(pHandle, &resultClassTypeId)); switch(resultClassTypeId) { - case 0x1549AD28813DAE05UL: return std::dynamic_pointer_cast<T>(std::make_shared<CBase>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Base" - case 0x8B40467DA6D327AFUL: return std::dynamic_pointer_cast<T>(std::make_shared<CAnimal>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Animal" - case 0xBC9D5FA7750C1020UL: return std::dynamic_pointer_cast<T>(std::make_shared<CMammal>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Mammal" - case 0x6756AA8EA5802EC3UL: return std::dynamic_pointer_cast<T>(std::make_shared<CReptile>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Reptile" - case 0x9751971BD2C2D958UL: return std::dynamic_pointer_cast<T>(std::make_shared<CGiraffe>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Giraffe" - case 0x08D007E7B5F7BAF4UL: return std::dynamic_pointer_cast<T>(std::make_shared<CTiger>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Tiger" - case 0x5F6826EF909803B2UL: return std::dynamic_pointer_cast<T>(std::make_shared<CSnake>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Snake" - case 0x8E551B208A2E8321UL: return std::dynamic_pointer_cast<T>(std::make_shared<CTurtle>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Turtle" - case 0xF1917FE6BBE77831UL: return std::dynamic_pointer_cast<T>(std::make_shared<CAnimalIterator>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" - case 0x2262ABE80A5E7878UL: return std::dynamic_pointer_cast<T>(std::make_shared<CZoo>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Zoo" - } - return std::make_shared<T>(this, pHandle); + case 0x1549AD28813DAE05UL: return new CBase(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::Base" + case 0x8B40467DA6D327AFUL: return new CAnimal(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::Animal" + case 0xBC9D5FA7750C1020UL: return new CMammal(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::Mammal" + case 0x6756AA8EA5802EC3UL: return new CReptile(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::Reptile" + case 0x9751971BD2C2D958UL: return new CGiraffe(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::Giraffe" + case 0x08D007E7B5F7BAF4UL: return new CTiger(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::Tiger" + case 0x5F6826EF909803B2UL: return new CSnake(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::Snake" + case 0x8E551B208A2E8321UL: return new CTurtle(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::Turtle" + case 0xF1917FE6BBE77831UL: return new CAnimalIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" + case 0x2262ABE80A5E7878UL: return new CZoo(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::Zoo" + } + return new CBase(this, pHandle); } /** @@ -631,7 +631,7 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(RTTIHandle pHandle) if (!hInstance) { CheckError(nullptr,RTTI_ERROR_INVALIDPARAM); } - return this->polymorphicFactory<CZoo>(hInstance); + return std::shared_ptr<CZoo>(dynamic_cast<CZoo*>(this->polymorphicFactory(hInstance))); } inline void CWrapper::CheckError(CBase * pBaseClass, RTTIResult nResult) @@ -728,12 +728,50 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(RTTIHandle pHandle) CheckError(rtti_animaliterator_getnextanimal(m_pHandle, &hAnimal)); if (hAnimal) { - return m_pWrapper->polymorphicFactory<CAnimal>(hAnimal); + return std::shared_ptr<CAnimal>(dynamic_cast<CAnimal*>(m_pWrapper->polymorphicFactory(hAnimal))); } else { return nullptr; } } + /** + * CAnimalIterator::GetNextOptinalAnimal - Return next animal + * @param[out] pAnimal - + * @return + */ + bool CAnimalIterator::GetNextOptinalAnimal(PAnimal & pAnimal) + { + RTTIHandle hAnimal = nullptr; + bool resultError = 0; + CheckError(rtti_animaliterator_getnextoptinalanimal(m_pHandle, &hAnimal, &resultError)); + if (hAnimal) { + pAnimal = std::shared_ptr<CAnimal>(dynamic_cast<CAnimal*>(m_pWrapper->polymorphicFactory(hAnimal))); + } else { + pAnimal = nullptr; + } + + return resultError; + } + + /** + * CAnimalIterator::GetNextMandatoryAnimal - Return next animal + * @param[out] pAnimal - + * @return + */ + bool CAnimalIterator::GetNextMandatoryAnimal(PAnimal & pAnimal) + { + RTTIHandle hAnimal = nullptr; + bool resultError = 0; + CheckError(rtti_animaliterator_getnextmandatoryanimal(m_pHandle, &hAnimal, &resultError)); + if (hAnimal) { + pAnimal = std::shared_ptr<CAnimal>(dynamic_cast<CAnimal*>(m_pWrapper->polymorphicFactory(hAnimal))); + } else { + pAnimal = nullptr; + } + + return resultError; + } + /** * Method definitions for class CZoo */ @@ -750,7 +788,7 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(RTTIHandle pHandle) if (!hIterator) { CheckError(RTTI_ERROR_INVALIDPARAM); } - return m_pWrapper->polymorphicFactory<CAnimalIterator>(hIterator); + return std::shared_ptr<CAnimalIterator>(dynamic_cast<CAnimalIterator*>(m_pWrapper->polymorphicFactory(hIterator))); } } // namespace RTTI diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h index 0f672975..3a1feb7d 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h @@ -93,6 +93,26 @@ typedef RTTIResult (*PRTTITiger_RoarPtr) (RTTI_Tiger pTiger); */ typedef RTTIResult (*PRTTIAnimalIterator_GetNextAnimalPtr) (RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal); +/** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @param[out] pError - +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIAnimalIterator_GetNextOptinalAnimalPtr) (RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal, bool * pError); + +/** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @param[out] pError - +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIAnimalIterator_GetNextMandatoryAnimalPtr) (RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal, bool * pError); + /************************************************************************************************************************* Class definition for Zoo **************************************************************************************************************************/ @@ -183,6 +203,8 @@ typedef struct { PRTTIAnimal_NamePtr m_Animal_Name; PRTTITiger_RoarPtr m_Tiger_Roar; PRTTIAnimalIterator_GetNextAnimalPtr m_AnimalIterator_GetNextAnimal; + PRTTIAnimalIterator_GetNextOptinalAnimalPtr m_AnimalIterator_GetNextOptinalAnimal; + PRTTIAnimalIterator_GetNextMandatoryAnimalPtr m_AnimalIterator_GetNextMandatoryAnimal; PRTTIZoo_IteratorPtr m_Zoo_Iterator; PRTTIGetVersionPtr m_GetVersion; PRTTIGetLastErrorPtr m_GetLastError; diff --git a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp index 494b3a34..9def3475 100644 --- a/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp @@ -296,8 +296,7 @@ class CWrapper { inline RTTI_pvoid GetSymbolLookupMethod(); inline PZoo CreateZoo(); - template<class U> - std::shared_ptr<U> polymorphicFactory(RTTIHandle); + inline CBase* polymorphicFactory(RTTIHandle); private: sRTTIDynamicWrapperTable m_WrapperTable; @@ -516,6 +515,8 @@ class CAnimalIterator : public CBase { } inline PAnimal GetNextAnimal(); + inline bool GetNextOptinalAnimal(PAnimal & pAnimal); + inline bool GetNextMandatoryAnimal(PAnimal & pAnimal); }; /************************************************************************************************************************* @@ -546,24 +547,23 @@ class CZoo : public CBase { * CWrapper::AcquireInstance(CBase object) must be called after instantiating new object. * This is important to keep reference count matching between application and library sides. */ -template <class T> -std::shared_ptr<T> CWrapper::polymorphicFactory(RTTIHandle pHandle) +inline CBase* CWrapper::polymorphicFactory(RTTIHandle pHandle) { RTTI_uint64 resultClassTypeId = 0; CheckError(nullptr, m_WrapperTable.m_Base_ClassTypeId(pHandle, &resultClassTypeId)); switch(resultClassTypeId) { - case 0x1549AD28813DAE05UL: return std::dynamic_pointer_cast<T>(std::make_shared<CBase>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Base" - case 0x8B40467DA6D327AFUL: return std::dynamic_pointer_cast<T>(std::make_shared<CAnimal>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Animal" - case 0xBC9D5FA7750C1020UL: return std::dynamic_pointer_cast<T>(std::make_shared<CMammal>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Mammal" - case 0x6756AA8EA5802EC3UL: return std::dynamic_pointer_cast<T>(std::make_shared<CReptile>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Reptile" - case 0x9751971BD2C2D958UL: return std::dynamic_pointer_cast<T>(std::make_shared<CGiraffe>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Giraffe" - case 0x08D007E7B5F7BAF4UL: return std::dynamic_pointer_cast<T>(std::make_shared<CTiger>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Tiger" - case 0x5F6826EF909803B2UL: return std::dynamic_pointer_cast<T>(std::make_shared<CSnake>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Snake" - case 0x8E551B208A2E8321UL: return std::dynamic_pointer_cast<T>(std::make_shared<CTurtle>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Turtle" - case 0xF1917FE6BBE77831UL: return std::dynamic_pointer_cast<T>(std::make_shared<CAnimalIterator>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" - case 0x2262ABE80A5E7878UL: return std::dynamic_pointer_cast<T>(std::make_shared<CZoo>(this, pHandle)); break; // First 64 bits of SHA1 of a string: "RTTI::Zoo" + case 0x1549AD28813DAE05UL: return new CBase(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::Base" + case 0x8B40467DA6D327AFUL: return new CAnimal(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::Animal" + case 0xBC9D5FA7750C1020UL: return new CMammal(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::Mammal" + case 0x6756AA8EA5802EC3UL: return new CReptile(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::Reptile" + case 0x9751971BD2C2D958UL: return new CGiraffe(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::Giraffe" + case 0x08D007E7B5F7BAF4UL: return new CTiger(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::Tiger" + case 0x5F6826EF909803B2UL: return new CSnake(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::Snake" + case 0x8E551B208A2E8321UL: return new CTurtle(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::Turtle" + case 0xF1917FE6BBE77831UL: return new CAnimalIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" + case 0x2262ABE80A5E7878UL: return new CZoo(this, pHandle); break; // First 64 bits of SHA1 of a string: "RTTI::Zoo" } - return std::make_shared<T>(this, pHandle); + return new CBase(this, pHandle); } /** @@ -655,7 +655,7 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(RTTIHandle pHandle) if (!hInstance) { CheckError(nullptr,RTTI_ERROR_INVALIDPARAM); } - return this->polymorphicFactory<CZoo>(hInstance); + return std::shared_ptr<CZoo>(dynamic_cast<CZoo*>(this->polymorphicFactory(hInstance))); } inline void CWrapper::CheckError(CBase * pBaseClass, RTTIResult nResult) @@ -680,6 +680,8 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(RTTIHandle pHandle) pWrapperTable->m_Animal_Name = nullptr; pWrapperTable->m_Tiger_Roar = nullptr; pWrapperTable->m_AnimalIterator_GetNextAnimal = nullptr; + pWrapperTable->m_AnimalIterator_GetNextOptinalAnimal = nullptr; + pWrapperTable->m_AnimalIterator_GetNextMandatoryAnimal = nullptr; pWrapperTable->m_Zoo_Iterator = nullptr; pWrapperTable->m_GetVersion = nullptr; pWrapperTable->m_GetLastError = nullptr; @@ -772,6 +774,24 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(RTTIHandle pHandle) if (pWrapperTable->m_AnimalIterator_GetNextAnimal == nullptr) return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 + pWrapperTable->m_AnimalIterator_GetNextOptinalAnimal = (PRTTIAnimalIterator_GetNextOptinalAnimalPtr) GetProcAddress(hLibrary, "rtti_animaliterator_getnextoptinalanimal"); + #else // _WIN32 + pWrapperTable->m_AnimalIterator_GetNextOptinalAnimal = (PRTTIAnimalIterator_GetNextOptinalAnimalPtr) dlsym(hLibrary, "rtti_animaliterator_getnextoptinalanimal"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_AnimalIterator_GetNextOptinalAnimal == nullptr) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_AnimalIterator_GetNextMandatoryAnimal = (PRTTIAnimalIterator_GetNextMandatoryAnimalPtr) GetProcAddress(hLibrary, "rtti_animaliterator_getnextmandatoryanimal"); + #else // _WIN32 + pWrapperTable->m_AnimalIterator_GetNextMandatoryAnimal = (PRTTIAnimalIterator_GetNextMandatoryAnimalPtr) dlsym(hLibrary, "rtti_animaliterator_getnextmandatoryanimal"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_AnimalIterator_GetNextMandatoryAnimal == nullptr) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 pWrapperTable->m_Zoo_Iterator = (PRTTIZoo_IteratorPtr) GetProcAddress(hLibrary, "rtti_zoo_iterator"); #else // _WIN32 @@ -876,6 +896,14 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(RTTIHandle pHandle) if ( (eLookupError != 0) || (pWrapperTable->m_AnimalIterator_GetNextAnimal == nullptr) ) return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + eLookupError = (*pLookup)("rtti_animaliterator_getnextoptinalanimal", (void**)&(pWrapperTable->m_AnimalIterator_GetNextOptinalAnimal)); + if ( (eLookupError != 0) || (pWrapperTable->m_AnimalIterator_GetNextOptinalAnimal == nullptr) ) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + eLookupError = (*pLookup)("rtti_animaliterator_getnextmandatoryanimal", (void**)&(pWrapperTable->m_AnimalIterator_GetNextMandatoryAnimal)); + if ( (eLookupError != 0) || (pWrapperTable->m_AnimalIterator_GetNextMandatoryAnimal == nullptr) ) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + eLookupError = (*pLookup)("rtti_zoo_iterator", (void**)&(pWrapperTable->m_Zoo_Iterator)); if ( (eLookupError != 0) || (pWrapperTable->m_Zoo_Iterator == nullptr) ) return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; @@ -994,12 +1022,50 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(RTTIHandle pHandle) CheckError(m_pWrapper->m_WrapperTable.m_AnimalIterator_GetNextAnimal(m_pHandle, &hAnimal)); if (hAnimal) { - return m_pWrapper->polymorphicFactory<CAnimal>(hAnimal); + return std::shared_ptr<CAnimal>(dynamic_cast<CAnimal*>(m_pWrapper->polymorphicFactory(hAnimal))); } else { return nullptr; } } + /** + * CAnimalIterator::GetNextOptinalAnimal - Return next animal + * @param[out] pAnimal - + * @return + */ + bool CAnimalIterator::GetNextOptinalAnimal(PAnimal & pAnimal) + { + RTTIHandle hAnimal = nullptr; + bool resultError = 0; + CheckError(m_pWrapper->m_WrapperTable.m_AnimalIterator_GetNextOptinalAnimal(m_pHandle, &hAnimal, &resultError)); + if (hAnimal) { + pAnimal = std::shared_ptr<CAnimal>(dynamic_cast<CAnimal*>(m_pWrapper->polymorphicFactory(hAnimal))); + } else { + pAnimal = nullptr; + } + + return resultError; + } + + /** + * CAnimalIterator::GetNextMandatoryAnimal - Return next animal + * @param[out] pAnimal - + * @return + */ + bool CAnimalIterator::GetNextMandatoryAnimal(PAnimal & pAnimal) + { + RTTIHandle hAnimal = nullptr; + bool resultError = 0; + CheckError(m_pWrapper->m_WrapperTable.m_AnimalIterator_GetNextMandatoryAnimal(m_pHandle, &hAnimal, &resultError)); + if (hAnimal) { + pAnimal = std::shared_ptr<CAnimal>(dynamic_cast<CAnimal*>(m_pWrapper->polymorphicFactory(hAnimal))); + } else { + pAnimal = nullptr; + } + + return resultError; + } + /** * Method definitions for class CZoo */ @@ -1016,7 +1082,7 @@ std::shared_ptr<T> CWrapper::polymorphicFactory(RTTIHandle pHandle) if (!hIterator) { CheckError(RTTI_ERROR_INVALIDPARAM); } - return m_pWrapper->polymorphicFactory<CAnimalIterator>(hIterator); + return std::shared_ptr<CAnimalIterator>(dynamic_cast<CAnimalIterator*>(m_pWrapper->polymorphicFactory(hIterator))); } } // namespace RTTI diff --git a/Examples/RTTI/RTTI_component/Bindings/Go/rtti.go b/Examples/RTTI/RTTI_component/Bindings/Go/rtti.go index fa11f32b..66502bde 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Go/rtti.go +++ b/Examples/RTTI/RTTI_component/Bindings/Go/rtti.go @@ -88,6 +88,24 @@ RTTIResult CCall_rtti_animaliterator_getnextanimal(RTTIHandle libraryHandle, RTT } +RTTIResult CCall_rtti_animaliterator_getnextoptinalanimal(RTTIHandle libraryHandle, RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal, bool * pError) +{ + if (libraryHandle == 0) + return RTTI_ERROR_INVALIDCAST; + sRTTIDynamicWrapperTable * wrapperTable = (sRTTIDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_AnimalIterator_GetNextOptinalAnimal (pAnimalIterator, pAnimal, pError); +} + + +RTTIResult CCall_rtti_animaliterator_getnextmandatoryanimal(RTTIHandle libraryHandle, RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal, bool * pError) +{ + if (libraryHandle == 0) + return RTTI_ERROR_INVALIDCAST; + sRTTIDynamicWrapperTable * wrapperTable = (sRTTIDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_AnimalIterator_GetNextMandatoryAnimal (pAnimalIterator, pAnimal, pError); +} + + RTTIResult CCall_rtti_zoo_iterator(RTTIHandle libraryHandle, RTTI_Zoo pZoo, RTTI_AnimalIterator * pIterator) { if (libraryHandle == 0) @@ -383,6 +401,38 @@ func (inst AnimalIterator) GetNextAnimal() (*Animal, error) { return _animalPtr, nil } +// GetNextOptinalAnimal return next animal. +func (inst AnimalIterator) GetNextOptinalAnimal() (*Animal, bool, error) { + var animal ref + var error C.bool + ret := C.CCall_rtti_animaliterator_getnextoptinalanimal(inst.wrapperRef.LibraryHandle, inst.Ref, &animal, &error) + if ret != 0 { + return nil, false, makeError(uint32(ret)) + } + var _animalPtr *Animal + if animal != nil { + _animalPtrVal := inst.wrapperRef.NewAnimal(animal) + _animalPtr = &_animalPtrVal + } + return _animalPtr, bool(error), nil +} + +// GetNextMandatoryAnimal return next animal. +func (inst AnimalIterator) GetNextMandatoryAnimal() (*Animal, bool, error) { + var animal ref + var error C.bool + ret := C.CCall_rtti_animaliterator_getnextmandatoryanimal(inst.wrapperRef.LibraryHandle, inst.Ref, &animal, &error) + if ret != 0 { + return nil, false, makeError(uint32(ret)) + } + var _animalPtr *Animal + if animal != nil { + _animalPtrVal := inst.wrapperRef.NewAnimal(animal) + _animalPtr = &_animalPtrVal + } + return _animalPtr, bool(error), nil +} + // Zoo represents a RTTI class. type Zoo struct { diff --git a/Examples/RTTI/RTTI_component/Bindings/Go/rtti_dynamic.cc b/Examples/RTTI/RTTI_component/Bindings/Go/rtti_dynamic.cc index 6cbe5c24..d8990f06 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Go/rtti_dynamic.cc +++ b/Examples/RTTI/RTTI_component/Bindings/Go/rtti_dynamic.cc @@ -32,6 +32,8 @@ RTTIResult InitRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable) pWrapperTable->m_Animal_Name = NULL; pWrapperTable->m_Tiger_Roar = NULL; pWrapperTable->m_AnimalIterator_GetNextAnimal = NULL; + pWrapperTable->m_AnimalIterator_GetNextOptinalAnimal = NULL; + pWrapperTable->m_AnimalIterator_GetNextMandatoryAnimal = NULL; pWrapperTable->m_Zoo_Iterator = NULL; pWrapperTable->m_GetVersion = NULL; pWrapperTable->m_GetLastError = NULL; @@ -128,6 +130,24 @@ RTTIResult LoadRTTIWrapperTable(sRTTIDynamicWrapperTable * pWrapperTable, const if (pWrapperTable->m_AnimalIterator_GetNextAnimal == NULL) return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 + pWrapperTable->m_AnimalIterator_GetNextOptinalAnimal = (PRTTIAnimalIterator_GetNextOptinalAnimalPtr) GetProcAddress(hLibrary, "rtti_animaliterator_getnextoptinalanimal"); + #else // _WIN32 + pWrapperTable->m_AnimalIterator_GetNextOptinalAnimal = (PRTTIAnimalIterator_GetNextOptinalAnimalPtr) dlsym(hLibrary, "rtti_animaliterator_getnextoptinalanimal"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_AnimalIterator_GetNextOptinalAnimal == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + + #ifdef _WIN32 + pWrapperTable->m_AnimalIterator_GetNextMandatoryAnimal = (PRTTIAnimalIterator_GetNextMandatoryAnimalPtr) GetProcAddress(hLibrary, "rtti_animaliterator_getnextmandatoryanimal"); + #else // _WIN32 + pWrapperTable->m_AnimalIterator_GetNextMandatoryAnimal = (PRTTIAnimalIterator_GetNextMandatoryAnimalPtr) dlsym(hLibrary, "rtti_animaliterator_getnextmandatoryanimal"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_AnimalIterator_GetNextMandatoryAnimal == NULL) + return RTTI_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 pWrapperTable->m_Zoo_Iterator = (PRTTIZoo_IteratorPtr) GetProcAddress(hLibrary, "rtti_zoo_iterator"); #else // _WIN32 diff --git a/Examples/RTTI/RTTI_component/Bindings/Go/rtti_dynamic.h b/Examples/RTTI/RTTI_component/Bindings/Go/rtti_dynamic.h index 871f180d..3a33db2b 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Go/rtti_dynamic.h +++ b/Examples/RTTI/RTTI_component/Bindings/Go/rtti_dynamic.h @@ -93,6 +93,26 @@ typedef RTTIResult (*PRTTITiger_RoarPtr) (RTTI_Tiger pTiger); */ typedef RTTIResult (*PRTTIAnimalIterator_GetNextAnimalPtr) (RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal); +/** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @param[out] pError - +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIAnimalIterator_GetNextOptinalAnimalPtr) (RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal, bool * pError); + +/** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @param[out] pError - +* @return error code or 0 (success) +*/ +typedef RTTIResult (*PRTTIAnimalIterator_GetNextMandatoryAnimalPtr) (RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal, bool * pError); + /************************************************************************************************************************* Class definition for Zoo **************************************************************************************************************************/ @@ -183,6 +203,8 @@ typedef struct { PRTTIAnimal_NamePtr m_Animal_Name; PRTTITiger_RoarPtr m_Tiger_Roar; PRTTIAnimalIterator_GetNextAnimalPtr m_AnimalIterator_GetNextAnimal; + PRTTIAnimalIterator_GetNextOptinalAnimalPtr m_AnimalIterator_GetNextOptinalAnimal; + PRTTIAnimalIterator_GetNextMandatoryAnimalPtr m_AnimalIterator_GetNextMandatoryAnimal; PRTTIZoo_IteratorPtr m_Zoo_Iterator; PRTTIGetVersionPtr m_GetVersion; PRTTIGetLastErrorPtr m_GetLastError; diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/AnimalIterator.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/AnimalIterator.java index fd84ed29..fb16a6f0 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/AnimalIterator.java +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/AnimalIterator.java @@ -49,6 +49,72 @@ public Animal getNextAnimal() throws RTTIException { return animal; } + /** + * Return next animal + * + * @return GetNextOptinalAnimal Result Tuple + * @throws RTTIException + */ + public GetNextOptinalAnimalResult getNextOptinalAnimal() throws RTTIException { + Pointer bufferAnimal = new Memory(8); + Pointer bufferError = new Memory(1); + mWrapper.checkError(this, mWrapper.rtti_animaliterator_getnextoptinalanimal.invokeInt(new java.lang.Object[]{mHandle, bufferAnimal, bufferError})); + Pointer valueAnimal = bufferAnimal.getPointer(0); + Animal animal = null; + if (valueAnimal != Pointer.NULL) { + animal = mWrapper.PolymorphicFactory(valueAnimal, Animal.class); + } + GetNextOptinalAnimalResult returnTuple = new GetNextOptinalAnimalResult(); + returnTuple.Animal = animal; + returnTuple.Error = bufferError.getByte(0) != 0; + return returnTuple; + } + + public static class GetNextOptinalAnimalResult { + /** + * + */ + public Animal Animal; + + /** + * + */ + public boolean Error; + + } + /** + * Return next animal + * + * @return GetNextMandatoryAnimal Result Tuple + * @throws RTTIException + */ + public GetNextMandatoryAnimalResult getNextMandatoryAnimal() throws RTTIException { + Pointer bufferAnimal = new Memory(8); + Pointer bufferError = new Memory(1); + mWrapper.checkError(this, mWrapper.rtti_animaliterator_getnextmandatoryanimal.invokeInt(new java.lang.Object[]{mHandle, bufferAnimal, bufferError})); + Pointer valueAnimal = bufferAnimal.getPointer(0); + Animal animal = null; + if (valueAnimal != Pointer.NULL) { + animal = mWrapper.PolymorphicFactory(valueAnimal, Animal.class); + } + GetNextMandatoryAnimalResult returnTuple = new GetNextMandatoryAnimalResult(); + returnTuple.Animal = animal; + returnTuple.Error = bufferError.getByte(0) != 0; + return returnTuple; + } + + public static class GetNextMandatoryAnimalResult { + /** + * + */ + public Animal Animal; + + /** + * + */ + public boolean Error; + + } } diff --git a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIWrapper.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIWrapper.java index 89ef6916..eb9c0413 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIWrapper.java +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIWrapper.java @@ -36,6 +36,8 @@ public static class EnumConversion { protected Function rtti_animal_name; protected Function rtti_tiger_roar; protected Function rtti_animaliterator_getnextanimal; + protected Function rtti_animaliterator_getnextoptinalanimal; + protected Function rtti_animaliterator_getnextmandatoryanimal; protected Function rtti_zoo_iterator; protected NativeLibrary mLibrary; @@ -53,6 +55,8 @@ public RTTIWrapper(String libraryPath) { rtti_animal_name = mLibrary.getFunction("rtti_animal_name"); rtti_tiger_roar = mLibrary.getFunction("rtti_tiger_roar"); rtti_animaliterator_getnextanimal = mLibrary.getFunction("rtti_animaliterator_getnextanimal"); + rtti_animaliterator_getnextoptinalanimal = mLibrary.getFunction("rtti_animaliterator_getnextoptinalanimal"); + rtti_animaliterator_getnextmandatoryanimal = mLibrary.getFunction("rtti_animaliterator_getnextmandatoryanimal"); rtti_zoo_iterator = mLibrary.getFunction("rtti_zoo_iterator"); } @@ -69,6 +73,8 @@ public RTTIWrapper(Pointer lookupPointer) throws RTTIException { rtti_animal_name = loadFunctionByLookup(lookupMethod, "rtti_animal_name"); rtti_tiger_roar = loadFunctionByLookup(lookupMethod, "rtti_tiger_roar"); rtti_animaliterator_getnextanimal = loadFunctionByLookup(lookupMethod, "rtti_animaliterator_getnextanimal"); + rtti_animaliterator_getnextoptinalanimal = loadFunctionByLookup(lookupMethod, "rtti_animaliterator_getnextoptinalanimal"); + rtti_animaliterator_getnextmandatoryanimal = loadFunctionByLookup(lookupMethod, "rtti_animaliterator_getnextmandatoryanimal"); rtti_zoo_iterator = loadFunctionByLookup(lookupMethod, "rtti_zoo_iterator"); } diff --git a/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas b/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas index 52b4c6be..8de38461 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas +++ b/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas @@ -166,6 +166,26 @@ TRTTIZoo = class; *) TRTTIAnimalIterator_GetNextAnimalFunc = function(pAnimalIterator: TRTTIHandle; out pAnimal: TRTTIHandle): TRTTIResult; cdecl; + (** + * Return next animal + * + * @param[in] pAnimalIterator - AnimalIterator instance. + * @param[out] pAnimal - + * @param[out] pError - + * @return error code or 0 (success) + *) + TRTTIAnimalIterator_GetNextOptinalAnimalFunc = function(pAnimalIterator: TRTTIHandle; out pAnimal: TRTTIHandle; out pError: Byte): TRTTIResult; cdecl; + + (** + * Return next animal + * + * @param[in] pAnimalIterator - AnimalIterator instance. + * @param[out] pAnimal - + * @param[out] pError - + * @return error code or 0 (success) + *) + TRTTIAnimalIterator_GetNextMandatoryAnimalFunc = function(pAnimalIterator: TRTTIHandle; out pAnimal: TRTTIHandle; out pError: Byte): TRTTIResult; cdecl; + (************************************************************************************************************************* Function type definitions for Zoo @@ -373,6 +393,8 @@ TRTTIAnimalIterator = class(TRTTIBase) constructor Create(AWrapper: TRTTIWrapper; AHandle: TRTTIHandle); destructor Destroy; override; function GetNextAnimal(): TRTTIAnimal; + function GetNextOptinalAnimal(out AAnimal: TRTTIAnimal): Boolean; + function GetNextMandatoryAnimal(out AAnimal: TRTTIAnimal): Boolean; end; @@ -398,6 +420,8 @@ TRTTIWrapper = class(TObject) FRTTIAnimal_NameFunc: TRTTIAnimal_NameFunc; FRTTITiger_RoarFunc: TRTTITiger_RoarFunc; FRTTIAnimalIterator_GetNextAnimalFunc: TRTTIAnimalIterator_GetNextAnimalFunc; + FRTTIAnimalIterator_GetNextOptinalAnimalFunc: TRTTIAnimalIterator_GetNextOptinalAnimalFunc; + FRTTIAnimalIterator_GetNextMandatoryAnimalFunc: TRTTIAnimalIterator_GetNextMandatoryAnimalFunc; FRTTIZoo_IteratorFunc: TRTTIZoo_IteratorFunc; FRTTIGetVersionFunc: TRTTIGetVersionFunc; FRTTIGetLastErrorFunc: TRTTIGetLastErrorFunc; @@ -420,6 +444,8 @@ TRTTIWrapper = class(TObject) property RTTIAnimal_NameFunc: TRTTIAnimal_NameFunc read FRTTIAnimal_NameFunc; property RTTITiger_RoarFunc: TRTTITiger_RoarFunc read FRTTITiger_RoarFunc; property RTTIAnimalIterator_GetNextAnimalFunc: TRTTIAnimalIterator_GetNextAnimalFunc read FRTTIAnimalIterator_GetNextAnimalFunc; + property RTTIAnimalIterator_GetNextOptinalAnimalFunc: TRTTIAnimalIterator_GetNextOptinalAnimalFunc read FRTTIAnimalIterator_GetNextOptinalAnimalFunc; + property RTTIAnimalIterator_GetNextMandatoryAnimalFunc: TRTTIAnimalIterator_GetNextMandatoryAnimalFunc read FRTTIAnimalIterator_GetNextMandatoryAnimalFunc; property RTTIZoo_IteratorFunc: TRTTIZoo_IteratorFunc read FRTTIZoo_IteratorFunc; property RTTIGetVersionFunc: TRTTIGetVersionFunc read FRTTIGetVersionFunc; property RTTIGetLastErrorFunc: TRTTIGetLastErrorFunc read FRTTIGetLastErrorFunc; @@ -733,6 +759,34 @@ implementation Result := TRTTIPolymorphicFactory<TRTTIAnimal, TRTTIAnimal>.Make(FWrapper, HAnimal); end; + function TRTTIAnimalIterator.GetNextOptinalAnimal(out AAnimal: TRTTIAnimal): Boolean; + var + HAnimal: TRTTIHandle; + ResultError: Byte; + begin + AAnimal := nil; + HAnimal := nil; + ResultError := 0; + FWrapper.CheckError(Self, FWrapper.RTTIAnimalIterator_GetNextOptinalAnimalFunc(FHandle, HAnimal, ResultError)); + if Assigned(HAnimal) then + AAnimal := TRTTIAnimal.Create(FWrapper, HAnimal); + Result := (ResultError <> 0); + end; + + function TRTTIAnimalIterator.GetNextMandatoryAnimal(out AAnimal: TRTTIAnimal): Boolean; + var + HAnimal: TRTTIHandle; + ResultError: Byte; + begin + AAnimal := nil; + HAnimal := nil; + ResultError := 0; + FWrapper.CheckError(Self, FWrapper.RTTIAnimalIterator_GetNextMandatoryAnimalFunc(FHandle, HAnimal, ResultError)); + if Assigned(HAnimal) then + AAnimal := TRTTIAnimal.Create(FWrapper, HAnimal); + Result := (ResultError <> 0); + end; + (************************************************************************************************************************* Class implementation for Zoo **************************************************************************************************************************) @@ -784,6 +838,8 @@ implementation FRTTIAnimal_NameFunc := LoadFunction('rtti_animal_name'); FRTTITiger_RoarFunc := LoadFunction('rtti_tiger_roar'); FRTTIAnimalIterator_GetNextAnimalFunc := LoadFunction('rtti_animaliterator_getnextanimal'); + FRTTIAnimalIterator_GetNextOptinalAnimalFunc := LoadFunction('rtti_animaliterator_getnextoptinalanimal'); + FRTTIAnimalIterator_GetNextMandatoryAnimalFunc := LoadFunction('rtti_animaliterator_getnextmandatoryanimal'); FRTTIZoo_IteratorFunc := LoadFunction('rtti_zoo_iterator'); FRTTIGetVersionFunc := LoadFunction('rtti_getversion'); FRTTIGetLastErrorFunc := LoadFunction('rtti_getlasterror'); @@ -813,6 +869,12 @@ implementation if AResult <> RTTI_SUCCESS then raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); AResult := ALookupMethod(PAnsiChar('rtti_animaliterator_getnextanimal'), @FRTTIAnimalIterator_GetNextAnimalFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_animaliterator_getnextoptinalanimal'), @FRTTIAnimalIterator_GetNextOptinalAnimalFunc); + if AResult <> RTTI_SUCCESS then + raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('rtti_animaliterator_getnextmandatoryanimal'), @FRTTIAnimalIterator_GetNextMandatoryAnimalFunc); if AResult <> RTTI_SUCCESS then raise ERTTIException.CreateCustomMessage(RTTI_ERROR_COULDNOTLOADLIBRARY, ''); AResult := ALookupMethod(PAnsiChar('rtti_zoo_iterator'), @FRTTIZoo_IteratorFunc); diff --git a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py index 6129b058..32983bf6 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py +++ b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py @@ -67,6 +67,8 @@ class FunctionTable: rtti_animal_name = None rtti_tiger_roar = None rtti_animaliterator_getnextanimal = None + rtti_animaliterator_getnextoptinalanimal = None + rtti_animaliterator_getnextmandatoryanimal = None rtti_zoo_iterator = None @@ -177,6 +179,18 @@ def _loadFunctionTableFromMethod(self, symbolLookupMethodAddress): methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p)) self.lib.rtti_animaliterator_getnextanimal = methodType(int(methodAddress.value)) + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_animaliterator_getnextoptinalanimal")), methodAddress) + if err != 0: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p), ctypes.POINTER(ctypes.c_bool)) + self.lib.rtti_animaliterator_getnextoptinalanimal = methodType(int(methodAddress.value)) + + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_animaliterator_getnextmandatoryanimal")), methodAddress) + if err != 0: + raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p), ctypes.POINTER(ctypes.c_bool)) + self.lib.rtti_animaliterator_getnextmandatoryanimal = methodType(int(methodAddress.value)) + err = symbolLookupMethod(ctypes.c_char_p(str.encode("rtti_zoo_iterator")), methodAddress) if err != 0: raise ERTTIException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) @@ -221,6 +235,12 @@ def _loadFunctionTable(self): self.lib.rtti_animaliterator_getnextanimal.restype = ctypes.c_int32 self.lib.rtti_animaliterator_getnextanimal.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p)] + self.lib.rtti_animaliterator_getnextoptinalanimal.restype = ctypes.c_int32 + self.lib.rtti_animaliterator_getnextoptinalanimal.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p), ctypes.POINTER(ctypes.c_bool)] + + self.lib.rtti_animaliterator_getnextmandatoryanimal.restype = ctypes.c_int32 + self.lib.rtti_animaliterator_getnextmandatoryanimal.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p), ctypes.POINTER(ctypes.c_bool)] + self.lib.rtti_zoo_iterator.restype = ctypes.c_int32 self.lib.rtti_zoo_iterator.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p)] @@ -449,6 +469,28 @@ def GetNextAnimal(self): return AnimalObject + def GetNextOptinalAnimal(self): + AnimalHandle = ctypes.c_void_p() + pError = ctypes.c_bool() + self._wrapper.checkError(self, self._wrapper.lib.rtti_animaliterator_getnextoptinalanimal(self._handle, AnimalHandle, pError)) + if AnimalHandle: + AnimalObject = self._wrapper._polymorphicFactory(AnimalHandle) + else: + AnimalObject = None + + return AnimalObject, pError.value + + def GetNextMandatoryAnimal(self): + AnimalHandle = ctypes.c_void_p() + pError = ctypes.c_bool() + self._wrapper.checkError(self, self._wrapper.lib.rtti_animaliterator_getnextmandatoryanimal(self._handle, AnimalHandle, pError)) + if AnimalHandle: + AnimalObject = self._wrapper._polymorphicFactory(AnimalHandle) + else: + AnimalObject = None + + return AnimalObject, pError.value + ''' Class Implementation for Zoo diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp index cffde6e3..8654ffee 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp @@ -106,6 +106,26 @@ RTTI_DECLSPEC RTTIResult rtti_tiger_roar(RTTI_Tiger pTiger); */ RTTI_DECLSPEC RTTIResult rtti_animaliterator_getnextanimal(RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal); +/** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @param[out] pError - +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_animaliterator_getnextoptinalanimal(RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal, bool * pError); + +/** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @param[out] pError - +* @return error code or 0 (success) +*/ +RTTI_DECLSPEC RTTIResult rtti_animaliterator_getnextmandatoryanimal(RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal, bool * pError); + /************************************************************************************************************************* Class definition for Zoo **************************************************************************************************************************/ diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp index a4abcb20..b0f1c576 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp @@ -398,6 +398,20 @@ class IAnimalIterator : public virtual IBase { */ virtual IAnimal * GetNextAnimal() = 0; + /** + * IAnimalIterator::GetNextOptinalAnimal - Return next animal + * @param[out] pAnimal - + * @return + */ + virtual bool GetNextOptinalAnimal(IAnimal*& pAnimal) = 0; + + /** + * IAnimalIterator::GetNextMandatoryAnimal - Return next animal + * @param[out] pAnimal - + * @return + */ + virtual bool GetNextMandatoryAnimal(IAnimal*& pAnimal) = 0; + }; typedef IBaseSharedPtr<IAnimalIterator> PIAnimalIterator; diff --git a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp index 9d7dbbad..c69c853d 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp @@ -214,6 +214,66 @@ RTTIResult rtti_animaliterator_getnextanimal(RTTI_AnimalIterator pAnimalIterator } } +RTTIResult rtti_animaliterator_getnextoptinalanimal(RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal, bool * pError) +{ + IBase* pIBaseClass = (IBase *)pAnimalIterator; + + try { + if (pAnimal == nullptr) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDPARAM); + if (pError == nullptr) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDPARAM); + IAnimal* pBaseAnimal(nullptr); + IAnimalIterator* pIAnimalIterator = dynamic_cast<IAnimalIterator*>(pIBaseClass); + if (!pIAnimalIterator) + throw ERTTIInterfaceException(RTTI_ERROR_INVALIDCAST); + + *pError = pIAnimalIterator->GetNextOptinalAnimal(pBaseAnimal); + + *pAnimal = (IBase*)(pBaseAnimal); + return RTTI_SUCCESS; + } + catch (ERTTIInterfaceException & Exception) { + return handleRTTIException(pIBaseClass, Exception); + } + catch (std::exception & StdException) { + return handleStdException(pIBaseClass, StdException); + } + catch (...) { + return handleUnhandledException(pIBaseClass); + } +} + +RTTIResult rtti_animaliterator_getnextmandatoryanimal(RTTI_AnimalIterator pAnimalIterator, RTTI_Animal * pAnimal, bool * pError) +{ + IBase* pIBaseClass = (IBase *)pAnimalIterator; + + try { + if (pAnimal == nullptr) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDPARAM); + if (pError == nullptr) + throw ERTTIInterfaceException (RTTI_ERROR_INVALIDPARAM); + IAnimal* pBaseAnimal(nullptr); + IAnimalIterator* pIAnimalIterator = dynamic_cast<IAnimalIterator*>(pIBaseClass); + if (!pIAnimalIterator) + throw ERTTIInterfaceException(RTTI_ERROR_INVALIDCAST); + + *pError = pIAnimalIterator->GetNextMandatoryAnimal(pBaseAnimal); + + *pAnimal = (IBase*)(pBaseAnimal); + return RTTI_SUCCESS; + } + catch (ERTTIInterfaceException & Exception) { + return handleRTTIException(pIBaseClass, Exception); + } + catch (std::exception & StdException) { + return handleStdException(pIBaseClass, StdException); + } + catch (...) { + return handleUnhandledException(pIBaseClass); + } +} + /************************************************************************************************************************* Class implementation for Zoo @@ -269,6 +329,10 @@ RTTIResult RTTI::Impl::RTTI_GetProcAddress (const char * pProcName, void ** ppPr *ppProcAddress = (void*) &rtti_tiger_roar; if (sProcName == "rtti_animaliterator_getnextanimal") *ppProcAddress = (void*) &rtti_animaliterator_getnextanimal; + if (sProcName == "rtti_animaliterator_getnextoptinalanimal") + *ppProcAddress = (void*) &rtti_animaliterator_getnextoptinalanimal; + if (sProcName == "rtti_animaliterator_getnextmandatoryanimal") + *ppProcAddress = (void*) &rtti_animaliterator_getnextmandatoryanimal; if (sProcName == "rtti_zoo_iterator") *ppProcAddress = (void*) &rtti_zoo_iterator; if (sProcName == "rtti_getversion") diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exports.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exports.pas index 01fe86c5..e8b361db 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exports.pas +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exports.pas @@ -99,6 +99,26 @@ function rtti_tiger_roar(pTiger: TRTTIHandle): TRTTIResult; cdecl; *) function rtti_animaliterator_getnextanimal(pAnimalIterator: TRTTIHandle; pAnimal: PRTTIHandle): TRTTIResult; cdecl; +(** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @param[out] pError - +* @return error code or 0 (success) +*) +function rtti_animaliterator_getnextoptinalanimal(pAnimalIterator: TRTTIHandle; pAnimal: PRTTIHandle; pError: PByte): TRTTIResult; cdecl; + +(** +* Return next animal +* +* @param[in] pAnimalIterator - AnimalIterator instance. +* @param[out] pAnimal - +* @param[out] pError - +* @return error code or 0 (success) +*) +function rtti_animaliterator_getnextmandatoryanimal(pAnimalIterator: TRTTIHandle; pAnimal: PRTTIHandle; pError: PByte): TRTTIResult; cdecl; + (************************************************************************************************************************* Class export definition of Zoo **************************************************************************************************************************) @@ -333,6 +353,84 @@ function rtti_animaliterator_getnextanimal(pAnimalIterator: TRTTIHandle; pAnimal end; end; +function rtti_animaliterator_getnextoptinalanimal(pAnimalIterator: TRTTIHandle; pAnimal: PRTTIHandle; pError: PByte): TRTTIResult; cdecl; +var + OutAnimal: TObject; + ResultError: Boolean; + ObjectAnimalIterator: TObject; + IntfAnimalIterator: IRTTIAnimalIterator; +begin + try + if not Assigned(pAnimal) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + if not Assigned(pError) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + if not Assigned(pAnimalIterator) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + + ObjectAnimalIterator := TObject(pAnimalIterator); + if Supports(ObjectAnimalIterator, IRTTIAnimalIterator) then begin + IntfAnimalIterator := ObjectAnimalIterator as IRTTIAnimalIterator; + ResultError := IntfAnimalIterator.GetNextOptinalAnimal(OutAnimal); + + pAnimal^ := OutAnimal; + pError^ := Ord(ResultError); + end else + raise ERTTIException.Create(RTTI_ERROR_INVALIDCAST); + + Result := RTTI_SUCCESS; + except + On E: ERTTIException do begin + Result := HandleRTTIException(ObjectAnimalIterator , E); + end; + On E: Exception do begin + Result := HandleStdException(ObjectAnimalIterator , E); + end + else begin + Result := HandleUnhandledException(ObjectAnimalIterator); + end; + end; +end; + +function rtti_animaliterator_getnextmandatoryanimal(pAnimalIterator: TRTTIHandle; pAnimal: PRTTIHandle; pError: PByte): TRTTIResult; cdecl; +var + OutAnimal: TObject; + ResultError: Boolean; + ObjectAnimalIterator: TObject; + IntfAnimalIterator: IRTTIAnimalIterator; +begin + try + if not Assigned(pAnimal) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + if not Assigned(pError) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + if not Assigned(pAnimalIterator) then + raise ERTTIException.Create(RTTI_ERROR_INVALIDPARAM); + + ObjectAnimalIterator := TObject(pAnimalIterator); + if Supports(ObjectAnimalIterator, IRTTIAnimalIterator) then begin + IntfAnimalIterator := ObjectAnimalIterator as IRTTIAnimalIterator; + ResultError := IntfAnimalIterator.GetNextMandatoryAnimal(OutAnimal); + + pAnimal^ := OutAnimal; + pError^ := Ord(ResultError); + end else + raise ERTTIException.Create(RTTI_ERROR_INVALIDCAST); + + Result := RTTI_SUCCESS; + except + On E: ERTTIException do begin + Result := HandleRTTIException(ObjectAnimalIterator , E); + end; + On E: Exception do begin + Result := HandleStdException(ObjectAnimalIterator , E); + end + else begin + Result := HandleUnhandledException(ObjectAnimalIterator); + end; + end; +end; + function rtti_zoo_iterator(pZoo: TRTTIHandle; pIterator: PRTTIHandle): TRTTIResult; cdecl; var ResultIterator: TObject; @@ -561,6 +659,10 @@ function _rtti_getprocaddress_internal(pProcName: PAnsiChar; out ppProcAddress: ppProcAddress := @rtti_tiger_roar else if (pProcName = 'rtti_animaliterator_getnextanimal') then ppProcAddress := @rtti_animaliterator_getnextanimal + else if (pProcName = 'rtti_animaliterator_getnextoptinalanimal') then + ppProcAddress := @rtti_animaliterator_getnextoptinalanimal + else if (pProcName = 'rtti_animaliterator_getnextmandatoryanimal') then + ppProcAddress := @rtti_animaliterator_getnextmandatoryanimal else if (pProcName = 'rtti_zoo_iterator') then ppProcAddress := @rtti_zoo_iterator else if (pProcName = 'rtti_getversion') then diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_interfaces.pas b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_interfaces.pas index cefb8f88..3d7f1492 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_interfaces.pas +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_interfaces.pas @@ -123,6 +123,8 @@ interface ['{6325253F-EC73-4DD7-A9E2-8BF921119C16}'] function GetNextAnimal(): TObject; + function GetNextOptinalAnimal(out AAnimal: TObject): Boolean; + function GetNextMandatoryAnimal(out AAnimal: TObject): Boolean; end; diff --git a/Examples/RTTI/RTTI_component/Implementations/Pascal/rtti.def b/Examples/RTTI/RTTI_component/Implementations/Pascal/rtti.def index 36fbb276..3af35a45 100644 --- a/Examples/RTTI/RTTI_component/Implementations/Pascal/rtti.def +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/rtti.def @@ -10,4 +10,6 @@ rtti_base_classtypeid rtti_animal_name rtti_tiger_roar rtti_animaliterator_getnextanimal +rtti_animaliterator_getnextoptinalanimal +rtti_animaliterator_getnextmandatoryanimal rtti_zoo_iterator From 96385f2e615b1d33e1c52c1ce2aaa8d0f4bc9e1a Mon Sep 17 00:00:00 2001 From: Martin Weismann <30837766+martinweismann@users.noreply.github.com> Date: Tue, 23 Aug 2022 12:10:04 +0200 Subject: [PATCH 117/143] Add entrypoint and modify dockerfile --- Build/Dockerfile | 46 +++++++++++++++++++++++++++++----------------- Build/build.sh | 7 ++++++- entrypoint.sh | 27 +++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 18 deletions(-) create mode 100644 entrypoint.sh diff --git a/Build/Dockerfile b/Build/Dockerfile index f1159ced..3bccd736 100644 --- a/Build/Dockerfile +++ b/Build/Dockerfile @@ -2,16 +2,20 @@ FROM centos:centos8 LABEL maintainer="Andrii Anpilogov (andrii.anpilogov@autodesk.com)" -ARG USER_ID -ARG GROUP_ID +# ARG USER_ID +# ARG GROUP_ID -RUN : "${USER_ID:?Build argument needs to be set and non-empty.}" \ - : "${GROUP_ID:?Build argument needs to be set and non-empty.}" +# RUN : "${USER_ID:?Build argument needs to be set and non-empty.}" \ +# : "${GROUP_ID:?Build argument needs to be set and non-empty.}" RUN [ -e /etc/yum.conf ] && sed -i '/tsflags=nodocs/d' /etc/yum.conf || true # RUN yum install -y icu +RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* +RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* +RUN yum update -y + RUN dnf -y install dnf-plugins-core RUN dnf -y install dnf-plugin-config-manager RUN dnf -y update @@ -31,6 +35,7 @@ RUN dnf -y install ninja-build # 3.0.4 should be used for validating compiler base compatibility. RUN (cd /opt && curl -O -L 'http://downloads.sourceforge.net/project/freepascal/Linux/3.0.4/fpc-3.0.4-1.x86_64.rpm' \ && rpm -i fpc-3.0.4-1.x86_64.rpm) + # Using 3.2.2 until PolymorphicFactory is reworked to not using generics that are not full functional in 3.0.4. # RUN (cd /opt && curl -O -L 'http://downloads.sourceforge.net/project/freepascal/Linux/3.2.2/fpc-3.2.2-1.x86_64.rpm' \ # && rpm -i fpc-3.2.2-1.x86_64.rpm) @@ -38,6 +43,7 @@ RUN (cd /opt && curl -O -L 'http://downloads.sourceforge.net/project/freepascal/ # Golang RUN (cd /opt && curl -O -L https://golang.org/dl/go1.17.2.linux-amd64.tar.gz \ && tar zxvf go1.17.2.linux-amd64.tar.gz) +ENV PATH="${PATH}:/opt/go/bin" # Java RUN dnf -y install \ @@ -65,20 +71,26 @@ RUN dnf -y install \ yum-utils \ && yum clean all -# Create user -RUN groupadd docker \ - && useradd -ms /bin/bash --uid $USER_ID -g docker -G wheel user \ - && printf "user:user" | chpasswd \ - && printf "user ALL= NOPASSWD: ALL\\n" >> /etc/sudoers +# # Create user +# RUN groupadd docker \ +# && useradd -ms /bin/bash --uid $USER_ID -g docker -G wheel user \ +# && printf "user:user" | chpasswd \ +# && printf "user ALL= NOPASSWD: ALL\\n" >> /etc/sudoers + +# # Initialize Toolkit +RUN echo "source /opt/rh/gcc-toolset-9/enable" >> /etc/bashrc +# RUN echo "source /opt/rh/gcc-toolset-9/enable" >> /home/user/.bash_profile +# RUN echo "export PATH=\$PATH:/opt/go/bin" >> /home/user/.bash_profile + +# VOLUME /data + +# # Run Container as nonroot +# USER user +# WORKDIR /data -# Initialize Toolkit -RUN echo "source /opt/rh/gcc-toolset-9/enable" >> /home/user/.bash_profile -RUN echo "export PATH=\$PATH:/opt/go/bin" >> /home/user/.bash_profile +# ENTRYPOINT [ "/bin/bash", "-l" ] -VOLUME /data +# COPY entrypoint.sh /entrypoint.sh -# Run Container as nonroot -USER user -WORKDIR /data +ENTRYPOINT ["./entrypoint.sh"] -ENTRYPOINT [ "/bin/bash", "-l" ] diff --git a/Build/build.sh b/Build/build.sh index 0add0e20..e4ba1ad4 100755 --- a/Build/build.sh +++ b/Build/build.sh @@ -9,7 +9,7 @@ startingpath="$(pwd)" basepath="$(cd "$(dirname "$0")" && pwd)" cd "$basepath/../Source" -Sources="actutils.go automaticcomponenttoolkit.go buildbindingccpp.go buildbindingcsharp.go buildbindinggo.go buildbindingnode.go buildbindingpascal.go buildbindingpython.go buildbindingjava.go buildimplementationcpp.go buildimplementationpascal.go componentdefinition.go componentdiff.go languagewriter.go languagec.go languagecpp.go languagepascal.go" +Sources="actutils.go automaticcomponenttoolkit.go buildbindingccpp.go buildbindingccppdocumentation.go buildbindingcsharp.go buildbindinggo.go buildbindingnode.go buildbindingpascal.go buildbindingpython.go buildbindingjava.go buildimplementationcpp.go buildimplementationpascal.go componentdefinition.go componentdiff.go languagewriter.go languagec.go languagecpp.go languagepascal.go" export GOARCH="amd64" echo "Build act.exe" @@ -24,6 +24,11 @@ echo "Build act.darwin" export GOOS="darwin" go build -o ../act.darwin $Sources || failed "Error compiling act.darwin" +echo "Build act.arm.darwin" +export GOOS="darwin" +export GOARCH="arm64" +go build -o ../act.arm.darwin $Sources || failed "Error compiling act.arm.darwin" + echo "Build act.arm.linux" || failed "Error compiling act.arm.linux" export GOOS="linux" export GOARCH="arm" diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 00000000..2c6fc7bf --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,27 @@ +#!/bin/sh -l + +echo "Action selected: $1" +time=$(date) +echo "::set-output name=time::$time" + +case "$1" in + act) + sh Build/build.sh + ;; + examples) + sh Examples/build.sh + ;; + all) + sh Build/build.sh + sh Examples/build.sh + ;; + *) + echo "Use one of available commands:" + echo " ./entrypoint.sh act - build ACT binaries" + echo " ./entrypoint.sh examples - build and run projects in Examples folder" + echo " ./entrypoint.sh all - build ACT binaries and then build and run projects in Examples folder" + exit 1 + ;; +esac + + From 88174247fad90ba48cb00f3d6748b48bda7986c8 Mon Sep 17 00:00:00 2001 From: Martin Weismann <30837766+martinweismann@users.noreply.github.com> Date: Tue, 23 Aug 2022 12:11:21 +0200 Subject: [PATCH 118/143] Add action and workflow --- .github/workflows/dockerbuild.yml | 21 +++++++++++++++++++++ action.yml | 16 ++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 .github/workflows/dockerbuild.yml create mode 100644 action.yml diff --git a/.github/workflows/dockerbuild.yml b/.github/workflows/dockerbuild.yml new file mode 100644 index 00000000..e266b5f8 --- /dev/null +++ b/.github/workflows/dockerbuild.yml @@ -0,0 +1,21 @@ +on: [push] + +jobs: + build_with_docker: + runs-on: ubuntu-latest + name: Build and test ACT inside Docker + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: build step + id: build_act + uses: martinweismann/AutomaticComponentToolkit@rtti-native-2 + with: + command: 'act' + - name: example step + id: build_and_test_examples + uses: martinweismann/AutomaticComponentToolkit@rtti-native-2 + with: + command: 'examples' + - name: Get the build time + run: echo "The build time was ${{ steps.build.outputs.time }}" \ No newline at end of file diff --git a/action.yml b/action.yml new file mode 100644 index 00000000..edaa2d28 --- /dev/null +++ b/action.yml @@ -0,0 +1,16 @@ +# docker.yml +name: 'BuildWithDocker' +description: 'Build ACT with in a Docker container' +inputs: + command: # id of input + description: 'What command to run' + required: true + default: 'act' +outputs: + time: # id of output + description: 'The time docker ran' +runs: + using: 'docker' + image: 'Build/Dockerfile' + args: + - ${{ inputs.command }} \ No newline at end of file From 12cb80b4f26eee6650ab6639848735d758bac029 Mon Sep 17 00:00:00 2001 From: Martin Weismann <30837766+martinweismann@users.noreply.github.com> Date: Tue, 23 Aug 2022 13:00:05 +0200 Subject: [PATCH 119/143] fix build.sh, make entrypoint executable --- Build/build.sh | 2 +- entrypoint.sh | 0 2 files changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 entrypoint.sh diff --git a/Build/build.sh b/Build/build.sh index e4ba1ad4..0a3ae636 100755 --- a/Build/build.sh +++ b/Build/build.sh @@ -9,7 +9,7 @@ startingpath="$(pwd)" basepath="$(cd "$(dirname "$0")" && pwd)" cd "$basepath/../Source" -Sources="actutils.go automaticcomponenttoolkit.go buildbindingccpp.go buildbindingccppdocumentation.go buildbindingcsharp.go buildbindinggo.go buildbindingnode.go buildbindingpascal.go buildbindingpython.go buildbindingjava.go buildimplementationcpp.go buildimplementationpascal.go componentdefinition.go componentdiff.go languagewriter.go languagec.go languagecpp.go languagepascal.go" +Sources="actutils.go automaticcomponenttoolkit.go buildbindingccpp.go buildbindingcsharp.go buildbindinggo.go buildbindingnode.go buildbindingpascal.go buildbindingpython.go buildbindingjava.go buildimplementationcpp.go buildimplementationpascal.go componentdefinition.go componentdiff.go languagewriter.go languagec.go languagecpp.go languagepascal.go" export GOARCH="amd64" echo "Build act.exe" diff --git a/entrypoint.sh b/entrypoint.sh old mode 100644 new mode 100755 From 59621c04bb1eadd6dafd008560d4129997a01cda Mon Sep 17 00:00:00 2001 From: Kevin Zhang <Ping.Zhang@autodesk.com> Date: Tue, 16 Nov 2021 10:10:36 +0800 Subject: [PATCH 120/143] Do null check for C# pointer to avoid crash. --- Source/buildbindingcsharp.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/buildbindingcsharp.go b/Source/buildbindingcsharp.go index 1f831452..81c5e84c 100644 --- a/Source/buildbindingcsharp.go +++ b/Source/buildbindingcsharp.go @@ -407,7 +407,10 @@ func writeCSharpClassMethodImplementation(method ComponentDefinitionMethod, w La if (ParamTypeName == "IntPtr") { callFunctionParameter = "A" + param.ParamName } else { - callFunctionParameter = "A" + param.ParamName + ".GetHandle()" + defineCommands = append(defineCommands, fmt.Sprintf(" IntPtr A%sHandle = IntPtr.Zero;", param.ParamName)) + defineCommands = append(defineCommands, fmt.Sprintf(" if (A%s != null)", param.ParamName)) + defineCommands = append(defineCommands, fmt.Sprintf(" A%sHandle = A%s.GetHandle();", param.ParamName, param.ParamName)) + callFunctionParameter = "A" + param.ParamName + "Handle" } initCallParameter = callFunctionParameter From f0ef90911cda0399ac22e8770ef8a8c9bde8b4f5 Mon Sep 17 00:00:00 2001 From: Kevin Zhang <Ping.Zhang@autodesk.com> Date: Wed, 10 Nov 2021 10:49:38 +0800 Subject: [PATCH 121/143] Add copyright for C# binding interface. --- Source/buildbindingcsharp.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/buildbindingcsharp.go b/Source/buildbindingcsharp.go index 81c5e84c..8c19d3b9 100644 --- a/Source/buildbindingcsharp.go +++ b/Source/buildbindingcsharp.go @@ -59,6 +59,9 @@ func BuildBindingCSharp(component ComponentDefinition, outputFolder string, outp return err } + CSharpImplFile.WriteCLicenseHeader(component, + fmt.Sprintf("This is an autogenerated CSharp file in order to allow an easy\n use of %s", libraryName), + true) err = buildBindingCSharpImplementation(component, CSharpImplFile, namespace, baseName) if len(outputFolderExample) > 0 { From 79fcb7b8cc278f290042897a22a4b2915c669896 Mon Sep 17 00:00:00 2001 From: Alexander Oster <alexanderoster@users.noreply.github.com> Date: Thu, 17 Feb 2022 11:51:20 +0100 Subject: [PATCH 122/143] Added new platforms --- Build/build.bat | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/Build/build.bat b/Build/build.bat index d6f69dc7..d642de3b 100644 --- a/Build/build.bat +++ b/Build/build.bat @@ -4,20 +4,35 @@ set basepath="%~dp0" cd %basepath%\..\Source set Sources=actutils.go automaticcomponenttoolkit.go buildbindingccpp.go buildbindingcsharp.go buildbindinggo.go buildbindingnode.go buildbindingpascal.go buildbindingpython.go buildimplementationcpp.go buildbindingjava.go buildimplementationpascal.go componentdefinition.go componentdiff.go languagewriter.go languagec.go languagecpp.go languagepascal.go -set GOARCH=amd64 set GOOS=windows +set GOARCH=amd64 echo "Build act.exe" go build -o ..\act.exe %Sources% echo "Patching properties of act.exe" ..\build\verpatch ..\act.exe /high /va 1.7.0 /pv "1.7.0-develop" /s copyright "(c) 2018-2019 ACT Developers" /s desc "ACT is a code generator for software components" /s productName "Automatic Component Toolkit" +set GOOS=windows +set GOARCH=386 +echo "Build act_win32.exe" +go build -o ..\act_win32.exe %Sources% + +echo "Patching properties of act_win32.exe" +..\build\verpatch ..\act_win32.exe /high /va 1.7.0 /pv "1.7.0-develop" /s copyright "(c) 2018-2019 ACT Developers" /s desc "ACT is a code generator for software components" /s productName "Automatic Component Toolkit" + set GOOS=linux +set GOARCH=amd64 echo "Build act.linux" go build -o ..\act.linux %Sources% +set GOOS=linux +set GOARCH=386 +echo "Build act.linux32" +go build -o ..\act.linux32 %Sources% + set GOOS=darwin +set GOARCH=amd64 echo "Build act.darwin" go build -o ..\act.darwin %Sources% @@ -27,4 +42,10 @@ set GOARM=5 echo "Build act.arm.linux" go build -o ..\act.arm.linux %Sources% +set GOOS=linux +set GOARCH=arm64 +set GOARM=5 +echo "Build act.arm64" +go build -o ..\act.arm64 %Sources% + cd %startingDir% From 8b08f7ca48e2ea61c0248f11c49c114bdc907f5f Mon Sep 17 00:00:00 2001 From: Alexander Oster <alexanderoster@users.noreply.github.com> Date: Thu, 17 Feb 2022 11:54:18 +0100 Subject: [PATCH 123/143] Added new platforms --- Build/build.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Build/build.bat b/Build/build.bat index d642de3b..b7038552 100644 --- a/Build/build.bat +++ b/Build/build.bat @@ -45,7 +45,7 @@ go build -o ..\act.arm.linux %Sources% set GOOS=linux set GOARCH=arm64 set GOARM=5 -echo "Build act.arm64" -go build -o ..\act.arm64 %Sources% +echo "Build act.arm.linux64" +go build -o ..\act.arm.linux64 %Sources% cd %startingDir% From 2a69d7fbeb8c7c1e38fc9c7381a35496ec62a4a3 Mon Sep 17 00:00:00 2001 From: Alexander Oster <alexanderoster@users.noreply.github.com> Date: Thu, 17 Feb 2022 17:05:24 +0100 Subject: [PATCH 124/143] Added disabling of stringout caching --- .gitignore | 2 ++ Build/build.bat | 26 ++++++++++++++------------ Source/buildimplementationcpp.go | 11 ++++++++--- Source/componentdefinition.go | 1 + 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index b9ebb9c2..f9b9a402 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ *.exe *.linux +*.linux32 +*.linux64 *.darwin *.exe *.dylib diff --git a/Build/build.bat b/Build/build.bat index b7038552..06443259 100644 --- a/Build/build.bat +++ b/Build/build.bat @@ -8,23 +8,23 @@ set Sources=actutils.go automaticcomponenttoolkit.go buildbindingccpp.go buildbi set GOOS=windows set GOARCH=amd64 echo "Build act.exe" -go build -o ..\act.exe %Sources% +go build -o ..\act.win64.exe %Sources% -echo "Patching properties of act.exe" -..\build\verpatch ..\act.exe /high /va 1.7.0 /pv "1.7.0-develop" /s copyright "(c) 2018-2019 ACT Developers" /s desc "ACT is a code generator for software components" /s productName "Automatic Component Toolkit" +echo "Patching properties of act.win64.exe" +..\build\verpatch ..\act.win64.exe /high /va 1.7.0 /pv "1.7.0-develop" /s copyright "(c) 2018-2019 ACT Developers" /s desc "ACT is a code generator for software components" /s productName "Automatic Component Toolkit" set GOOS=windows set GOARCH=386 -echo "Build act_win32.exe" -go build -o ..\act_win32.exe %Sources% +echo "Build act.win32.exe" +go build -o ..\act.win32.exe %Sources% echo "Patching properties of act_win32.exe" -..\build\verpatch ..\act_win32.exe /high /va 1.7.0 /pv "1.7.0-develop" /s copyright "(c) 2018-2019 ACT Developers" /s desc "ACT is a code generator for software components" /s productName "Automatic Component Toolkit" +..\build\verpatch ..\act.win32.exe /high /va 1.7.0 /pv "1.7.0-develop" /s copyright "(c) 2018-2019 ACT Developers" /s desc "ACT is a code generator for software components" /s productName "Automatic Component Toolkit" set GOOS=linux set GOARCH=amd64 -echo "Build act.linux" -go build -o ..\act.linux %Sources% +echo "Build act.linux64" +go build -o ..\act.linux64 %Sources% set GOOS=linux set GOARCH=386 @@ -39,13 +39,15 @@ go build -o ..\act.darwin %Sources% set GOOS=linux set GOARCH=arm set GOARM=5 -echo "Build act.arm.linux" -go build -o ..\act.arm.linux %Sources% +echo "Build act.linux32.arm" +go build -o ..\act.linux32.arm %Sources% set GOOS=linux set GOARCH=arm64 set GOARM=5 -echo "Build act.arm.linux64" -go build -o ..\act.arm.linux64 %Sources% +echo "Build act.linux64.arm" +go build -o ..\act.linux64.arm %Sources% + +copy ..\act.win64.exe ..\act.exe /Y cd %startingDir% diff --git a/Source/buildimplementationcpp.go b/Source/buildimplementationcpp.go index 35b743a7..e47ae9b8 100644 --- a/Source/buildimplementationcpp.go +++ b/Source/buildimplementationcpp.go @@ -992,15 +992,20 @@ func writeCImplementationMethod(component ComponentDefinition, method ComponentD outParameterCount := method.countOutParameters (); - bHasCacheCall := (len (stringOutParameters) > 0) && (isSpecialFunction != eSpecialMethodError); // GetLastError is an exception for string outs in global functions! + // Special functions are an exception for string outs in global functions! + bHasCacheCall := (len (stringOutParameters) > 0) && (isSpecialFunction != eSpecialMethodError) && (isSpecialFunction != eSpecialMethodBuildinfo) && (isSpecialFunction != eSpecialMethodPrerelease); + if (isGlobal && method.DisableStringOutCache) { + bHasCacheCall = false; + } + if (bHasCacheCall) { if (isGlobal) { - return errors.New ("String out parameter not allowed in global functions."); + return errors.New ("String out parameter not allowed in global functions: " + method.MethodName); } if (!isStringOutClass) { - return errors.New ("String out parameter without being the string out base class."); + return errors.New ("String out parameter without being the string out base class: " + method.MethodName) } templateParameters, err := buildOutCacheTemplateParameters (method, NameSpace, BaseClassName, ClassIdentifier); diff --git a/Source/componentdefinition.go b/Source/componentdefinition.go index bf1e9c75..f14dff7a 100644 --- a/Source/componentdefinition.go +++ b/Source/componentdefinition.go @@ -79,6 +79,7 @@ type ComponentDefinitionMethod struct { XMLName xml.Name `xml:"method"` MethodName string `xml:"name,attr"` MethodDescription string `xml:"description,attr"` + DisableStringOutCache bool `xml:"disablestringoutcache,attr"` Params []ComponentDefinitionParam `xml:"param"` } From 2059d30a27f4c962ea3a1f55ebc1a1daea99ccfb Mon Sep 17 00:00:00 2001 From: Alexander Oster <alexanderoster@users.noreply.github.com> Date: Thu, 17 Feb 2022 17:05:50 +0100 Subject: [PATCH 125/143] Added disabling of stringout caching --- Source/buildimplementationcpp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/buildimplementationcpp.go b/Source/buildimplementationcpp.go index e47ae9b8..16acaee5 100644 --- a/Source/buildimplementationcpp.go +++ b/Source/buildimplementationcpp.go @@ -994,7 +994,7 @@ func writeCImplementationMethod(component ComponentDefinition, method ComponentD // Special functions are an exception for string outs in global functions! bHasCacheCall := (len (stringOutParameters) > 0) && (isSpecialFunction != eSpecialMethodError) && (isSpecialFunction != eSpecialMethodBuildinfo) && (isSpecialFunction != eSpecialMethodPrerelease); - if (isGlobal && method.DisableStringOutCache) { + if (method.DisableStringOutCache) { bHasCacheCall = false; } From dd1c61f9b225bb75ce44905528564c9cb7ff24ce Mon Sep 17 00:00:00 2001 From: Alexander Oster <alexanderoster@users.noreply.github.com> Date: Thu, 17 Feb 2022 17:25:57 +0100 Subject: [PATCH 126/143] Removed explicit constructors from CInputVector --- Source/buildbindingccpp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index 8aea8f74..416c9189 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -970,7 +970,7 @@ func writeCPPInputVector(w LanguageWriter, NameSpace string, ClassIdentifier str w.Writeln(" ") w.Writeln("public:") w.Writeln(" ") - w.Writeln(" explicit C%sInputVector( const std::vector<T>& vec)", ClassIdentifier) + w.Writeln(" C%sInputVector( const std::vector<T>& vec)", ClassIdentifier) w.Writeln(" : m_data( vec.data() ), m_size( vec.size() )") w.Writeln(" {") w.Writeln(" }") From 53d84dc48f12a658e66cbe66fa68878dccf72ce9 Mon Sep 17 00:00:00 2001 From: Alexander Oster <alexanderoster@users.noreply.github.com> Date: Wed, 23 Feb 2022 12:15:09 +0100 Subject: [PATCH 127/143] some platforms don't support strnlen_s --- Source/buildbindingccpp.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index 416c9189..39b7cb07 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -415,7 +415,9 @@ func buildDynamicCLoadTableCode(component ComponentDefinition, w LanguageWriter, w.Writeln("#ifdef _WIN32") w.Writeln("// Convert filename to UTF16-string") - w.Writeln("int nLength = static_cast<int>(strnlen_s(pLibraryFileName, MAX_PATH));") + w.Writeln("int nLength = 0;") + w.Writeln("while ((pLibraryFileName[nLength] != 0) && (nLength < MAX_PATH))") + w.Writeln(" nLength++;") w.Writeln("int nBufferSize = nLength * 2 + 2;") if (!useStrictC) { w.Writeln("std::vector<wchar_t> wsLibraryFileName(nBufferSize);") From af2bf4f313850329c0265da153d98c0e50f4a503 Mon Sep 17 00:00:00 2001 From: Kevin Zhang <ping.zhang@live.com> Date: Tue, 5 Apr 2022 15:19:35 +0800 Subject: [PATCH 128/143] Make the C# object disposable (#179) * Make C# object with native handle disposable The wrapper user can decide to release the native handle immediately to avoid potential resource race issues. * Implement dispose pattern following the Microsoft documentation https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose * Refine the change according to pull request comments Co-authored-by: Kevin Zhang <Ping.Zhang@autodesk.com> --- Source/buildbindingcsharp.go | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Source/buildbindingcsharp.go b/Source/buildbindingcsharp.go index 8c19d3b9..6900291f 100644 --- a/Source/buildbindingcsharp.go +++ b/Source/buildbindingcsharp.go @@ -1011,7 +1011,9 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW class := component.Classes[i] CSharpParentClassName := "" - if !component.isBaseClass(class) { + if component.isBaseClass(class) { + CSharpParentClassName = ": IDisposable" + } else { if class.ParentClass == "" { CSharpParentClassName = ": " + CSharpBaseClassName } else { @@ -1030,14 +1032,28 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW w.Writeln(" Handle = NewHandle;") w.Writeln(" }") w.Writeln("") - w.Writeln(" ~C%s ()", class.ClassName) + w.Writeln(" protected virtual void Dispose(bool disposing)") w.Writeln(" {") + w.Writeln(" if (disposing)") + w.Writeln(" {") + w.Writeln(" // dispose managed state (managed objects).") + w.Writeln(" }") w.Writeln(" if (Handle != IntPtr.Zero) {") w.Writeln(" Internal.%sWrapper.%s (Handle);", NameSpace, component.Global.ReleaseMethod) w.Writeln(" Handle = IntPtr.Zero;") w.Writeln(" }") w.Writeln(" }") w.Writeln("") + w.Writeln(" public void Dispose()") + w.Writeln(" {") + w.Writeln(" // Dispose of unmanaged resources.") + w.Writeln(" Dispose(true);") + w.Writeln(" // Suppress finalization.") + w.Writeln(" GC.SuppressFinalize(this);") + w.Writeln(" }") + w.Writeln("") + w.Writeln(" ~C%s () => Dispose(false);", class.ClassName) + w.Writeln("") w.Writeln(" protected void CheckError (Int32 errorCode)") w.Writeln(" {") From ff6fa29cf33ab3f01a62a8a2dc57d9941fba05c6 Mon Sep 17 00:00:00 2001 From: Martin Weismann <martin.weismann@autodesk.com> Date: Mon, 27 Jun 2022 06:34:39 +0200 Subject: [PATCH 129/143] Add MacOS ARM build --- .github/workflows/build.yml | 7 ++++++- Build/build.bat | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 79e8cf21..43954297 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,12 +35,17 @@ jobs: with: name: act.darwin path: act.darwin + - name: Upload MacOS ARM Binary + uses: actions/upload-artifact@v2 + with: + name: act.arm.darwin + path: act.arm.darwin - name: Upload Linux Binary uses: actions/upload-artifact@v2 with: name: act.linux path: act.linux - - name: Upload Linux Arm Binary + - name: Upload Linux ARM Binary uses: actions/upload-artifact@v2 with: name: act.arm.linux diff --git a/Build/build.bat b/Build/build.bat index 06443259..a690dae0 100644 --- a/Build/build.bat +++ b/Build/build.bat @@ -36,6 +36,11 @@ set GOARCH=amd64 echo "Build act.darwin" go build -o ..\act.darwin %Sources% +set GOOS=darwin +set GOARCH=arm +echo "Build act.arm.darwin" +go build -o ..\act.arm.darwin %Sources% + set GOOS=linux set GOARCH=arm set GOARM=5 From b9bff5ab53be3d8e155a08dc09527c2caf221a55 Mon Sep 17 00:00:00 2001 From: Nathan Woodward <52930367+woodwan@users.noreply.github.com> Date: Tue, 2 Aug 2022 16:53:43 +0100 Subject: [PATCH 130/143] Allow struct predeclaration (#175) Co-authored-by: Martin Weismann <30837766+martinweismann@users.noreply.github.com> --- Source/languagec.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/languagec.go b/Source/languagec.go index 6fe92be5..d375cdec 100644 --- a/Source/languagec.go +++ b/Source/languagec.go @@ -465,7 +465,11 @@ func buildCCPPStructs(component ComponentDefinition, w LanguageWriter, NameSpace for i := 0; i < len(component.Structs); i++ { structinfo := component.Structs[i]; - w.Writeln("typedef struct {"); + if (useCPPTypes) { + w.Writeln("typedef struct s%s {", structinfo.Name); + } else { + w.Writeln("typedef struct s%s%s {", NameSpace, structinfo.Name); + } for j := 0; j < len(structinfo.Members); j++ { member := structinfo.Members[j]; From 5a7e0c0e61346a05ec4189c84126d962083b786f Mon Sep 17 00:00:00 2001 From: Martin Weismann <30837766+martinweismann@users.noreply.github.com> Date: Tue, 2 Aug 2022 17:54:08 +0200 Subject: [PATCH 131/143] Autogenerate Documentation with Sphinx (#181) * First try for Sphinx documentation * Add more documentation * Prepare for more documentation-generation * Fixup build --- Build/build.bat | 2 +- Build/build.sh | 2 +- README.md | 26 +- Source/automaticcomponenttoolkit.go | 9 +- Source/buildbindingccpp.go | 57 ++- Source/buildbindingccppdocumentation.go | 482 ++++++++++++++++++++++++ Source/componentdefinition.go | 2 +- Source/languagec.go | 57 ++- Source/languagecpp.go | 6 +- 9 files changed, 597 insertions(+), 46 deletions(-) mode change 100755 => 100644 Build/build.sh create mode 100644 Source/buildbindingccppdocumentation.go diff --git a/Build/build.bat b/Build/build.bat index a690dae0..49a6a27d 100644 --- a/Build/build.bat +++ b/Build/build.bat @@ -3,7 +3,7 @@ set startingDir="%CD%" set basepath="%~dp0" cd %basepath%\..\Source -set Sources=actutils.go automaticcomponenttoolkit.go buildbindingccpp.go buildbindingcsharp.go buildbindinggo.go buildbindingnode.go buildbindingpascal.go buildbindingpython.go buildimplementationcpp.go buildbindingjava.go buildimplementationpascal.go componentdefinition.go componentdiff.go languagewriter.go languagec.go languagecpp.go languagepascal.go +set Sources=actutils.go automaticcomponenttoolkit.go buildbindingccpp.go buildbindingccppdocumentation.go buildbindingcsharp.go buildbindinggo.go buildbindingnode.go buildbindingpascal.go buildbindingpython.go buildimplementationcpp.go buildbindingjava.go buildimplementationpascal.go componentdefinition.go componentdiff.go languagewriter.go languagec.go languagecpp.go languagepascal.go set GOOS=windows set GOARCH=amd64 diff --git a/Build/build.sh b/Build/build.sh old mode 100755 new mode 100644 index 0a3ae636..e4ba1ad4 --- a/Build/build.sh +++ b/Build/build.sh @@ -9,7 +9,7 @@ startingpath="$(pwd)" basepath="$(cd "$(dirname "$0")" && pwd)" cd "$basepath/../Source" -Sources="actutils.go automaticcomponenttoolkit.go buildbindingccpp.go buildbindingcsharp.go buildbindinggo.go buildbindingnode.go buildbindingpascal.go buildbindingpython.go buildbindingjava.go buildimplementationcpp.go buildimplementationpascal.go componentdefinition.go componentdiff.go languagewriter.go languagec.go languagecpp.go languagepascal.go" +Sources="actutils.go automaticcomponenttoolkit.go buildbindingccpp.go buildbindingccppdocumentation.go buildbindingcsharp.go buildbindinggo.go buildbindingnode.go buildbindingpascal.go buildbindingpython.go buildbindingjava.go buildimplementationcpp.go buildimplementationpascal.go componentdefinition.go componentdiff.go languagewriter.go languagec.go languagecpp.go languagepascal.go" export GOARCH="amd64" echo "Build act.exe" diff --git a/README.md b/README.md index 661795e1..ff2e6af4 100644 --- a/README.md +++ b/README.md @@ -56,19 +56,19 @@ Alternatively to 1) build ACT from source ([master](../../tree/master) for a rel ACT supports generation of bindings or implementation stubs for C++, C, Pascal, Golang, NodeJS and Python3. However, not all features of the IDL are yet supported by the individual binding or implementation language: #### Feature Matrix: Bindings -| Binding | Status | Operating Systems | class | scalar type | struct | enumeration | string | basicarray | structarray | Callbacks | Error Message Propagation | Injection | -|:---------------:|:----------------------------------------------------------:|:-----------------:|:---------:|:-------------:|:-------------:|:-------------:|:-------------:|:----------:|:-----------:|:---------:|:---------:|:---------:| -| C++ | ![](Documentation/images/Tick.png) mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | + | -| C++ Dynamic | ![](Documentation/images/Tick.png) mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | + | -| C | ![](Documentation/images/Tick.png) mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | - | -| C Dynamic | ![](Documentation/images/Tick.png) mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | - | -| Pascal | ![](Documentation/images/Tick.png) mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | + | -| Python3 | ![](Documentation/images/Tick.png) complete (but not very pythonic) | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | + | -| Golang | ![](Documentation/images/Tick.png) mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | + | -| NodeJS | ![](Documentation/images/O.png) partial support | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | ? | ? | - | + | - | -| C# | ![](Documentation/images/O.png) experimental | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | - | - | - | + | - | -| Java | ![](Documentation/images/Tick.png) experimental | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | + | -| PHP | ![](Documentation/images/X.png) not implemented | Win, Linux, MacOS | - | - | - | - | - | - | - | - | - | - | +| Binding | Status | Operating Systems | class | scalar type | struct | enumeration | string | basicarray | structarray | Callbacks | Error Message Propagation | Injection | API Documentation | +|:---------------:|:----------------------------------------------------------:|:-----------------:|:---------:|:-------------:|:-------------:|:-------------:|:-------------:|:----------:|:-----------:|:---------:|:---------:|:---------:|:---------:| +| C++ | ![](Documentation/images/Tick.png) mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | + | + | +| C++ Dynamic | ![](Documentation/images/Tick.png) mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | + | + | +| C | ![](Documentation/images/Tick.png) mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | - | - | +| C Dynamic | ![](Documentation/images/Tick.png) mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | - | - | +| Pascal | ![](Documentation/images/Tick.png) mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | + | + | +| Python3 | ![](Documentation/images/Tick.png) complete (but not very pythonic) | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | + | - | +| Golang | ![](Documentation/images/Tick.png) mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | + | - | +| NodeJS | ![](Documentation/images/O.png) partial support | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | ? | ? | - | + | - | - | +| C# | ![](Documentation/images/O.png) experimental | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | - | - | - | + | - | - | +| Java | ![](Documentation/images/Tick.png) experimental | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | + | - | +| PHP | ![](Documentation/images/X.png) not implemented | Win, Linux, MacOS | - | - | - | - | - | - | - | - | - | - | - | #### Feature Matrix: Implementation Stubs | Implementation | Status | Operating Systems | class | scalar type | struct | enumeration | string | basicarray | structarray | Callbacks | Journaling | Error Message Propagation | Injection | diff --git a/Source/automaticcomponenttoolkit.go b/Source/automaticcomponenttoolkit.go index 755d54a4..864d486b 100644 --- a/Source/automaticcomponenttoolkit.go +++ b/Source/automaticcomponenttoolkit.go @@ -64,6 +64,7 @@ func createComponent(component ComponentDefinition, outfolderBase string, bindin outputFolder := path.Join(outfolderBase, component.NameSpace+"_component") outputFolderBindings := path.Join(outputFolder, "Bindings") outputFolderExamples := path.Join(outputFolder, "Examples") + outputFolderDocumentation := path.Join(outputFolder, "Documentations") outputFolderImplementations := path.Join(outputFolder, "Implementations") if bindingsDirectoryOverride != "" { @@ -176,6 +177,12 @@ func createComponent(component ComponentDefinition, outfolderBase string, bindin case "Cpp": { + outputFolderDocumentationCppImplicit := outputFolderDocumentation + "/Cpp" + err = os.MkdirAll(outputFolderDocumentationCppImplicit, os.ModePerm) + if err != nil { + log.Fatal(err) + } + outputFolderBindingCppImplicit := outputFolderBindings + "/Cpp" err = os.MkdirAll(outputFolderBindingCppImplicit, os.ModePerm) if err != nil { @@ -204,7 +211,7 @@ func createComponent(component ComponentDefinition, outfolderBase string, bindin } err = BuildBindingCppImplicit(component, outputFolderBindingCppImplicit, outputFolderExampleCppImplicit, - indentString, binding.ClassIdentifier) + outputFolderDocumentationCppImplicit, indentString, binding.ClassIdentifier) if err != nil { return err } diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index 39b7cb07..303e9e6f 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -115,7 +115,8 @@ func BuildBindingCExplicit(component ComponentDefinition, outputFolder string, o } // BuildBindingCppImplicit builds dynamic C++-bindings of a library's API in form of implicitly linked functions handles. -func BuildBindingCppImplicit(component ComponentDefinition, outputFolder string, outputFolderExample string, indentString string, ClassIdentifier string) error { +func BuildBindingCppImplicit(component ComponentDefinition, outputFolder string, outputFolderExample string, + outputFolderDocumentation string, indentString string, ClassIdentifier string) error { forceRecreation := false ExplicitLinking := false @@ -168,9 +169,17 @@ func BuildBindingCppImplicit(component ComponentDefinition, outputFolder string, log.Printf("Omitting recreation of C++-example CMakeLists-file \"%s\"", CPPCMake) } } + + err = BuildCCPPDocumentation(component, outputFolderDocumentation, ClassIdentifier) + if err != nil { + return err + } + + return nil } + func buildDynamicCCPPHeader(component ComponentDefinition, w LanguageWriter, NameSpace string, BaseName string, headerOnly bool, useCPPTypes bool) error { @@ -527,7 +536,7 @@ func buildDynamicCImplementation(component ComponentDefinition, w LanguageWriter return nil } -func writeDynamicCPPMethodDeclaration(method ComponentDefinitionMethod, w LanguageWriter, NameSpace string, ClassIdentifier string, ClassName string) error { +func getDynamicCPPMethodParameters(method ComponentDefinitionMethod, NameSpace string, ClassIdentifier string, ClassName string) (string, string, error) { parameters := "" returntype := "void" @@ -564,12 +573,19 @@ func writeDynamicCPPMethodDeclaration(method ComponentDefinitionMethod, w Langua case "return": returntype = getBindingCppParamType(param.ParamType, param.ParamClass, NameSpace, ClassIdentifier, false) default: - return fmt.Errorf("invalid method parameter passing \"%s\" for %s.%s(%s)", param.ParamPass, ClassName, method.MethodName, param.ParamName) + return "", "", fmt.Errorf("invalid method parameter passing \"%s\" for %s.%s(%s)", param.ParamPass, ClassName, method.MethodName, param.ParamName) } } - w.Writeln(" inline %s %s(%s);", returntype, method.MethodName, parameters) + return parameters, returntype, nil +} +func writeDynamicCPPMethodDeclaration(method ComponentDefinitionMethod, w LanguageWriter, NameSpace string, ClassIdentifier string, ClassName string) error { + parameters, returntype, err := getDynamicCPPMethodParameters(method, NameSpace, ClassIdentifier, ClassName) + if (err!= nil) { + return err + } + w.Writeln(" inline %s %s(%s);", returntype, method.MethodName, parameters) return nil } @@ -972,12 +988,12 @@ func writeCPPInputVector(w LanguageWriter, NameSpace string, ClassIdentifier str w.Writeln(" ") w.Writeln("public:") w.Writeln(" ") - w.Writeln(" C%sInputVector( const std::vector<T>& vec)", ClassIdentifier) + w.Writeln(" C%sInputVector(const std::vector<T>& vec)", ClassIdentifier) w.Writeln(" : m_data( vec.data() ), m_size( vec.size() )") w.Writeln(" {") w.Writeln(" }") w.Writeln(" ") - w.Writeln(" C%sInputVector( const T* in_data, size_t in_size)", ClassIdentifier) + w.Writeln(" C%sInputVector(const T* in_data, size_t in_size)", ClassIdentifier) w.Writeln(" : m_data( in_data ), m_size(in_size )") w.Writeln(" {") w.Writeln(" }") @@ -1094,6 +1110,20 @@ func getBindingCppVariableName(param ComponentDefinitionParam) string { } +func getCPPInheritanceSpecifier(component ComponentDefinition, class ComponentDefinitionClass, cppClassPrefix string, ClassIdentifier string) (string, string) { + cppParentClassName := "" + inheritanceSpecifier := "" + if !component.isBaseClass(class) { + if class.ParentClass == "" { + cppParentClassName = cppClassPrefix + ClassIdentifier + component.Global.BaseClassName + } else { + cppParentClassName = cppClassPrefix + ClassIdentifier+ class.ParentClass + } + inheritanceSpecifier = fmt.Sprintf(": public %s ", cppParentClassName) + } + return cppParentClassName, inheritanceSpecifier +} + func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace string, BaseName string, ClassIdentifier string, ExplicitLinking bool) error { useCPPTypes := true @@ -1397,16 +1427,7 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s class := component.Classes[i] cppClassName := cppClassPrefix + ClassIdentifier + class.ClassName - cppParentClassName := "" - inheritanceSpecifier := "" - if !component.isBaseClass(class) { - if class.ParentClass == "" { - cppParentClassName = cppClassPrefix + ClassIdentifier + component.Global.BaseClassName - } else { - cppParentClassName = cppClassPrefix + ClassIdentifier+ class.ParentClass - } - inheritanceSpecifier = fmt.Sprintf(": public %s ", cppParentClassName) - } + cppParentClassName, inheritanceSpecifier := getCPPInheritanceSpecifier(component, class, cppClassPrefix, ClassIdentifier) w.Writeln(" ") w.Writeln("/*************************************************************************************************************************") @@ -1670,7 +1691,7 @@ func BuildBindingCppExplicit(component ComponentDefinition, outputFolder string, } -func buildDynamicCppExample(componentdefinition ComponentDefinition, w LanguageWriter, outputFolder string, ClassIdentifier string, ExplicitLinking bool) error { +func buildDynamicCppExample(componentdefinition ComponentDefinition, w LanguageWriter, outputFolder string, ClassIdentifier string, ExplicitLinking bool) { NameSpace := componentdefinition.NameSpace BaseName := componentdefinition.BaseName @@ -1719,8 +1740,6 @@ func buildDynamicCppExample(componentdefinition ComponentDefinition, w LanguageW w.Writeln(" return 0;") w.Writeln("}") w.Writeln("") - - return nil } func buildCppDynamicExampleCMake(componentdefinition ComponentDefinition, w LanguageWriter, outputFolder string, outputFolderExample string, ExplicitLinking bool) error { diff --git a/Source/buildbindingccppdocumentation.go b/Source/buildbindingccppdocumentation.go new file mode 100644 index 00000000..2e6e4dad --- /dev/null +++ b/Source/buildbindingccppdocumentation.go @@ -0,0 +1,482 @@ +/*++ + +Copyright (C) 2019 Autodesk Inc. (Original Author) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--*/ + +////////////////////////////////////////////////////////////////////////////////////////////////////// +// buildbindingccppdocumentation.go.go +// functions to generate the Sphinx documentation of a library's C++-bindings +////////////////////////////////////////////////////////////////////////////////////////////////////// + +package main + +import ( + "fmt" + "log" + "path" +) + + +// BuildCCPPDocumentation builds the Sphinx documentation of a library's C++-bindings +func BuildCCPPDocumentation(component ComponentDefinition, outputFolder string, ClassIdentifier string) (error) { + BaseName := component.BaseName + + globalFileName := path.Join(outputFolder, BaseName + ".rst") + log.Printf("Creating \"%s\"", globalFileName) + globalDocFile, err := CreateLanguageFile(globalFileName, "\t") + if err != nil { + return err + } + err = buildCCPPDocumentationGlobal(component, globalDocFile, ClassIdentifier) + if err != nil { + return err + } + + typesFileName := path.Join(outputFolder, BaseName + "-types.rst") + log.Printf("Creating \"%s\"", typesFileName) + typesDocFile, err := CreateLanguageFile(typesFileName, "\t") + if err != nil { + return err + } + err = buildCCPPDocumentationTypes(component, typesDocFile, ClassIdentifier) + if err != nil { + return err + } + + for i := 0; i < len(component.Classes); i++ { + class := component.Classes[i] + classFileName := path.Join(outputFolder, BaseName + "_" + class.ClassName + ".rst") + log.Printf("Creating \"%s\"", classFileName) + classDocFile, err := CreateLanguageFile(classFileName, "\t") + if err != nil { + return err + } + err = buildCCPPDocumentationClass(component, classDocFile, class, ClassIdentifier) + if err != nil { + return err + } + + } + + + err = buildCCPPDocumentationExample(component, outputFolder, ClassIdentifier, true, "_dynamic") + if err != nil { + return err + } + err = buildCCPPDocumentationExample(component, outputFolder, ClassIdentifier, false, "_implicit") + if err != nil { + return err + } + + return nil +} + +func buildCCPPDocumentationExample(component ComponentDefinition, outputFolder string, ClassIdentifier string, ExplicitLinking bool, suffix string) error { + NameSpace := component.NameSpace + + DynamicCPPExample := path.Join(outputFolder, NameSpace +"_example"+suffix+".cpp") + log.Printf("Creating \"%s\"", DynamicCPPExample) + dyncppexamplefile, err := CreateLanguageFile(DynamicCPPExample, " ") + if err != nil { + return err + } + buildDynamicCppExample(component, dyncppexamplefile, outputFolder, ClassIdentifier, ExplicitLinking) + + DynamicCPPCMake := path.Join(outputFolder, "CMakeLists"+suffix+".txt") + log.Printf("Creating \"%s\"", DynamicCPPCMake) + dyncppcmake, err := CreateLanguageFile(DynamicCPPCMake, " ") + if err != nil { + return err + } + buildCppDynamicExampleCMake(component, dyncppcmake, outputFolder, outputFolder, ExplicitLinking) + return nil +} + +func writeCPPDocumentationFunctionPointer(component ComponentDefinition, w LanguageWriter, + functiontype ComponentDefinitionFunctionType) (error) { + + NameSpace := component.NameSpace + returnType := "void" + parameters := "" + + for j := 0; j < len(functiontype.Params); j++ { + param := functiontype.Params[j] + + cParamTypeName, err := getCPPParameterTypeName(param.ParamType, NameSpace, param.ParamClass); + if (err != nil) { + return err; + } + if (parameters != "") { + parameters = parameters + ", " + } + if (param.ParamPass == "in") { + parameters = parameters + cParamTypeName + } else { + parameters = parameters + cParamTypeName + "*" + } + } + w.Writeln(" .. cpp:type:: %s = %s(*)(%s)", functiontype.FunctionName, returnType, parameters) + w.Writeln(" ") + w.Writeln(" %s", functiontype.FunctionDescription) + w.Writeln(" ") + + for j := 0; j < len(functiontype.Params); j++ { + param := functiontype.Params[j] + + cParams, err := generateCCPPParameter(param, "", functiontype.FunctionName, NameSpace, true) + if (err != nil) { + return err; + } + for _, cParam := range cParams { + w.Writeln(" %s", cParam.ParamDocumentationLine); + } + } + w.Writeln(" ") + + return nil +} + + +func buildCCPPDocumentationGlobal(component ComponentDefinition, w LanguageWriter, ClassIdentifier string) (error) { + + NameSpace := component.NameSpace + LibraryName := component.LibraryName + global := component.Global + + wrapperName := "C"+ClassIdentifier+"Wrapper" + + w.Writeln("") + w.Writeln("The wrapper class %s", wrapperName) + w.Writeln("===================================================================================") + w.Writeln("") + w.Writeln("") + w.Writeln(".. cpp:class:: %s::%s", NameSpace, wrapperName) + + w.Writeln("") + w.Writeln(" All types of %s reside in the namespace %s and all", LibraryName, NameSpace) + w.Writeln(" functionality of %s resides in %s::%s.", LibraryName, NameSpace, wrapperName) + w.Writeln("") + w.Writeln(" A suitable way to use %s::%s is as a singleton.", NameSpace, wrapperName) + w.Writeln("") + + + for j := 0; j < len(global.Methods); j++ { + method := global.Methods[j] + + parameters, returntype, err := getDynamicCPPMethodParameters(method, NameSpace, ClassIdentifier, "Wrapper") + if (err != nil) { + return err + } + w.Writeln(" .. cpp:function:: %s %s(%s)", returntype, method.MethodName, parameters) + w.Writeln(" ") + w.Writeln(" %s", method.MethodDescription) + w.Writeln(" ") + writeCPPDocumentationParameters(method, w, NameSpace) + w.Writeln(" ") + } + + w.Writeln(".. cpp:type:: std::shared_ptr<%s> %s::P%s%s", wrapperName, NameSpace, ClassIdentifier, "Wrapper") + w.Writeln(" ") + + // Load library functions + // Check error functions of the base class + + return nil +} + + +func writeCPPDocumentationParameters(method ComponentDefinitionMethod, w LanguageWriter, NameSpace string) { + for k := 0; k < len(method.Params); k++ { + param := method.Params[k] + variableName := getBindingCppVariableName(param) + if (param.ParamPass == "return") { + w.Writeln(" :returns: %s", param.ParamDescription ) + } else { + w.Writeln(" :param %s: %s ", variableName, param.ParamDescription) + } + } + w.Writeln("") +} + +func buildCCPPDocumentationClass(component ComponentDefinition, w LanguageWriter, class ComponentDefinitionClass, ClassIdentifier string) (error) { + + NameSpace := component.NameSpace + className := "C"+ClassIdentifier+class.ClassName + + w.Writeln("") + w.Writeln("%s", className) + w.Writeln("====================================================================================================") + w.Writeln("") + w.Writeln("") + + _, inheritanceSpecifier := getCPPInheritanceSpecifier(component, class, "C", ClassIdentifier) + + w.Writeln(".. cpp:class:: %s::%s %s", NameSpace, className, inheritanceSpecifier) + w.Writeln("") + w.Writeln(" %s", class.ClassDescription) + w.Writeln("") + w.Writeln("") + + w.Writeln("") + w.Writeln("") + for j := 0; j < len(class.Methods); j++ { + method := class.Methods[j] + + parameters, returntype, err := getDynamicCPPMethodParameters(method, NameSpace, ClassIdentifier, class.ClassName) + if (err != nil) { + return err + } + w.Writeln(" .. cpp:function:: %s %s(%s)", returntype, method.MethodName, parameters) + w.Writeln("") + w.Writeln(" %s", method.MethodDescription) + w.Writeln("") + writeCPPDocumentationParameters(method, w, NameSpace) + w.Writeln("") + } + + w.Writeln(".. cpp:type:: std::shared_ptr<%s> %s::P%s%s", className, NameSpace, ClassIdentifier, class.ClassName) + w.Writeln("") + w.Writeln(" Shared pointer to %s to easily allow reference counting.", className) + w.Writeln("") + + return nil +} + +func buildCCPPDocumentationException(component ComponentDefinition, w LanguageWriter) { + LibraryName := component.LibraryName + NameSpace := component.NameSpace + + ExceptionName := "E" + NameSpace + "Exception" + w.Writeln(" ") + w.Writeln("%s: The standard exception class of %s", ExceptionName, LibraryName) + w.Writeln("============================================================================================================================================================================================================") + w.Writeln(" ") + w.Writeln(" Errors in %s are reported as Exceptions. It is recommended to not throw these exceptions in your client code.", LibraryName) + w.Writeln(" ") + w.Writeln(" ") + w.Writeln(" .. cpp:class:: %s::%s", NameSpace, ExceptionName) + w.Writeln(" ") + w.Writeln(" .. cpp:function:: void %s::what() const noexcept", ExceptionName) + w.Writeln(" ") + w.Writeln(" Returns error message") + w.Writeln(" ") + w.Writeln(" :return: the error message of this exception") + w.Writeln(" ") + + + w.Writeln(" ") + w.Writeln(" .. cpp:function:: %sResult %s::getErrorCode() const noexcept", NameSpace, ExceptionName) + w.Writeln(" ") + w.Writeln(" Returns error code") + w.Writeln(" ") + w.Writeln(" :return: the error code of this exception") + w.Writeln(" ") +} + + +func buildCCPPDocumentationInputVector(component ComponentDefinition, w LanguageWriter, ClassIdentifier string) { + LibraryName := component.LibraryName + NameSpace := component.NameSpace + + InputVector := "C" + ClassIdentifier + "InputVector" + w.Writeln(" ") + w.Writeln("%s: Adapter for passing arrays as input for functions", InputVector) + w.Writeln("===============================================================================================================================================================") + w.Writeln(" ") + w.Writeln(" Several functions of %s expect arrays of integral types or structs as input parameters.", LibraryName) + w.Writeln(" To not restrict the interface to, say, std::vector<type>,") + w.Writeln(" and to have a more abstract interface than a location in memory and the number of elements to input to a function") + w.Writeln(" %s provides a templated adapter class to pass arrays as input for functions.", LibraryName) + w.Writeln(" ") + w.Writeln(" Usually, instances of %s are generated anonymously (or even implicitly) in the call to a function that expects an input array.", InputVector) + w.Writeln(" ") + w.Writeln(" ") + + + w.Writeln(" .. cpp:class:: template<typename T> %s::%s", NameSpace, InputVector) + w.Writeln(" ") + w.Writeln(" .. cpp:function:: %s(const std::vector<T>& vec)", InputVector) + w.Writeln(" ") + w.Writeln(" Constructs of a %s from a std::vector<T>", InputVector) + w.Writeln(" ") + w.Writeln(" .. cpp:function:: %s(const T* in_data, size_t in_size)", InputVector) + w.Writeln(" ") + w.Writeln(" Constructs of a %s from a memory address and a given number of elements", InputVector) + w.Writeln(" ") + + w.Writeln(" .. cpp:function:: const T* %s::data() const", InputVector) + w.Writeln(" ") + w.Writeln(" returns the start address of the data captured by this %s", InputVector) + w.Writeln(" ") + + w.Writeln(" .. cpp:function:: size_t %s::size() const", InputVector) + w.Writeln(" ") + w.Writeln(" returns the number of elements captured by this %s", InputVector) + w.Writeln(" ") + w.Writeln(" ") +} + + +func buildCCPPDocumentationStructs(component ComponentDefinition, w LanguageWriter) (error) { + if len(component.Structs) == 0 { + return nil + } + + NameSpace := component.NameSpace + + w.Writeln("") + w.Writeln("Structs") + w.Writeln("--------------") + w.Writeln("") + w.Writeln(" All structs are defined as `packed`, i.e. with the") + w.Writeln(" ") + w.Writeln(" .. code-block:: c") + w.Writeln(" "); + w.Writeln(" #pragma pack (1)"); + w.Writeln(""); + + for i := 0; i < len(component.Structs); i++ { + structinfo := component.Structs[i]; + w.Writeln(" .. cpp:struct:: s%s", structinfo.Name); + w.Writeln(" "); + // w.Writeln(" %s", structinfo.Description); + // w.Writeln(" "); + for j := 0; j < len(structinfo.Members); j++ { + member := structinfo.Members[j]; + arraysuffix := ""; + if (member.Rows > 0) { + if (member.Columns > 0) { + arraysuffix = fmt.Sprintf ("[%d][%d]", member.Columns, member.Rows) + } else { + arraysuffix = fmt.Sprintf ("[%d]",member.Rows) + } + } + memberLine, err:= getCPPMemberLine(member, NameSpace, arraysuffix, structinfo.Name, "") + if (err!=nil) { + return err + } + w.Writeln(" .. cpp:member:: %s", memberLine) + w.Writeln(" "); + } + w.Writeln(""); + } + + return nil +} + +func buildCCPPDocumentationSimpleTypes(component ComponentDefinition, w LanguageWriter) { + NameSpace := component.NameSpace + + w.Writeln("Simple types") + w.Writeln("--------------") + w.Writeln("") + types := []string{"uint8", "uint16", "uint32", "uint64", "int8", "int16", "int32", "int64"} + for _, _type := range types { + w.Writeln(" .. cpp:type:: %s_t %s_%s", _type, NameSpace, _type) + w.Writeln(" ") + } + w.Writeln(" .. cpp:type:: float %s_single", NameSpace) + w.Writeln(" ") + w.Writeln(" .. cpp:type:: double %s_double", NameSpace) + w.Writeln(" ") + w.Writeln(" .. cpp:type:: %s_pvoid = void*", NameSpace) + w.Writeln(" ") + w.Writeln(" .. cpp:type:: %sResult = %s_int32", NameSpace, NameSpace) + w.Writeln(" ") + w.Writeln(" ") +} + +func buildCCPPDocumentationEnums(component ComponentDefinition, w LanguageWriter) { + if len(component.Enums) == 0 { + return + } + + NameSpace := component.NameSpace + + w.Writeln("") + w.Writeln("Enumerations") + w.Writeln("--------------") + w.Writeln("") + for i := 0; i < len(component.Enums); i++ { + enum := component.Enums[i] + w.Writeln(" .. cpp:enum-class:: e%s : %s_int32", enum.Name, NameSpace); + w.Writeln(" ") + // w.Writeln(" %s", enum.Description) + // w.Writeln(" ") + for j := 0; j < len(enum.Options); j++ { + option := enum.Options[j]; + w.Writeln(" .. cpp:enumerator:: %s = %d", option.Name, option.Value); + } + w.Writeln(" "); + } +} + +func buildCCPPDocumentationFunctionTypes(component ComponentDefinition, w LanguageWriter) (error) { + if len(component.Functions) == 0 { + return nil + } + w.Writeln("") + w.Writeln("Function types") + w.Writeln("---------------") + w.Writeln("") + w.Writeln("") + for i := 0; i < len(component.Functions); i++ { + functiontype := component.Functions[i] + err := writeCPPDocumentationFunctionPointer(component, w, functiontype) + if (err!=nil) { + return err + } + } + w.Writeln("") + + return nil +} + +func buildCCPPDocumentationTypes(component ComponentDefinition, w LanguageWriter, ClassIdentifier string) (error) { + LibraryName := component.LibraryName + + w.Writeln("") + w.Writeln("Types used in %s", LibraryName) + w.Writeln("==========================================================================================================") + w.Writeln("") + w.Writeln("") + + buildCCPPDocumentationSimpleTypes(component, w) + buildCCPPDocumentationEnums(component, w) + + err := buildCCPPDocumentationStructs(component, w) + if (err!=nil) { + return err + } + err = buildCCPPDocumentationFunctionTypes(component, w) + if (err!=nil) { + return err + } + buildCCPPDocumentationException(component, w) + buildCCPPDocumentationInputVector(component, w, ClassIdentifier) + + return nil +} diff --git a/Source/componentdefinition.go b/Source/componentdefinition.go index f14dff7a..0bdfdfc7 100644 --- a/Source/componentdefinition.go +++ b/Source/componentdefinition.go @@ -1033,7 +1033,7 @@ func (component *ComponentDefinition) CheckComponentDefinition() (error) { // CheckHeaderSpecialFunction checks a special function of the header against their required definitions -func CheckHeaderSpecialFunction (method ComponentDefinitionMethod, global ComponentDefinitionGlobal) (int, error) { +func CheckHeaderSpecialFunction(method ComponentDefinitionMethod, global ComponentDefinitionGlobal) (int, error) { if (global.ReleaseMethod == "") { return eSpecialMethodNone, errors.New ("No release method specified"); diff --git a/Source/languagec.go b/Source/languagec.go index d375cdec..8d1ab5c3 100644 --- a/Source/languagec.go +++ b/Source/languagec.go @@ -483,7 +483,7 @@ func buildCCPPStructs(component ComponentDefinition, w LanguageWriter, NameSpace } var memberLine string if (useCPPTypes) { - memberLine, err= getCPPMemberLine(member, NameSpace, arraysuffix, structinfo.Name) + memberLine, err= getCPPMemberLine(member, NameSpace, arraysuffix, structinfo.Name, ";") } else { memberLine, err= getCMemberLine(member, NameSpace, arraysuffix, structinfo.Name) } @@ -677,6 +677,7 @@ type CParameter struct { ParamType string ParamName string ParamComment string + ParamDocumentationLine string } @@ -700,61 +701,73 @@ func generateCCPPParameter(param ComponentDefinitionParam, className string, met cParams[0].ParamType = cParamTypeName; cParams[0].ParamName = "n" + param.ParamName; cParams[0].ParamComment = fmt.Sprintf("* @param[in] %s - %s", cParams[0].ParamName, param.ParamDescription); + cParams[0].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[0].ParamName, param.ParamDescription) case "bool": cParams[0].ParamType = cParamTypeName; cParams[0].ParamName = "b" + param.ParamName; cParams[0].ParamComment = fmt.Sprintf("* @param[in] %s - %s", cParams[0].ParamName, param.ParamDescription); + cParams[0].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[0].ParamName, param.ParamDescription) case "single": cParams[0].ParamType = cParamTypeName; cParams[0].ParamName = "f" + param.ParamName; cParams[0].ParamComment = fmt.Sprintf("* @param[in] %s - %s", cParams[0].ParamName, param.ParamDescription); + cParams[0].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[0].ParamName, param.ParamDescription) case "double": cParams[0].ParamType = cParamTypeName; cParams[0].ParamName = "d" + param.ParamName; cParams[0].ParamComment = fmt.Sprintf("* @param[in] %s - %s", cParams[0].ParamName, param.ParamDescription); + cParams[0].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[0].ParamName, param.ParamDescription) case "pointer": cParams[0].ParamType = cParamTypeName; cParams[0].ParamName = "p" + param.ParamName; cParams[0].ParamComment = fmt.Sprintf("* @param[in] %s - %s", cParams[0].ParamName, param.ParamDescription); + cParams[0].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[0].ParamName, param.ParamDescription) case "string": cParams[0].ParamType = "const " + cParamTypeName; cParams[0].ParamName = "p" + param.ParamName; cParams[0].ParamComment = fmt.Sprintf("* @param[in] %s - %s", cParams[0].ParamName, param.ParamDescription); + cParams[0].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[0].ParamName, param.ParamDescription) case "enum": cParams[0].ParamType = cParamTypeName; cParams[0].ParamName = "e" + param.ParamName; cParams[0].ParamComment = fmt.Sprintf("* @param[in] %s - %s", cParams[0].ParamName, param.ParamDescription); + cParams[0].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[0].ParamName, param.ParamDescription) case "struct": cParams[0].ParamType = "const " + cParamTypeName; cParams[0].ParamName = "p" + param.ParamName; cParams[0].ParamComment = fmt.Sprintf("* @param[in] %s - %s", cParams[0].ParamName, param.ParamDescription); + cParams[0].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[0].ParamName, param.ParamDescription) case "basicarray", "structarray": cParams = make([]CParameter,2) cParams[0].ParamType = fmt.Sprintf ("%s_uint64", NameSpace); cParams[0].ParamName = "n" + param.ParamName + "BufferSize"; cParams[0].ParamComment = fmt.Sprintf("* @param[in] %s - Number of elements in buffer", cParams[0].ParamName); + cParams[0].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[0].ParamName, param.ParamDescription) cParams[1].ParamType = "const " + cParamTypeName; cParams[1].ParamName = "p" + param.ParamName + "Buffer"; cParams[1].ParamComment = fmt.Sprintf("* @param[in] %s - %s buffer of %s", cParams[1].ParamName, param.ParamClass, param.ParamDescription); + cParams[1].ParamDocumentationLine = fmt.Sprintf(":param %s: buffer of %s", cParams[0].ParamName, param.ParamDescription) case "class", "optionalclass": cParams[0].ParamType = cParamTypeName; cParams[0].ParamName = "p" + param.ParamName; cParams[0].ParamComment = fmt.Sprintf("* @param[in] %s - %s", cParams[0].ParamName, param.ParamDescription); + cParams[0].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[0].ParamName, param.ParamDescription) case "functiontype": cParams[0].ParamType = cParamTypeName; cParams[0].ParamName = "p" + param.ParamName; cParams[0].ParamComment = fmt.Sprintf("* @param[in] %s - %s", cParams[0].ParamName, param.ParamDescription); + cParams[0].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[0].ParamName, param.ParamDescription) default: return nil, fmt.Errorf ("invalid method parameter type \"%s\" for %s.%s (%s)", param.ParamType, className, methodName, param.ParamName); @@ -768,45 +781,75 @@ func generateCCPPParameter(param ComponentDefinitionParam, className string, met cParams[0].ParamType = cParamTypeName + " *"; cParams[0].ParamName = "p" + param.ParamName; cParams[0].ParamComment = fmt.Sprintf("* @param[out] %s - %s", cParams[0].ParamName, param.ParamDescription); + if ("out" == param.ParamPass) { + cParams[0].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[0].ParamName, param.ParamDescription) + } else { + cParams[0].ParamDocumentationLine = fmt.Sprintf(":return: %s", param.ParamDescription) + } case "struct": cParams[0].ParamType = cParamTypeName; cParams[0].ParamName = "p" + param.ParamName; cParams[0].ParamComment = fmt.Sprintf("* @param[out] %s - %s", cParams[0].ParamName, param.ParamDescription); + if ("out" == param.ParamPass) { + cParams[0].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[0].ParamName, param.ParamDescription) + } else { + cParams[0].ParamDocumentationLine = fmt.Sprintf(":return: %s", param.ParamDescription) + } case "basicarray", "structarray": cParams = make([]CParameter,3) cParams[0].ParamType = fmt.Sprintf("const %s_uint64", NameSpace) cParams[0].ParamName = "n" + param.ParamName + "BufferSize"; - cParams[0].ParamComment = fmt.Sprintf("* @param[in] %s - Number of elements in buffer", cParams[0].ParamName); + paramComment0 := "Number of elements in buffer" + cParams[0].ParamComment = fmt.Sprintf("* @param[in] %s - %s", cParams[0].ParamName, paramComment0); cParams[1].ParamType = fmt.Sprintf("%s_uint64*", NameSpace) cParams[1].ParamName = "p" + param.ParamName + "NeededCount"; - cParams[1].ParamComment = fmt.Sprintf("* @param[out] %s - will be filled with the count of the written elements, or needed buffer size.", cParams[1].ParamName); + paramComment1 := "will be filled with the count of the written elements, or needed buffer size." + cParams[1].ParamComment = fmt.Sprintf("* @param[out] %s - %s", cParams[1].ParamName, paramComment1); cParams[2].ParamType = cParamTypeName; cParams[2].ParamName = "p" + param.ParamName + "Buffer"; - cParams[2].ParamComment = fmt.Sprintf("* @param[out] %s - %s buffer of %s", cParams[2].ParamName, param.ParamClass, param.ParamDescription); + paramComment2 := "buffer of " + param.ParamDescription + cParams[2].ParamComment = fmt.Sprintf("* @param[out] %s - %s %s", cParams[2].ParamName, param.ParamClass, paramComment2); + + cParams[0].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[0].ParamName, paramComment0) + cParams[1].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[1].ParamName, paramComment1) + cParams[2].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[2].ParamName, paramComment2) case "string": cParams = make([]CParameter,3) cParams[0].ParamType = fmt.Sprintf("const %s_uint32", NameSpace) cParams[0].ParamName = "n" + param.ParamName + "BufferSize"; - cParams[0].ParamComment = fmt.Sprintf("* @param[in] %s - size of the buffer (including trailing 0)", cParams[0].ParamName); + paramComment0 := "size of the buffer (including trailing 0)" + cParams[0].ParamComment = fmt.Sprintf("* @param[in] %s - %s", cParams[0].ParamName, paramComment0); cParams[1].ParamType = fmt.Sprintf("%s_uint32*", NameSpace) cParams[1].ParamName = "p" + param.ParamName + "NeededChars"; - cParams[1].ParamComment = fmt.Sprintf("* @param[out] %s - will be filled with the count of the written bytes, or needed buffer size.", cParams[1].ParamName); + paramComment1 := "will be filled with the count of the written bytes, or needed buffer size." + cParams[1].ParamComment = fmt.Sprintf("* @param[out] %s - %s", cParams[1].ParamName, paramComment1); cParams[2].ParamType = cParamTypeName; cParams[2].ParamName = "p" + param.ParamName + "Buffer"; - cParams[2].ParamComment = fmt.Sprintf("* @param[out] %s - %s buffer of %s, may be NULL", cParams[2].ParamName, param.ParamClass, param.ParamDescription); + paramComment2 := fmt.Sprintf("buffer of %s, may be NULL", param.ParamDescription) + cParams[2].ParamComment = fmt.Sprintf("* @param[out] %s - %s %s", cParams[2].ParamName, param.ParamClass, paramComment2); + + cParams[0].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[0].ParamName, paramComment0) + cParams[1].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[1].ParamName, paramComment1) + cParams[2].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[2].ParamName, paramComment2) case "class", "optionalclass": cParams[0].ParamType = cParamTypeName + " *"; cParams[0].ParamName = "p" + param.ParamName; cParams[0].ParamComment = fmt.Sprintf("* @param[out] %s - %s", cParams[0].ParamName, param.ParamDescription); + if ("out" == param.ParamPass) { + cParams[0].ParamDocumentationLine = fmt.Sprintf(":param %s: %s", cParams[0].ParamName, param.ParamDescription) + } else { + cParams[0].ParamDocumentationLine = fmt.Sprintf(":return: %s", param.ParamDescription) + } + default: return nil, fmt.Errorf ("invalid method parameter type \"%s\" for %s.%s (%s)", param.ParamType, className, methodName, param.ParamName); } diff --git a/Source/languagecpp.go b/Source/languagecpp.go index b2aa71e8..576e94dd 100644 --- a/Source/languagecpp.go +++ b/Source/languagecpp.go @@ -51,16 +51,16 @@ func CreateCPPTypesHeader(component ComponentDefinition, CTypesHeaderName string return err; } -func getCPPMemberLine(member ComponentDefinitionMember, NameSpace string, arraysuffix string, structName string) (string, error) { +func getCPPMemberLine(member ComponentDefinitionMember, NameSpace string, arraysuffix string, structName string, endCharacter string) (string, error) { switch (member.Type) { case "uint8", "uint16", "uint32", "uint64", "int8", "int16", "int32", "int64", "single", "double", "bool", "pointer": typeName, err := getCPPParameterTypeName(member.Type, NameSpace, "") if (err != nil) { return "", err } - return fmt.Sprintf("%s m_%s%s;", typeName, member.Name, arraysuffix), nil + return fmt.Sprintf("%s m_%s%s%s", typeName, member.Name, arraysuffix, endCharacter), nil case "enum": - return fmt.Sprintf("e%s m_%s%s;", member.Class, member.Name, arraysuffix), nil + return fmt.Sprintf("e%s m_%s%s%s", member.Class, member.Name, arraysuffix, endCharacter), nil default: return "", fmt.Errorf ("it is not possible for struct %s to contain a %s member", structName, member.Type); From 935104c1311f03b410593b920cb069960a5a092a Mon Sep 17 00:00:00 2001 From: Alexander Oster <alexanderoster@users.noreply.github.com> Date: Fri, 5 Aug 2022 16:07:12 +0200 Subject: [PATCH 132/143] Added Cpp Documentation creation --- Source/automaticcomponenttoolkit.go | 28 ++++++++++++++++++++++------ Source/buildbindingccpp.go | 21 +++++++++++++++++---- Source/componentdefinition.go | 1 + 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/Source/automaticcomponenttoolkit.go b/Source/automaticcomponenttoolkit.go index 864d486b..557242d5 100644 --- a/Source/automaticcomponenttoolkit.go +++ b/Source/automaticcomponenttoolkit.go @@ -147,6 +147,18 @@ func createComponent(component ComponentDefinition, outfolderBase string, bindin case "CppDynamic": { + + outputFolderDocumentationCppExplicit := ""; + + if (binding.Documentation != "") { + + outputFolderDocumentationCppExplicit = outputFolderDocumentation + "/Cpp" + err = os.MkdirAll(outputFolderDocumentationCppExplicit, os.ModePerm) + if err != nil { + log.Fatal(err) + } + } + outputFolderBindingCppDynamic := outputFolderBindings + "/CppDynamic" err = os.MkdirAll(outputFolderBindingCppDynamic, os.ModePerm) if err != nil { @@ -169,7 +181,7 @@ func createComponent(component ComponentDefinition, outfolderBase string, bindin } err = BuildBindingCppExplicit(component, outputFolderBindingCppDynamic, outputFolderExampleCppDynamic, - indentString, binding.ClassIdentifier) + outputFolderDocumentationCppExplicit, indentString, binding.ClassIdentifier) if err != nil { return err } @@ -177,10 +189,14 @@ func createComponent(component ComponentDefinition, outfolderBase string, bindin case "Cpp": { - outputFolderDocumentationCppImplicit := outputFolderDocumentation + "/Cpp" - err = os.MkdirAll(outputFolderDocumentationCppImplicit, os.ModePerm) - if err != nil { - log.Fatal(err) + outputFolderDocumentationCppImplicit := ""; + + if (binding.Documentation != "") { + outputFolderDocumentationCppImplicit = outputFolderDocumentation + "/Cpp"; + err = os.MkdirAll(outputFolderDocumentationCppImplicit, os.ModePerm) + if err != nil { + log.Fatal(err) + } } outputFolderBindingCppImplicit := outputFolderBindings + "/Cpp" @@ -513,7 +529,7 @@ func printUsageInfo() { } func main() { - ACTVersion := "1.7.0-develop" + ACTVersion := "1.8.0-develop" fmt.Fprintln(os.Stdout, "Automatic Component Toolkit v"+ACTVersion) if len(os.Args) < 2 { printUsageInfo() diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index 303e9e6f..034a4d19 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -170,9 +170,13 @@ func BuildBindingCppImplicit(component ComponentDefinition, outputFolder string, } } - err = BuildCCPPDocumentation(component, outputFolderDocumentation, ClassIdentifier) - if err != nil { - return err + if (outputFolderDocumentation != "") { + + err = BuildCCPPDocumentation(component, outputFolderDocumentation, ClassIdentifier) + if err != nil { + return err + } + } @@ -1620,7 +1624,7 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s // BuildBindingCppExplicit builds headeronly C++-bindings of a library's API in form of expliclty loaded function handles. func BuildBindingCppExplicit(component ComponentDefinition, outputFolder string, outputFolderExample string, - indentString string, ClassIdentifier string) error { + outputFolderDocumentation string, indentString string, ClassIdentifier string) error { forceRecreation := false ExplicitLinking := true namespace := component.NameSpace @@ -1686,6 +1690,15 @@ func BuildBindingCppExplicit(component ComponentDefinition, outputFolder string, log.Printf("Omitting recreation of C++Dynamic example file \"%s\"", DynamicCPPCMake) } } + + if (outputFolderDocumentation != "") { + + err = BuildCCPPDocumentation(component, outputFolderDocumentation, ClassIdentifier) + if err != nil { + return err + } + + } return nil } diff --git a/Source/componentdefinition.go b/Source/componentdefinition.go index 0bdfdfc7..24be9903 100644 --- a/Source/componentdefinition.go +++ b/Source/componentdefinition.go @@ -140,6 +140,7 @@ type ComponentDefinitionBinding struct { Language string `xml:"language,attr"` Indentation string `xml:"indentation,attr"` ClassIdentifier string `xml:"classidentifier,attr"` + Documentation string `xml:"documentation,attr"` Version string `xml:"version,attr"` } From bdaff609f18b092abb832387366c47598b52d449 Mon Sep 17 00:00:00 2001 From: Martin Weismann <30837766+martinweismann@users.noreply.github.com> Date: Tue, 23 Aug 2022 15:09:51 +0200 Subject: [PATCH 133/143] Run docker inside github action --- .github/workflows/dockerbuild.yml | 6 ++--- Build/Dockerfile | 39 ++++++++++++------------------- Build/build.sh | 0 Build/docker.sh | 10 ++++---- action.yml | 7 ++---- entrypoint.sh | 3 +++ 6 files changed, 27 insertions(+), 38 deletions(-) mode change 100644 => 100755 Build/build.sh diff --git a/.github/workflows/dockerbuild.yml b/.github/workflows/dockerbuild.yml index e266b5f8..0729b80a 100644 --- a/.github/workflows/dockerbuild.yml +++ b/.github/workflows/dockerbuild.yml @@ -7,15 +7,13 @@ jobs: steps: - name: Checkout uses: actions/checkout@v3 - - name: build step + - name: build act id: build_act uses: martinweismann/AutomaticComponentToolkit@rtti-native-2 with: command: 'act' - - name: example step + - name: run examples id: build_and_test_examples uses: martinweismann/AutomaticComponentToolkit@rtti-native-2 with: command: 'examples' - - name: Get the build time - run: echo "The build time was ${{ steps.build.outputs.time }}" \ No newline at end of file diff --git a/Build/Dockerfile b/Build/Dockerfile index 3bccd736..7e6c3641 100644 --- a/Build/Dockerfile +++ b/Build/Dockerfile @@ -1,12 +1,9 @@ FROM centos:centos8 -LABEL maintainer="Andrii Anpilogov (andrii.anpilogov@autodesk.com)" - -# ARG USER_ID -# ARG GROUP_ID +ARG USER_ID +ARG GROUP_ID -# RUN : "${USER_ID:?Build argument needs to be set and non-empty.}" \ -# : "${GROUP_ID:?Build argument needs to be set and non-empty.}" +LABEL maintainer="Andrii Anpilogov (andrii.anpilogov@autodesk.com)" RUN [ -e /etc/yum.conf ] && sed -i '/tsflags=nodocs/d' /etc/yum.conf || true @@ -43,7 +40,6 @@ RUN (cd /opt && curl -O -L 'http://downloads.sourceforge.net/project/freepascal/ # Golang RUN (cd /opt && curl -O -L https://golang.org/dl/go1.17.2.linux-amd64.tar.gz \ && tar zxvf go1.17.2.linux-amd64.tar.gz) -ENV PATH="${PATH}:/opt/go/bin" # Java RUN dnf -y install \ @@ -54,7 +50,6 @@ RUN rpm --import https://download.mono-project.com/repo/xamarin.gpg \ && dnf config-manager --add-repo https://download.mono-project.com/repo/centos8-stable.repo \ && dnf -y install mono-complete - # General purpose tools RUN dnf -y install \ glibc-common \ @@ -71,26 +66,22 @@ RUN dnf -y install \ yum-utils \ && yum clean all -# # Create user -# RUN groupadd docker \ -# && useradd -ms /bin/bash --uid $USER_ID -g docker -G wheel user \ -# && printf "user:user" | chpasswd \ -# && printf "user ALL= NOPASSWD: ALL\\n" >> /etc/sudoers - # # Initialize Toolkit RUN echo "source /opt/rh/gcc-toolset-9/enable" >> /etc/bashrc -# RUN echo "source /opt/rh/gcc-toolset-9/enable" >> /home/user/.bash_profile -# RUN echo "export PATH=\$PATH:/opt/go/bin" >> /home/user/.bash_profile - -# VOLUME /data +ENV PATH="${PATH}:/opt/go/bin" -# # Run Container as nonroot -# USER user -# WORKDIR /data +# Initialize Toolkit +# RUN : "${USER_ID:?Build argument needs to be set and non-empty.}" \ +# : "${GROUP_ID:?Build argument needs to be set and non-empty.}" -# ENTRYPOINT [ "/bin/bash", "-l" ] +# Create user +RUN if [ $USER_ID != "" ] ; then groupadd docker \ + && useradd -ms /bin/bash --uid $USER_ID -g docker -G wheel user \ + && printf "user:user" | chpasswd \ + && printf "user ALL= NOPASSWD: ALL\\n" >> /etc/sudoers ; fi -# COPY entrypoint.sh /entrypoint.sh +# Initialize Toolkit +RUN if [ $USER_ID != "" ] ; then echo "source /opt/rh/gcc-toolset-9/enable" >> /home/user/.bash_profile ; fi +RUN if [ $USER_ID != "" ] ; then echo "export PATH=\$PATH:/opt/go/bin" >> /home/user/.bash_profile ; fi ENTRYPOINT ["./entrypoint.sh"] - diff --git a/Build/build.sh b/Build/build.sh old mode 100644 new mode 100755 diff --git a/Build/docker.sh b/Build/docker.sh index 158d36c3..97e384e9 100755 --- a/Build/docker.sh +++ b/Build/docker.sh @@ -9,17 +9,17 @@ case "$1" in docker build -t act-build --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) . ;; act) - docker run -it --rm -v $PWD/..:/data act-build /data/Build/build.sh + docker run -it --rm -v $PWD/..:/data --user $(id -u):$(id -g) --entrypoint /data/Build/build.sh act-build ;; examples) - docker run -it --rm -v $PWD/..:/data act-build /data/Examples/build.sh + docker run -it --rm -v $PWD/..:/data --user $(id -u):$(id -g) --entrypoint /data/Examples/build.sh act-build ;; all) - docker run -it --rm -v $PWD/..:/data act-build /data/Build/build.sh - docker run -it --rm -v $PWD/..:/data act-build /data/Examples/build.sh + docker run -it --rm -v $PWD/..:/data --user $(id -u):$(id -g) --entrypoint /data/Build/build.sh act-build + docker run -it --rm -v $PWD/..:/data --user $(id -u):$(id -g) --entrypoint /data/Examples/build.sh act-build ;; cli) - docker run -it --rm -v $PWD/..:/data --entrypoint bash act-build -l + docker run -it --rm -v $PWD/..:/data --user $(id -u):$(id -g) --entrypoint bash act-build -l ;; *) echo "Use one of availbale commands:" diff --git a/action.yml b/action.yml index edaa2d28..6af23b99 100644 --- a/action.yml +++ b/action.yml @@ -1,4 +1,4 @@ -# docker.yml +# action.yml name: 'BuildWithDocker' description: 'Build ACT with in a Docker container' inputs: @@ -6,11 +6,8 @@ inputs: description: 'What command to run' required: true default: 'act' -outputs: - time: # id of output - description: 'The time docker ran' runs: using: 'docker' image: 'Build/Dockerfile' args: - - ${{ inputs.command }} \ No newline at end of file + - ${{ inputs.command }} diff --git a/entrypoint.sh b/entrypoint.sh index 2c6fc7bf..0e18e3aa 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -3,6 +3,9 @@ echo "Action selected: $1" time=$(date) echo "::set-output name=time::$time" +echo $(id -u) +echo $(id -g) + case "$1" in act) From 629e950d1fd817122e925c319eff972a33abfb44 Mon Sep 17 00:00:00 2001 From: Martin Weismann <martin.weismann@autodesk.com> Date: Wed, 24 Aug 2022 13:08:46 +0200 Subject: [PATCH 134/143] Rename docker workflow --- .github/workflows/{dockerbuild.yml => build_examples.yml} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename .github/workflows/{dockerbuild.yml => build_examples.yml} (76%) diff --git a/.github/workflows/dockerbuild.yml b/.github/workflows/build_examples.yml similarity index 76% rename from .github/workflows/dockerbuild.yml rename to .github/workflows/build_examples.yml index 0729b80a..27c72475 100644 --- a/.github/workflows/dockerbuild.yml +++ b/.github/workflows/build_examples.yml @@ -1,9 +1,9 @@ on: [push] - +name: Build ACT examples jobs: build_with_docker: runs-on: ubuntu-latest - name: Build and test ACT inside Docker + name: Build ACT examples with docker steps: - name: Checkout uses: actions/checkout@v3 @@ -12,8 +12,8 @@ jobs: uses: martinweismann/AutomaticComponentToolkit@rtti-native-2 with: command: 'act' - - name: run examples - id: build_and_test_examples + - name: build examples + id: build_examples uses: martinweismann/AutomaticComponentToolkit@rtti-native-2 with: command: 'examples' From 38635dc3ee872e5884e9a24e33ef56c6affb1095 Mon Sep 17 00:00:00 2001 From: Martin Weismann <martin.weismann@autodesk.com> Date: Wed, 24 Aug 2022 14:03:48 +0200 Subject: [PATCH 135/143] Build examples also for pull requests --- .github/workflows/build_examples.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_examples.yml b/.github/workflows/build_examples.yml index 27c72475..6313169b 100644 --- a/.github/workflows/build_examples.yml +++ b/.github/workflows/build_examples.yml @@ -1,4 +1,4 @@ -on: [push] +on: [push, pull_request] name: Build ACT examples jobs: build_with_docker: From 78ffde0d7dbc92b18992f54629dd22e7fe923041 Mon Sep 17 00:00:00 2001 From: Martin Weismann <martin.weismann@autodesk.com> Date: Wed, 24 Aug 2022 22:26:04 +0200 Subject: [PATCH 136/143] Align build.sh with build.bat --- Build/build.sh | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/Build/build.sh b/Build/build.sh index e4ba1ad4..6b1ee390 100755 --- a/Build/build.sh +++ b/Build/build.sh @@ -1,38 +1,53 @@ #!/bin/bash -failed() { - echo "${1}" 1>&2 - exit 1; -} +set -euxo pipefail startingpath="$(pwd)" basepath="$(cd "$(dirname "$0")" && pwd)" cd "$basepath/../Source" Sources="actutils.go automaticcomponenttoolkit.go buildbindingccpp.go buildbindingccppdocumentation.go buildbindingcsharp.go buildbindinggo.go buildbindingnode.go buildbindingpascal.go buildbindingpython.go buildbindingjava.go buildimplementationcpp.go buildimplementationpascal.go componentdefinition.go componentdiff.go languagewriter.go languagec.go languagecpp.go languagepascal.go" + +echo "Build act.win64.exe" export GOARCH="amd64" +export GOOS="windows" +go build -o ../act.win64.exe $Sources -echo "Build act.exe" +echo "Build act.win32.exe" +export GOARCH="386" export GOOS="windows" -go build -o ../act.exe $Sources || failed "Error compiling act.exe" +go build -o ../act.win32.exe $Sources + +echo "Build act.linux64" +export GOOS="linux" +export GOARCH="amd64" +go build -o ../act.linux64 $Sources -echo "Build act.linux" +echo "Build act.linux32" export GOOS="linux" -go build -o ../act.linux $Sources || failed "Error compiling act.linux" +export GOARCH="386" +go build -o ../act.linux32 $Sources echo "Build act.darwin" export GOOS="darwin" -go build -o ../act.darwin $Sources || failed "Error compiling act.darwin" +export GOARCH="amd64" +go build -o ../act.darwin $Sources echo "Build act.arm.darwin" export GOOS="darwin" export GOARCH="arm64" -go build -o ../act.arm.darwin $Sources || failed "Error compiling act.arm.darwin" +go build -o ../act.arm.darwin $Sources -echo "Build act.arm.linux" || failed "Error compiling act.arm.linux" +echo "Build act.linux32.arm" export GOOS="linux" -export GOARCH="arm" export GOARM="5" -go build -o ../act.arm.linux $Sources +export GOARCH="386" +go build -o ../act.linux32.arm $Sources + +echo "Build act.linux64.arm" +export GOOS="linux" +export GOARCH="arm64" +export GOARM="5" +go build -o ../act.linux64.arm $Sources cd "$startingpath" From 4fb0f76e9f433170b369c27d6abdc75fd6b85642 Mon Sep 17 00:00:00 2001 From: Martin Weismann <martin.weismann@autodesk.com> Date: Wed, 24 Aug 2022 22:49:19 +0200 Subject: [PATCH 137/143] Rename created files --- .github/workflows/build.yml | 33 ++++++++++++++++++++++++--------- Build/build.bat | 12 ++++++------ Build/build.sh | 8 ++++---- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 43954297..b6819f53 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,11 +25,16 @@ jobs: submodules: true - run: ./build.bat working-directory: ./Build - - name: Upload Windows Binary + - name: Upload Windows 64bit Binary uses: actions/upload-artifact@v2 with: - name: act.exe - path: act.exe + name: act.win64.exe + path: act.win64.exe + - name: Upload Windows 32bit Binary + uses: actions/upload-artifact@v2 + with: + name: act.win32.exe + path: act.win32.exe - name: Upload MacOS Binary uses: actions/upload-artifact@v2 with: @@ -40,14 +45,24 @@ jobs: with: name: act.arm.darwin path: act.arm.darwin - - name: Upload Linux Binary + - name: Upload Linux 32bit Binary + uses: actions/upload-artifact@v2 + with: + name: act.linux32 + path: act.linux32 + - name: Upload Linux ARM 32bit Binary + uses: actions/upload-artifact@v2 + with: + name: act.arm.linux32 + path: act.arm.linux32 + - name: Upload Linux 64bit Binary uses: actions/upload-artifact@v2 with: - name: act.linux - path: act.linux - - name: Upload Linux ARM Binary + name: act.linux64 + path: act.linux64 + - name: Upload Linux ARM 64bit Binary uses: actions/upload-artifact@v2 with: - name: act.arm.linux - path: act.arm.linux + name: act.arm.linux64 + path: act.arm.linux64 diff --git a/Build/build.bat b/Build/build.bat index 49a6a27d..81f775b3 100644 --- a/Build/build.bat +++ b/Build/build.bat @@ -7,7 +7,7 @@ set Sources=actutils.go automaticcomponenttoolkit.go buildbindingccpp.go buildbi set GOOS=windows set GOARCH=amd64 -echo "Build act.exe" +echo "Build act.win64.exe" go build -o ..\act.win64.exe %Sources% echo "Patching properties of act.win64.exe" @@ -18,7 +18,7 @@ set GOARCH=386 echo "Build act.win32.exe" go build -o ..\act.win32.exe %Sources% -echo "Patching properties of act_win32.exe" +echo "Patching properties of act.win32.exe" ..\build\verpatch ..\act.win32.exe /high /va 1.7.0 /pv "1.7.0-develop" /s copyright "(c) 2018-2019 ACT Developers" /s desc "ACT is a code generator for software components" /s productName "Automatic Component Toolkit" set GOOS=linux @@ -44,14 +44,14 @@ go build -o ..\act.arm.darwin %Sources% set GOOS=linux set GOARCH=arm set GOARM=5 -echo "Build act.linux32.arm" -go build -o ..\act.linux32.arm %Sources% +echo "Build act.arm.linux32" +go build -o ..\act.arm.linux32 %Sources% set GOOS=linux set GOARCH=arm64 set GOARM=5 -echo "Build act.linux64.arm" -go build -o ..\act.linux64.arm %Sources% +echo "Build act.arm.linux64" +go build -o ..\act.arm.linux64 %Sources% copy ..\act.win64.exe ..\act.exe /Y diff --git a/Build/build.sh b/Build/build.sh index 6b1ee390..75888941 100755 --- a/Build/build.sh +++ b/Build/build.sh @@ -38,16 +38,16 @@ export GOOS="darwin" export GOARCH="arm64" go build -o ../act.arm.darwin $Sources -echo "Build act.linux32.arm" +echo "Build act.arm.linux32" export GOOS="linux" export GOARM="5" export GOARCH="386" -go build -o ../act.linux32.arm $Sources +go build -o ../act.arm.linux32 $Sources -echo "Build act.linux64.arm" +echo "Build act.arm.linux64" export GOOS="linux" export GOARCH="arm64" export GOARM="5" -go build -o ../act.linux64.arm $Sources +go build -o ../act.arm.linux64 $Sources cd "$startingpath" From 1cdee87d82c17bd7cf070b984bf99af7de24bb42 Mon Sep 17 00:00:00 2001 From: Martin Weismann <martin.weismann@autodesk.com> Date: Thu, 25 Aug 2022 12:28:12 +0200 Subject: [PATCH 138/143] Use local github action --- action.yml => .github/actions/buildWithDocker.yml | 4 ++-- .github/workflows/build_examples.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename action.yml => .github/actions/buildWithDocker.yml (75%) diff --git a/action.yml b/.github/actions/buildWithDocker.yml similarity index 75% rename from action.yml rename to .github/actions/buildWithDocker.yml index 6af23b99..04b4096f 100644 --- a/action.yml +++ b/.github/actions/buildWithDocker.yml @@ -1,6 +1,6 @@ -# action.yml +# buildWithDocker.yml name: 'BuildWithDocker' -description: 'Build ACT with in a Docker container' +description: 'Build ACT within a Docker container' inputs: command: # id of input description: 'What command to run' diff --git a/.github/workflows/build_examples.yml b/.github/workflows/build_examples.yml index 6313169b..8857121d 100644 --- a/.github/workflows/build_examples.yml +++ b/.github/workflows/build_examples.yml @@ -9,11 +9,11 @@ jobs: uses: actions/checkout@v3 - name: build act id: build_act - uses: martinweismann/AutomaticComponentToolkit@rtti-native-2 + uses: ./.github/actions/buildWithDocker.yml with: command: 'act' - name: build examples id: build_examples - uses: martinweismann/AutomaticComponentToolkit@rtti-native-2 + uses: ./.github/actions/buildWithDocker.yml with: command: 'examples' From bc4990661220a28a9d43b01dd514d28854e0bce5 Mon Sep 17 00:00:00 2001 From: Martin Weismann <martin.weismann@autodesk.com> Date: Thu, 25 Aug 2022 12:36:21 +0200 Subject: [PATCH 139/143] Move action location, try to fix build --- .../{buildWithDocker.yml => buildWithDocker/action.yml} | 2 +- .github/workflows/build.yml | 4 ++-- .github/workflows/build_examples.yml | 4 ++-- Build/build.bat | 1 + Build/build.sh | 1 + 5 files changed, 7 insertions(+), 5 deletions(-) rename .github/actions/{buildWithDocker.yml => buildWithDocker/action.yml} (92%) diff --git a/.github/actions/buildWithDocker.yml b/.github/actions/buildWithDocker/action.yml similarity index 92% rename from .github/actions/buildWithDocker.yml rename to .github/actions/buildWithDocker/action.yml index 04b4096f..78191f38 100644 --- a/.github/actions/buildWithDocker.yml +++ b/.github/actions/buildWithDocker/action.yml @@ -1,4 +1,4 @@ -# buildWithDocker.yml +# action.yml name: 'BuildWithDocker' description: 'Build ACT within a Docker container' inputs: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b6819f53..59fc2729 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,7 +7,7 @@ jobs: - uses: actions/checkout@v2 with: submodules: true - - run: sh build.sh + - run: ./build.sh working-directory: ./Build build-macos: runs-on: macos-10.15 @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v2 with: submodules: true - - run: sh build.sh + - run: ./build.sh working-directory: ./Build build-windows: runs-on: windows-2019 diff --git a/.github/workflows/build_examples.yml b/.github/workflows/build_examples.yml index 8857121d..42624a20 100644 --- a/.github/workflows/build_examples.yml +++ b/.github/workflows/build_examples.yml @@ -9,11 +9,11 @@ jobs: uses: actions/checkout@v3 - name: build act id: build_act - uses: ./.github/actions/buildWithDocker.yml + uses: ./.github/actions/buildWithDocker with: command: 'act' - name: build examples id: build_examples - uses: ./.github/actions/buildWithDocker.yml + uses: ./.github/actions/buildWithDocker with: command: 'examples' diff --git a/Build/build.bat b/Build/build.bat index 81f775b3..a29fc1e2 100644 --- a/Build/build.bat +++ b/Build/build.bat @@ -38,6 +38,7 @@ go build -o ..\act.darwin %Sources% set GOOS=darwin set GOARCH=arm +set GOARM=5 echo "Build act.arm.darwin" go build -o ..\act.arm.darwin %Sources% diff --git a/Build/build.sh b/Build/build.sh index 75888941..e2e7e8cd 100755 --- a/Build/build.sh +++ b/Build/build.sh @@ -35,6 +35,7 @@ go build -o ../act.darwin $Sources echo "Build act.arm.darwin" export GOOS="darwin" +export GOARM="5" export GOARCH="arm64" go build -o ../act.arm.darwin $Sources From 3c7879e93110a9d3c9ad383354221409a197a409 Mon Sep 17 00:00:00 2001 From: Martin Weismann <martin.weismann@autodesk.com> Date: Thu, 25 Aug 2022 12:40:56 +0200 Subject: [PATCH 140/143] Fix path to Dockerfile --- .github/actions/buildWithDocker/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/buildWithDocker/action.yml b/.github/actions/buildWithDocker/action.yml index 78191f38..5f06be47 100644 --- a/.github/actions/buildWithDocker/action.yml +++ b/.github/actions/buildWithDocker/action.yml @@ -8,6 +8,6 @@ inputs: default: 'act' runs: using: 'docker' - image: 'Build/Dockerfile' + image: '../../../Build/Dockerfile' args: - ${{ inputs.command }} From 781e0efa67d7efe01f3e9884407bc113531f553e Mon Sep 17 00:00:00 2001 From: Martin Weismann <martin.weismann@autodesk.com> Date: Thu, 25 Aug 2022 12:49:07 +0200 Subject: [PATCH 141/143] Copy act.linux64 to act.linux --- Build/build.bat | 1 + Build/build.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/Build/build.bat b/Build/build.bat index a29fc1e2..d3f21a56 100644 --- a/Build/build.bat +++ b/Build/build.bat @@ -55,5 +55,6 @@ echo "Build act.arm.linux64" go build -o ..\act.arm.linux64 %Sources% copy ..\act.win64.exe ..\act.exe /Y +copy ..\act.linux64 ..\act.linux /Y cd %startingDir% diff --git a/Build/build.sh b/Build/build.sh index e2e7e8cd..5d4b9e49 100755 --- a/Build/build.sh +++ b/Build/build.sh @@ -22,6 +22,7 @@ echo "Build act.linux64" export GOOS="linux" export GOARCH="amd64" go build -o ../act.linux64 $Sources +cp ../act.linux64 ../act.linux echo "Build act.linux32" export GOOS="linux" From 2dae7f9b3c728fd73146f4ac9427f77eabf064ec Mon Sep 17 00:00:00 2001 From: Martin Weismann <martin.weismann@autodesk.com> Date: Thu, 25 Aug 2022 13:26:28 +0200 Subject: [PATCH 142/143] Make Build/build.sh exectuable --- Build/build.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 Build/build.sh diff --git a/Build/build.sh b/Build/build.sh old mode 100644 new mode 100755 From b558b922b460a284c1116a7876fa5ce5ffafd5e6 Mon Sep 17 00:00:00 2001 From: Martin Weismann <martin.weismann@autodesk.com> Date: Thu, 25 Aug 2022 13:36:47 +0200 Subject: [PATCH 143/143] Finish merge of build.bat --- Build/build.bat | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/Build/build.bat b/Build/build.bat index a0e721cf..9298216f 100644 --- a/Build/build.bat +++ b/Build/build.bat @@ -4,7 +4,6 @@ set basepath="%~dp0" cd %basepath%\..\Source set Sources=actutils.go automaticcomponenttoolkit.go buildbindingccpp.go buildbindingccppdocumentation.go buildbindingcsharp.go buildbindinggo.go buildbindingnode.go buildbindingpascal.go buildbindingpython.go buildimplementationcpp.go buildbindingjava.go buildimplementationpascal.go componentdefinition.go componentdiff.go languagewriter.go languagec.go languagecpp.go languagepascal.go -<<<<<<< HEAD set GOOS=windows set GOARCH=amd64 @@ -12,31 +11,15 @@ echo "Build act.win64.exe" go build -o ..\act.win64.exe %Sources% echo "Patching properties of act.win64.exe" -..\build\verpatch ..\act.win64.exe /high /va 1.7.0 /pv "1.7.0-develop" /s copyright "(c) 2018-2019 ACT Developers" /s desc "ACT is a code generator for software components" /s productName "Automatic Component Toolkit" +..\build\verpatch ..\act.win64.exe /high /va 1.8.0 /pv "1.8.0-develop" /s copyright "(c) 2018-2019 ACT Developers" /s desc "ACT is a code generator for software components" /s productName "Automatic Component Toolkit" set GOOS=windows -======= - -set GOOS=windows -set GOARCH=amd64 -echo "Build act.exe" -go build -o ..\act.win64.exe %Sources% - -echo "Patching properties of act.win64.exe" -..\build\verpatch ..\act.win64.exe /high /va 1.7.0 /pv "1.7.0-develop" /s copyright "(c) 2018-2019 ACT Developers" /s desc "ACT is a code generator for software components" /s productName "Automatic Component Toolkit" - -set GOOS=windows ->>>>>>> ADSK/develop set GOARCH=386 echo "Build act.win32.exe" go build -o ..\act.win32.exe %Sources% -<<<<<<< HEAD echo "Patching properties of act.win32.exe" -======= -echo "Patching properties of act_win32.exe" ->>>>>>> ADSK/develop -..\build\verpatch ..\act.win32.exe /high /va 1.7.0 /pv "1.7.0-develop" /s copyright "(c) 2018-2019 ACT Developers" /s desc "ACT is a code generator for software components" /s productName "Automatic Component Toolkit" +..\build\verpatch ..\act.win32.exe /high /va 1.8.0 /pv "1.8.0-develop" /s copyright "(c) 2018-2019 ACT Developers" /s desc "ACT is a code generator for software components" /s productName "Automatic Component Toolkit" set GOOS=linux set GOARCH=amd64