diff --git a/.github/actions/buildWithDocker/action.yml b/.github/actions/buildWithDocker/action.yml new file mode 100644 index 00000000..5f06be47 --- /dev/null +++ b/.github/actions/buildWithDocker/action.yml @@ -0,0 +1,13 @@ +# action.yml +name: 'BuildWithDocker' +description: 'Build ACT within a Docker container' +inputs: + command: # id of input + description: 'What command to run' + required: true + default: 'act' +runs: + using: 'docker' + image: '../../../Build/Dockerfile' + args: + - ${{ inputs.command }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 43954297..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 @@ -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/.github/workflows/build_examples.yml b/.github/workflows/build_examples.yml new file mode 100644 index 00000000..42624a20 --- /dev/null +++ b/.github/workflows/build_examples.yml @@ -0,0 +1,19 @@ +on: [push, pull_request] +name: Build ACT examples +jobs: + build_with_docker: + runs-on: ubuntu-latest + name: Build ACT examples with docker + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: build act + id: build_act + uses: ./.github/actions/buildWithDocker + with: + command: 'act' + - name: build examples + id: build_examples + uses: ./.github/actions/buildWithDocker + with: + command: 'examples' diff --git a/.gitignore b/.gitignore index 5aa2ab2f..f9b9a402 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,28 @@ -*.cpp -*.hpp -*.h *.exe *.linux *.linux32 *.linux64 *.darwin *.exe +*.dylib +*.so +*.dll *.arm -*.c -*.go *.orig +*.class +*.jar +*.log +*.o +*.ppu +__pycache__ + +Examples/**/build +Examples/**/build-* +Examples/**/bin +Examples/**/obj # Visual Studio Code debug .vscode -*_headers -*_component - -Examples/*.xml +.DS_Store \ No newline at end of file diff --git a/Build/Dockerfile b/Build/Dockerfile new file mode 100644 index 00000000..7e6c3641 --- /dev/null +++ b/Build/Dockerfile @@ -0,0 +1,87 @@ +FROM centos:centos8 + +ARG USER_ID +ARG GROUP_ID + +LABEL maintainer="Andrii Anpilogov (andrii.anpilogov@autodesk.com)" + +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 + +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 +# 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) + +# 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 + +# # Initialize Toolkit +RUN echo "source /opt/rh/gcc-toolset-9/enable" >> /etc/bashrc +ENV PATH="${PATH}:/opt/go/bin" + +# 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.}" + +# 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 + +# 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/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) | diff --git a/Build/build.bat b/Build/build.bat index 49a6a27d..9298216f 100644 --- a/Build/build.bat +++ b/Build/build.bat @@ -7,19 +7,19 @@ 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" -..\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 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" +echo "Patching properties of act.win32.exe" +..\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 @@ -38,21 +38,23 @@ 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% set GOOS=linux set GOARCH=arm set GOARM=5 -echo "Build act.linux32.arm" -go build -o ..\act.linux32.arm %Sources% +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 +copy ..\act.linux64 ..\act.linux /Y + cd %startingDir% diff --git a/Build/build.inc b/Build/build.inc new file mode 100644 index 00000000..a4a18347 --- /dev/null +++ b/Build/build.inc @@ -0,0 +1,54 @@ +#!/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= + 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/Build/build.sh b/Build/build.sh old mode 100644 new mode 100755 index e4ba1ad4..5d4b9e49 --- a/Build/build.sh +++ b/Build/build.sh @@ -1,38 +1,55 @@ #!/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 +cp ../act.linux64 ../act.linux -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 GOARM="5" 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.arm.linux32" export GOOS="linux" -export GOARCH="arm" export GOARM="5" -go build -o ../act.arm.linux $Sources +export GOARCH="386" +go build -o ../act.arm.linux32 $Sources + +echo "Build act.arm.linux64" +export GOOS="linux" +export GOARCH="arm64" +export GOARM="5" +go build -o ../act.arm.linux64 $Sources cd "$startingpath" diff --git a/Build/docker.sh b/Build/docker.sh new file mode 100755 index 00000000..97e384e9 --- /dev/null +++ b/Build/docker.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" + +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 --user $(id -u):$(id -g) --entrypoint /data/Build/build.sh act-build + ;; + examples) + 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 --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 --user $(id -u):$(id -g) --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/Documentation/IDL.md b/Documentation/IDL.md index f0faa3bc..2a9b8447 100644 --- a/Documentation/IDL.md +++ b/Documentation/IDL.md @@ -183,6 +183,7 @@ Element **\** 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 \ within the \ 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 \ within the \ 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 \ within baseclassname \ 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 \ within the \ 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"`. diff --git a/Examples/Injection/Calculation.xml b/Examples/Injection/Calculation.xml index 6c8eedce..b75f88b9 100644 --- a/Examples/Injection/Calculation.xml +++ b/Examples/Injection/Calculation.xml @@ -15,6 +15,7 @@ + @@ -33,6 +34,9 @@ + + + @@ -62,7 +66,7 @@ versionmethod="GetVersion" errormethod="GetLastError" injectionmethod="InjectComponent" symbollookupmethod="GetSymbolLookupMethod" - > + classtypeidmethod="ClassTypeId"> 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..16979853 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 #endif // _WIN32 +#include #include #include #include @@ -62,6 +63,33 @@ typedef PBase PCalculationBase; typedef PCalculator PCalculationCalculator; +/************************************************************************************************************************* + 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()) + { + } + + 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& vec) + explicit CInputVector( const std::vector& vec) : m_data( vec.data() ), m_size( vec.size() ) { } @@ -164,12 +240,14 @@ 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 pInstance, std::string & sErrorMessage); + inline void ReleaseInstance(classParam pInstance); + inline void AcquireInstance(classParam pInstance); inline void InjectComponent(const std::string & sNameSpace, const Calculation_pvoid pSymbolAddressMethod); inline Calculation_pvoid GetSymbolLookupMethod(); + inline CBase* polymorphicFactory(CalculationHandle); + private: // Injected Components Numbers::PWrapper m_pNumbersWrapper; @@ -179,7 +257,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 +307,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 +340,34 @@ class CCalculator : public CBase { { } - inline void EnlistVariable(Numbers::CVariable * pVariable); + inline void EnlistVariable(Numbers::classParam 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. +*/ +inline CBase* CWrapper::polymorphicFactory(CalculationHandle pHandle) +{ + Calculation_uint64 resultClassTypeId = 0; + CheckError(nullptr, calculation_base_classtypeid(pHandle, &resultClassTypeId)); + switch(resultClassTypeId) { + 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 new CBase(this, pHandle); +} /** * CWrapper::CreateCalculator - Creates a new Calculator instance @@ -272,7 +381,7 @@ class CCalculator : public CBase { if (!hInstance) { CheckError(nullptr,CALCULATION_ERROR_INVALIDPARAM); } - return std::make_shared(this, hInstance); + return std::shared_ptr(dynamic_cast(this->polymorphicFactory(hInstance))); } /** @@ -292,12 +401,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 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 +419,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 pInstance) { - CalculationHandle hInstance = nullptr; - if (pInstance != nullptr) { - hInstance = pInstance->GetHandle(); - }; + CalculationHandle hInstance = pInstance.GetHandle(); CheckError(nullptr,calculation_releaseinstance(hInstance)); } @@ -326,12 +429,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 pInstance) { - CalculationHandle hInstance = nullptr; - if (pInstance != nullptr) { - hInstance = pInstance->GetHandle(); - }; + CalculationHandle hInstance = pInstance.GetHandle(); CheckError(nullptr,calculation_acquireinstance(hInstance)); } @@ -385,6 +485,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 +505,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 pVariable) { - NumbersHandle hVariable = nullptr; - if (pVariable != nullptr) { - hVariable = pVariable->GetHandle(); - }; + NumbersHandle hVariable = pVariable.GetHandle(); CheckError(calculation_calculator_enlistvariable(m_pHandle, hVariable)); } @@ -409,13 +518,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(m_pWrapper->m_pNumbersWrapper.get(), hVariable); + return std::shared_ptr(dynamic_cast(m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory(hVariable))); } /** @@ -432,13 +541,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(m_pWrapper->m_pNumbersWrapper.get(), hInstance); + return std::shared_ptr(dynamic_cast(m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory(hInstance))); } /** @@ -447,13 +556,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(m_pWrapper->m_pNumbersWrapper.get(), hInstance); + return std::shared_ptr(dynamic_cast(m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory(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..2c3c0eb6 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 #endif // _WIN32 +#include #include #include #include @@ -62,6 +63,33 @@ typedef PBase PCalculationBase; typedef PCalculator PCalculationCalculator; +/************************************************************************************************************************* + 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()) + { + } + + 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& vec) + explicit CInputVector( const std::vector& vec) : m_data( vec.data() ), m_size( vec.size() ) { } @@ -148,7 +224,7 @@ using CCalculationInputVector = CInputVector; 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,14 @@ 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 pInstance, std::string & sErrorMessage); + inline void ReleaseInstance(classParam pInstance); + inline void AcquireInstance(classParam pInstance); inline void InjectComponent(const std::string & sNameSpace, const Calculation_pvoid pSymbolAddressMethod); inline Calculation_pvoid GetSymbolLookupMethod(); + inline CBase* polymorphicFactory(CalculationHandle); + private: sCalculationDynamicWrapperTable m_WrapperTable; // Injected Components @@ -199,7 +277,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 +331,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 +364,34 @@ class CCalculator : public CBase { { } - inline void EnlistVariable(Numbers::CVariable * pVariable); + inline void EnlistVariable(Numbers::classParam 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. +*/ +inline CBase* CWrapper::polymorphicFactory(CalculationHandle pHandle) +{ + Calculation_uint64 resultClassTypeId = 0; + CheckError(nullptr, m_WrapperTable.m_Base_ClassTypeId(pHandle, &resultClassTypeId)); + switch(resultClassTypeId) { + 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 new CBase(this, pHandle); +} /** * CWrapper::CreateCalculator - Creates a new Calculator instance @@ -296,7 +405,7 @@ class CCalculator : public CBase { if (!hInstance) { CheckError(nullptr,CALCULATION_ERROR_INVALIDPARAM); } - return std::make_shared(this, hInstance); + return std::shared_ptr(dynamic_cast(this->polymorphicFactory(hInstance))); } /** @@ -316,12 +425,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 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 +443,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 pInstance) { - CalculationHandle hInstance = nullptr; - if (pInstance != nullptr) { - hInstance = pInstance->GetHandle(); - }; + CalculationHandle hInstance = pInstance.GetHandle(); CheckError(nullptr,m_WrapperTable.m_ReleaseInstance(hInstance)); } @@ -350,12 +453,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 pInstance) { - CalculationHandle hInstance = nullptr; - if (pInstance != nullptr) { - hInstance = pInstance->GetHandle(); - }; + CalculationHandle hInstance = pInstance.GetHandle(); CheckError(nullptr,m_WrapperTable.m_AcquireInstance(hInstance)); } @@ -410,6 +510,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 +554,7 @@ class CCalculator : 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); @@ -470,6 +571,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 +704,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 +765,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 +785,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 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 +798,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(m_pWrapper->m_pNumbersWrapper.get(), hVariable); + return std::shared_ptr(dynamic_cast(m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory(hVariable))); } /** @@ -698,13 +821,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(m_pWrapper->m_pNumbersWrapper.get(), hInstance); + return std::shared_ptr(dynamic_cast(m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory(hInstance))); } /** @@ -713,13 +836,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(m_pWrapper->m_pNumbersWrapper.get(), hInstance); + return std::shared_ptr(dynamic_cast(m_pWrapper->m_pNumbersWrapper.get()->polymorphicFactory(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/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 ErrorCodeMap = new HashMap(); + public static final Map ErrorDescriptionMap = new HashMap(); + + 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 PolymorphicFactory(Pointer handle, Class 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/Bindings/Pascal/Unit_Calculation.pas b/Examples/Injection/Calculation_component/Bindings/Pascal/Unit_Calculation.pas index e4db83b1..e5ee03d6 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,48 @@ TCalculationWrapper = class(TObject) function GetSymbolLookupMethod(): Pointer; end; + 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 +(************************************************************************************************************************* + 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; + function TCalculationPolymorphicFactoryMakeBase(Wrapper: TCalculationWrapper; Handle: TCalculationHandle): TCALCULATIONBase; + begin + Result := TCalculationPolymorphicFactory.Make(Wrapper, Handle); + end; + function TCalculationPolymorphicFactoryMakeCalculator(Wrapper: TCalculationWrapper; Handle: TCalculationHandle): TCALCULATIONCalculator; + begin + Result := TCalculationPolymorphicFactory.Make(Wrapper, Handle); + end; + (************************************************************************************************************************* Exception implementation **************************************************************************************************************************) @@ -373,6 +423,11 @@ implementation inherited; end; + function TCalculationBase.ClassTypeId(): QWord; + begin + FWrapper.CheckError(Self, FWrapper.CalculationBase_ClassTypeIdFunc(FHandle, Result)); + end; + (************************************************************************************************************************* Class implementation for Calculator **************************************************************************************************************************) @@ -389,7 +444,7 @@ implementation procedure TCalculationCalculator.EnlistVariable(const AVariable: TNumbersVariable); var - AVariableHandle: TCalculationHandle; + AVariableHandle: TNumbersHandle; begin if Assigned(AVariable) then AVariableHandle := AVariable.TheHandle @@ -400,13 +455,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 := TNumbersPolymorphicFactoryMakeVariable(FWrapper.NumbersWrapper, HVariable); end; procedure TCalculationCalculator.ClearVariables(); @@ -416,24 +471,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 := TNumbersPolymorphicFactoryMakeVariable(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 := TNumbersPolymorphicFactoryMakeVariable(FWrapper.NumbersWrapper, HInstance); end; (************************************************************************************************************************* @@ -459,6 +514,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 +539,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 +651,7 @@ implementation HInstance := nil; CheckError(nil, CalculationCreateCalculatorFunc(HInstance)); if Assigned(HInstance) then - Result := TCalculationCalculator.Create(Self, HInstance); + Result := TCalculationPolymorphicFactory.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/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/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/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/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/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/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); 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..46928434 --- /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 -fPIC -T$FPC_TARGET -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/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..95ffc645 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 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 **************************************************************************************************************************/ @@ -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,15 @@ typedef IBaseSharedPtr 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 + { + return 0xB23F514353D0C606UL; // First 64 bits of SHA1 of a string: "Calculation::Calculator" + } + /** * 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 +294,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(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 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/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/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/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/build.sh b/Examples/Injection/Calculation_component/Implementations/Pascal/build.sh new file mode 100755 index 00000000..874d254d --- /dev/null +++ b/Examples/Injection/Calculation_component/Implementations/Pascal/build.sh @@ -0,0 +1,12 @@ +#!/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 -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/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.xml b/Examples/Injection/Numbers.xml index dc186540..bead17f0 100644 --- a/Examples/Injection/Numbers.xml +++ b/Examples/Injection/Numbers.xml @@ -10,6 +10,7 @@ + @@ -28,6 +29,9 @@ + + + @@ -42,7 +46,8 @@ + symbollookupmethod="GetSymbolLookupMethod" + classtypeidmethod="ClassTypeId"> 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..21a749ae 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 #endif // _WIN32 +#include #include #include #include @@ -61,6 +62,33 @@ typedef PBase PNumbersBase; typedef PVariable PNumbersVariable; +/************************************************************************************************************************* + 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()) + { + } + + 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& vec) + explicit CInputVector( const std::vector& vec) : m_data( vec.data() ), m_size( vec.size() ) { } @@ -147,7 +223,7 @@ using CNumbersInputVector = CInputVector; 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,13 @@ 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 pInstance, std::string & sErrorMessage); + inline void ReleaseInstance(classParam pInstance); + inline void AcquireInstance(classParam pInstance); inline Numbers_pvoid GetSymbolLookupMethod(); + inline CBase* polymorphicFactory(NumbersHandle); + private: sNumbersDynamicWrapperTable m_WrapperTable; @@ -194,7 +272,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 +326,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 +362,28 @@ 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. +*/ +inline CBase* CWrapper::polymorphicFactory(NumbersHandle pHandle) +{ + Numbers_uint64 resultClassTypeId = 0; + CheckError(nullptr, m_WrapperTable.m_Base_ClassTypeId(pHandle, &resultClassTypeId)); + switch(resultClassTypeId) { + 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 new CBase(this, pHandle); +} /** * CWrapper::CreateVariable - Creates a new Variable instance @@ -289,7 +398,7 @@ class CVariable : public CBase { if (!hInstance) { CheckError(nullptr,NUMBERS_ERROR_INVALIDPARAM); } - return std::make_shared(this, hInstance); + return std::shared_ptr(dynamic_cast(this->polymorphicFactory(hInstance))); } /** @@ -309,12 +418,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 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 +436,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 pInstance) { - NumbersHandle hInstance = nullptr; - if (pInstance != nullptr) { - hInstance = pInstance->GetHandle(); - }; + NumbersHandle hInstance = pInstance.GetHandle(); CheckError(nullptr,m_WrapperTable.m_ReleaseInstance(hInstance)); } @@ -343,12 +446,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 pInstance) { - NumbersHandle hInstance = nullptr; - if (pInstance != nullptr) { - hInstance = pInstance->GetHandle(); - }; + NumbersHandle hInstance = pInstance.GetHandle(); CheckError(nullptr,m_WrapperTable.m_AcquireInstance(hInstance)); } @@ -382,6 +482,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 +522,7 @@ class CVariable : 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); @@ -438,6 +539,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 +636,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 +681,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/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 ErrorCodeMap = new HashMap(); + public static final Map ErrorDescriptionMap = new HashMap(); + + 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 PolymorphicFactory(Pointer handle, Class 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/Numbers_component/Bindings/Pascal/Unit_Numbers.pas b/Examples/Injection/Numbers_component/Bindings/Pascal/Unit_Numbers.pas index 106bf41e..6c995006 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,48 @@ TNumbersWrapper = class(TObject) function GetSymbolLookupMethod(): Pointer; end; + 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 +(************************************************************************************************************************* + 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; + function TNumbersPolymorphicFactoryMakeBase(Wrapper: TNumbersWrapper; Handle: TNumbersHandle): TNUMBERSBase; + begin + Result := TNumbersPolymorphicFactory.Make(Wrapper, Handle); + end; + function TNumbersPolymorphicFactoryMakeVariable(Wrapper: TNumbersWrapper; Handle: TNumbersHandle): TNUMBERSVariable; + begin + Result := TNumbersPolymorphicFactory.Make(Wrapper, Handle); + end; + (************************************************************************************************************************* Exception implementation **************************************************************************************************************************) @@ -316,6 +366,11 @@ implementation inherited; end; + function TNumbersBase.ClassTypeId(): QWord; + begin + FWrapper.CheckError(Self, FWrapper.NumbersBase_ClassTypeIdFunc(FHandle, Result)); + end; + (************************************************************************************************************************* Class implementation for Variable **************************************************************************************************************************) @@ -362,6 +417,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 +437,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 +529,7 @@ implementation HInstance := nil; CheckError(nil, NumbersCreateVariableFunc(AInitialValue, HInstance)); if Assigned(HInstance) then - Result := TNumbersVariable.Create(Self, HInstance); + Result := TNumbersPolymorphicFactory.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/Examples/.gitignore b/Examples/Injection/Numbers_component/Examples/.gitignore new file mode 100644 index 00000000..f59ec20a --- /dev/null +++ b/Examples/Injection/Numbers_component/Examples/.gitignore @@ -0,0 +1 @@ +* \ No newline at end of file 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..c1cc9128 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 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 { @@ -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,20 @@ typedef IBaseSharedPtr 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 + { + return 0x23934EDF762423EAUL; // First 64 bits of SHA1 of a string: "Numbers::Variable" + } + /** * IVariable::GetValue - Returns the current value of this Variable * @return The current value of this Variable @@ -198,6 +273,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(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 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/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/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. 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/build.sh b/Examples/Injection/Numbers_component/Implementations/Pascal/build.sh new file mode 100755 index 00000000..52913406 --- /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 -fPIC -T$FPC_TARGET -FU./build -o./build/numbers$OSLIBEXT Interfaces/numbers.lpr 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. + + diff --git a/Examples/Injection/build.sh b/Examples/Injection/build.sh new file mode 100755 index 00000000..97ce415c --- /dev/null +++ b/Examples/Injection/build.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../Build/build.inc + +echo "Generate IDL" +../../$ACT Numbers.xml -suppressexamples +../../$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 +./Calculation_component/Examples/Java9/build.sh + +echo "Build and test are done and successful" \ No newline at end of file diff --git a/Examples/RTTI/RTTI.xml b/Examples/RTTI/RTTI.xml new file mode 100644 index 00000000..a564949d --- /dev/null +++ b/Examples/RTTI/RTTI.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 +#else // _WIN32 +#include +#include +#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(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..d8990f06 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.cc @@ -0,0 +1,226 @@ +/*++ + +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 +#else // _WIN32 +#include +#include +#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_AnimalIterator_GetNextOptinalAnimal = NULL; + pWrapperTable->m_AnimalIterator_GetNextMandatoryAnimal = 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(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_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 + 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..3a33db2b --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_dynamic.h @@ -0,0 +1,226 @@ +/*++ + +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); + +/** +* 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 +**************************************************************************************************************************/ + +/** +* 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; + PRTTIAnimalIterator_GetNextOptinalAnimalPtr m_AnimalIterator_GetNextOptinalAnimal; + PRTTIAnimalIterator_GetNextMandatoryAnimalPtr m_AnimalIterator_GetNextMandatoryAnimal; + 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..000a5b65 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/CDynamic/rtti_types.h @@ -0,0 +1,121 @@ +/*++ + +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 + +/************************************************************************************************************************* + 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 /** 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; + + +#endif // __RTTI_TYPES_HEADER 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..b963dd11 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/CSharp/RTTI.cs @@ -0,0 +1,350 @@ +using System; +using System.Text; +using System.Runtime.InteropServices; + +namespace RTTI { + + + namespace Internal { + + + public class RTTIWrapper + { + [DllImport("rtti.dll", EntryPoint = "rtti_base_classtypeid", CallingConvention=CallingConvention.Cdecl)] + 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 (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 (IntPtr Handle); + + [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); + + [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 (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 (IntPtr AInstance); + + [DllImport("rtti.dll", EntryPoint = "rtti_acquireinstance", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] + 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); + + [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 IntPtr AInstance); + + public static void ThrowError(IntPtr Handle, Int32 errorCode) + { + String sMessage = "RTTI 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 + * 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(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 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 IntPtr Handle; + + public CBase (IntPtr NewHandle) + { + Handle = NewHandle; + } + + ~CBase () + { + if (Handle != IntPtr.Zero) { + Internal.RTTIWrapper.ReleaseInstance (Handle); + Handle = IntPtr.Zero; + } + } + + protected void CheckError (Int32 errorCode) + { + if (errorCode != 0) { + Internal.RTTIWrapper.ThrowError (Handle, errorCode); + } + } + + public IntPtr 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 (IntPtr 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 (IntPtr NewHandle) : base (NewHandle) + { + } + + } + + public class CReptile : CAnimal + { + public CReptile (IntPtr NewHandle) : base (NewHandle) + { + } + + } + + public class CGiraffe : CMammal + { + public CGiraffe (IntPtr NewHandle) : base (NewHandle) + { + } + + } + + public class CTiger : CMammal + { + public CTiger (IntPtr NewHandle) : base (NewHandle) + { + } + + public void Roar () + { + + CheckError(Internal.RTTIWrapper.Tiger_Roar (Handle)); + } + + } + + public class CSnake : CReptile + { + public CSnake (IntPtr NewHandle) : base (NewHandle) + { + } + + } + + public class CTurtle : CReptile + { + public CTurtle (IntPtr NewHandle) : base (NewHandle) + { + } + + } + + public class CAnimalIterator : CBase + { + public CAnimalIterator (IntPtr NewHandle) : base (NewHandle) + { + } + + public CAnimal GetNextAnimal () + { + IntPtr newAnimal = IntPtr.Zero; + + CheckError(Internal.RTTIWrapper.AnimalIterator_GetNextAnimal (Handle, out newAnimal)); + return Internal.RTTIWrapper.PolymorphicFactory(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(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(newAnimal); + return (resultError != 0); + } + + } + + public class CZoo : CBase + { + public CZoo (IntPtr NewHandle) : base (NewHandle) + { + } + + public CAnimalIterator Iterator () + { + IntPtr newIterator = IntPtr.Zero; + + CheckError(Internal.RTTIWrapper.Zoo_Iterator (Handle, out newIterator)); + return Internal.RTTIWrapper.PolymorphicFactory(newIterator); + } + + } + + class Wrapper + { + private static void CheckError (Int32 errorCode) + { + if (errorCode != 0) { + Internal.RTTIWrapper.ThrowError (IntPtr.Zero, 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 () + { + IntPtr newInstance = IntPtr.Zero; + + CheckError(Internal.RTTIWrapper.CreateZoo (out newInstance)); + return Internal.RTTIWrapper.PolymorphicFactory(newInstance); + } + + } + +} 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..8654ffee --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_abi.hpp @@ -0,0 +1,214 @@ +/*++ + +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); + +/** +* 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 +**************************************************************************************************************************/ + +/** +* 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..8d89403d --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_implicit.hpp @@ -0,0 +1,797 @@ +/*++ + +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 +#else // _WIN32 +#include +#endif // _WIN32 +#include +#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; + 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 +class CInputVector { +private: + + const T* m_data; + size_t m_size; + +public: + + explicit 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() + { + } + + ~CWrapper() + { + } + static inline PWrapper loadLibrary() + { + return std::make_shared(); + } + + 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(); + + inline CBase* polymorphicFactory(RTTIHandle); + +private: + + RTTIResult checkBinaryVersion() + { + RTTI_uint32 nMajor, nMinor, nMicro; + GetVersion(nMajor, nMinor, nMicro); + if (nMajor != RTTI_VERSION_MAJOR) { + return RTTI_ERROR_INCOMPATIBLEBINARYVERSION; + } + return RTTI_SUCCESS; + } + + 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(); + inline bool GetNextOptinalAnimal(PAnimal & pAnimal); + inline bool GetNextMandatoryAnimal(PAnimal & pAnimal); +}; + +/************************************************************************************************************************* + 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 +**************************************************************************************************************************/ + +/** +* 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. +*/ +inline CBase* CWrapper::polymorphicFactory(RTTIHandle pHandle) +{ + RTTI_uint64 resultClassTypeId = 0; + CheckError(nullptr, rtti_base_classtypeid(pHandle, &resultClassTypeId)); + switch(resultClassTypeId) { + 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); +} + + /** + * 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 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 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 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 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 = nullptr; + CheckError(nullptr,rtti_createzoo(&hInstance)); + + if (!hInstance) { + CheckError(nullptr,RTTI_ERROR_INVALIDPARAM); + } + return std::shared_ptr(dynamic_cast(this->polymorphicFactory(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 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 = nullptr; + CheckError(rtti_animaliterator_getnextanimal(m_pHandle, &hAnimal)); + + if (hAnimal) { + return std::shared_ptr(dynamic_cast(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(dynamic_cast(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(dynamic_cast(m_pWrapper->polymorphicFactory(hAnimal))); + } else { + pAnimal = nullptr; + } + + return resultError; + } + + /** + * Method definitions for class CZoo + */ + + /** + * CZoo::Iterator - Return an iterator over all zoo animals + * @return + */ + PAnimalIterator CZoo::Iterator() + { + RTTIHandle hIterator = nullptr; + CheckError(rtti_zoo_iterator(m_pHandle, &hIterator)); + + if (!hIterator) { + CheckError(RTTI_ERROR_INVALIDPARAM); + } + return std::shared_ptr(dynamic_cast(m_pWrapper->polymorphicFactory(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..cc0455f9 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Cpp/rtti_types.hpp @@ -0,0 +1,125 @@ +/*++ + +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 + +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 /** 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 { + +} // 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/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/Bindings/CppDynamic/rtti_dynamic.h b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h new file mode 100644 index 00000000..3a1feb7d --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.h @@ -0,0 +1,219 @@ +/*++ + +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_DYNAMICHEADER_CPPTYPES +#define __RTTI_DYNAMICHEADER_CPPTYPES + +#include "rtti_types.hpp" + + + +/************************************************************************************************************************* + 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); + +/** +* 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 +**************************************************************************************************************************/ + +/** +* 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; + PRTTIAnimalIterator_GetNextOptinalAnimalPtr m_AnimalIterator_GetNextOptinalAnimal; + PRTTIAnimalIterator_GetNextMandatoryAnimalPtr m_AnimalIterator_GetNextMandatoryAnimal; + 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..9def3475 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_dynamic.hpp @@ -0,0 +1,1091 @@ +/*++ + +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_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 +#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; + 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 +class CInputVector { +private: + + const T* m_data; + size_t m_size; + +public: + + explicit 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: + + explicit CWrapper(void* pSymbolLookupMethod) + { + CheckError(nullptr, initWrapperTable(&m_WrapperTable)); + CheckError(nullptr, loadWrapperTableFromSymbolLookupMethod(&m_WrapperTable, pSymbolLookupMethod)); + + CheckError(nullptr, checkBinaryVersion()); + } + + explicit 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(); + + inline CBase* polymorphicFactory(RTTIHandle); + +private: + sRTTIDynamicWrapperTable m_WrapperTable; + + RTTIResult checkBinaryVersion() + { + RTTI_uint32 nMajor, nMinor, nMicro; + GetVersion(nMajor, nMinor, nMicro); + if (nMajor != RTTI_VERSION_MAJOR) { + 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; + 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(); + inline bool GetNextOptinalAnimal(PAnimal & pAnimal); + inline bool GetNextMandatoryAnimal(PAnimal & pAnimal); +}; + +/************************************************************************************************************************* + 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 +**************************************************************************************************************************/ + +/** +* 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. +*/ +inline CBase* CWrapper::polymorphicFactory(RTTIHandle pHandle) +{ + RTTI_uint64 resultClassTypeId = 0; + CheckError(nullptr, m_WrapperTable.m_Base_ClassTypeId(pHandle, &resultClassTypeId)); + switch(resultClassTypeId) { + 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); +} + + /** + * 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::shared_ptr(dynamic_cast(this->polymorphicFactory(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_Base_ClassTypeId = nullptr; + 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; + 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 = 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); + 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_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 + 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 + 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_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 + 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_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; + + 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_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; + + 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 + */ + + /** + * 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 + */ + + /** + * 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 + */ + + /** + * 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::shared_ptr(dynamic_cast(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(dynamic_cast(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(dynamic_cast(m_pWrapper->polymorphicFactory(hAnimal))); + } else { + pAnimal = nullptr; + } + + return resultError; + } + + /** + * 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::shared_ptr(dynamic_cast(m_pWrapper->polymorphicFactory(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..cc0455f9 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/CppDynamic/rtti_types.hpp @@ -0,0 +1,125 @@ +/*++ + +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 + +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 /** 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 { + +} // 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/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..66502bde --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Go/rtti.go @@ -0,0 +1,563 @@ +/*++ + +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 + +/* +#cgo linux LDFLAGS: -ldl +#include "rtti_dynamic.cc" + +RTTIHandle 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 (RTTIHandle) pWrapperTable; + } +} + +void unloadRTTILibrary (RTTIHandle nLibraryHandle) +{ + sRTTIDynamicWrapperTable * pWrapperTable = (sRTTIDynamicWrapperTable *) malloc (sizeof (sRTTIDynamicWrapperTable)); + if (pWrapperTable != NULL) { + ReleaseRTTIWrapperTable (pWrapperTable); + free (pWrapperTable); + } +} + + +RTTIResult CCall_rtti_base_classtypeid(RTTIHandle 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(RTTIHandle 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(RTTIHandle 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(RTTIHandle 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_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) + return RTTI_ERROR_INVALIDCAST; + sRTTIDynamicWrapperTable * wrapperTable = (sRTTIDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_Zoo_Iterator (pZoo, pIterator); +} + + +RTTIResult CCall_rtti_getversion(RTTIHandle 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(RTTIHandle 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(RTTIHandle libraryHandle, RTTI_Base pInstance) +{ + if (libraryHandle == 0) + return RTTI_ERROR_INVALIDCAST; + sRTTIDynamicWrapperTable * wrapperTable = (sRTTIDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_ReleaseInstance (pInstance); +} + + +RTTIResult CCall_rtti_acquireinstance(RTTIHandle libraryHandle, RTTI_Base pInstance) +{ + if (libraryHandle == 0) + return RTTI_ERROR_INVALIDCAST; + sRTTIDynamicWrapperTable * wrapperTable = (sRTTIDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_AcquireInstance (pInstance); +} + + +RTTIResult CCall_rtti_injectcomponent(RTTIHandle 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(RTTIHandle libraryHandle, RTTI_pvoid * pSymbolLookupMethod) +{ + if (libraryHandle == 0) + return RTTI_ERROR_INVALIDCAST; + sRTTIDynamicWrapperTable * wrapperTable = (sRTTIDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_GetSymbolLookupMethod (pSymbolLookupMethod); +} + + +RTTIResult CCall_rtti_createzoo(RTTIHandle 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 + +// 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 ref +} + +// 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 = 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 != nil { + _animalPtrVal := inst.wrapperRef.NewAnimal(animal) + _animalPtr = &_animalPtrVal + } + 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 { + 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 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)) + } + return nil +} + +// GetSymbolLookupMethod returns the address of the SymbolLookupMethod. +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 uintptr(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 == 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..d8990f06 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Go/rtti_dynamic.cc @@ -0,0 +1,226 @@ +/*++ + +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 +#else // _WIN32 +#include +#include +#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_AnimalIterator_GetNextOptinalAnimal = NULL; + pWrapperTable->m_AnimalIterator_GetNextMandatoryAnimal = 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(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_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 + 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..3a33db2b --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Go/rtti_dynamic.h @@ -0,0 +1,226 @@ +/*++ + +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); + +/** +* 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 +**************************************************************************************************************************/ + +/** +* 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; + PRTTIAnimalIterator_GetNextOptinalAnimalPtr m_AnimalIterator_GetNextOptinalAnimal; + PRTTIAnimalIterator_GetNextMandatoryAnimalPtr m_AnimalIterator_GetNextMandatoryAnimal; + 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..000a5b65 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Go/rtti_types.h @@ -0,0 +1,121 @@ +/*++ + +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 + +/************************************************************************************************************************* + 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 /** 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; + + +#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 new file mode 100644 index 00000000..bab117af --- /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 ] || 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/* + +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..24855e07 --- /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, Pointer 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, 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, 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..fb16a6f0 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/AnimalIterator.java @@ -0,0 +1,120 @@ +/*++ + +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, Pointer handle) { + super(wrapper, handle); + } + + /** + * Return next animal + * + * @return + * @throws RTTIException + */ + public Animal getNextAnimal() throws RTTIException { + 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 (valueAnimal != Pointer.NULL) { + animal = mWrapper.PolymorphicFactory(valueAnimal, Animal.class); + } + 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/Base.java b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Base.java new file mode 100644 index 00000000..e907d446 --- /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 Pointer mHandle; + + protected RTTIWrapper mWrapper; + + public Base(RTTIWrapper 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 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})); + } 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, 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..8a67d287 --- /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, 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 new file mode 100644 index 00000000..5b1356b8 --- /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, Pointer 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 ErrorCodeMap = new HashMap(); + public static final Map ErrorDescriptionMap = new HashMap(); + + 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..eb9c0413 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/RTTIWrapper.java @@ -0,0 +1,343 @@ +/*++ + +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_animaliterator_getnextoptinalanimal; + protected Function rtti_animaliterator_getnextmandatoryanimal; + 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_animaliterator_getnextoptinalanimal = mLibrary.getFunction("rtti_animaliterator_getnextoptinalanimal"); + rtti_animaliterator_getnextmandatoryanimal = mLibrary.getFunction("rtti_animaliterator_getnextmandatoryanimal"); + 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_animaliterator_getnextoptinalanimal = loadFunctionByLookup(lookupMethod, "rtti_animaliterator_getnextoptinalanimal"); + rtti_animaliterator_getnextmandatoryanimal = loadFunctionByLookup(lookupMethod, "rtti_animaliterator_getnextmandatoryanimal"); + 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 { + Pointer instanceHandle = null; + if (instance != null) { + instanceHandle = instance.getHandle(); + } 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 { + Pointer instanceHandle = null; + if (instance != null) { + instanceHandle = instance.getHandle(); + } 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 { + Pointer instanceHandle = null; + if (instance != null) { + instanceHandle = instance.getHandle(); + } 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 { + Pointer bufferInstance = new Memory(8); + checkError(null, rtti_createzoo.invokeInt(new java.lang.Object[]{bufferInstance})); + Pointer valueInstance = bufferInstance.getPointer(0); + Zoo instance = null; + if (valueInstance == Pointer.NULL) { + throw new RTTIException(RTTIException.RTTI_ERROR_INVALIDPARAM, "Instance was a null pointer"); + } + instance = this.PolymorphicFactory(valueInstance, Zoo.class); + return instance; + } + + /** + * 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 PolymorphicFactory(Pointer handle, Class 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 0x08D007E7: + switch(lsbId) { + case 0xB5F7BAF4: obj = (T)(new Tiger(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Tiger" + } + 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 0x2262ABE8: + switch(lsbId) { + case 0x0A5E7878: obj = (T)(new Zoo(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Zoo" + } + 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 0x6756AA8E: + switch(lsbId) { + case 0xA5802EC3: obj = (T)(new Reptile(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Reptile" + } + 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; + 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 0x9751971B: + switch(lsbId) { + case 0xD2C2D958: obj = (T)(new Giraffe(this, handle)); break; // First 64 bits of SHA1 of a string: "RTTI::Giraffe" + } + break; + 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 0xF1917FE6: + switch(lsbId) { + 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; + } + 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..8a49ebe7 --- /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, 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 new file mode 100644 index 00000000..e2fc6e44 --- /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, Pointer 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..206e06e7 --- /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, Pointer 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})); + } + + +} + 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..157c4032 --- /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, 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 new file mode 100644 index 00000000..dd26d525 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Java9/rtti/Zoo.java @@ -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 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, Pointer handle) { + super(wrapper, handle); + } + + /** + * Return an iterator over all zoo animals + * + * @return + * @throws RTTIException + */ + public AnimalIterator iterator() throws RTTIException { + 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 (valueIterator == Pointer.NULL) { + throw new RTTIException(RTTIException.RTTI_ERROR_INVALIDPARAM, "Iterator was a null pointer"); + } + 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 new file mode 100644 index 00000000..8de38461 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Pascal/Unit_RTTI.pas @@ -0,0 +1,1032 @@ +{$IFDEF FPC}{$MODE DELPHI}{$ENDIF} +(*++ + +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 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; + + (** + * 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 +**************************************************************************************************************************) + + (** + * 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; + function GetNextOptinalAnimal(out AAnimal: TRTTIAnimal): Boolean; + function GetNextMandatoryAnimal(out AAnimal: TRTTIAnimal): Boolean; + 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; + FRTTIAnimalIterator_GetNextOptinalAnimalFunc: TRTTIAnimalIterator_GetNextOptinalAnimalFunc; + FRTTIAnimalIterator_GetNextMandatoryAnimalFunc: TRTTIAnimalIterator_GetNextMandatoryAnimalFunc; + 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 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; + 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; + 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 + + +(************************************************************************************************************************* + PolymorficFactory 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 + * 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; + function TRTTIPolymorphicFactoryMakeBase(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIBase; + begin + Result := TRTTIPolymorphicFactory.Make(Wrapper, Handle); + end; + function TRTTIPolymorphicFactoryMakeAnimal(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIAnimal; + begin + Result := TRTTIPolymorphicFactory.Make(Wrapper, Handle); + end; + function TRTTIPolymorphicFactoryMakeMammal(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIMammal; + begin + Result := TRTTIPolymorphicFactory.Make(Wrapper, Handle); + end; + function TRTTIPolymorphicFactoryMakeReptile(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIReptile; + begin + Result := TRTTIPolymorphicFactory.Make(Wrapper, Handle); + end; + function TRTTIPolymorphicFactoryMakeGiraffe(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIGiraffe; + begin + Result := TRTTIPolymorphicFactory.Make(Wrapper, Handle); + end; + function TRTTIPolymorphicFactoryMakeTiger(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTITiger; + begin + Result := TRTTIPolymorphicFactory.Make(Wrapper, Handle); + end; + function TRTTIPolymorphicFactoryMakeSnake(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTISnake; + begin + Result := TRTTIPolymorphicFactory.Make(Wrapper, Handle); + end; + function TRTTIPolymorphicFactoryMakeTurtle(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTITurtle; + begin + Result := TRTTIPolymorphicFactory.Make(Wrapper, Handle); + end; + function TRTTIPolymorphicFactoryMakeAnimalIterator(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIAnimalIterator; + begin + Result := TRTTIPolymorphicFactory.Make(Wrapper, Handle); + end; + function TRTTIPolymorphicFactoryMakeZoo(Wrapper: TRTTIWrapper; Handle: TRTTIHandle): TRTTIZoo; + begin + Result := TRTTIPolymorphicFactory.Make(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 := TRTTIPolymorphicFactory.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 +**************************************************************************************************************************) + + 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 := TRTTIPolymorphicFactory.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'); + 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'); + 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_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); + 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.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 new file mode 100644 index 00000000..32983bf6 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py @@ -0,0 +1,511 @@ +'''++ + +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 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_base_classtypeid = None + rtti_animal_name = None + rtti_tiger_roar = None + rtti_animaliterator_getnextanimal = None + rtti_animaliterator_getnextoptinalanimal = None + rtti_animaliterator_getnextmandatoryanimal = 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_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)) + 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)) + 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_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)) + 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_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] + + 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_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)] + + 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 = self._polymorphicFactory(InstanceHandle) + else: + raise ERTTIException(ErrorCodes.INVALIDCAST, 'Invalid return/output value') + + 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): + 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) + + if not handle: + return None + 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: + 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) + 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): + 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 +''' +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 = self._wrapper._polymorphicFactory(AnimalHandle) + else: + AnimalObject = None + + 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 +''' +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 = self._wrapper._polymorphicFactory(IteratorHandle) + else: + raise ERTTIException(ErrorCodes.INVALIDCAST, 'Invalid return/output value') + + return IteratorObject + + 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..0acb961f --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/CDynamic/CMakeLists.txt @@ -0,0 +1,35 @@ +#[[++ + +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) + +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_BINARY_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..edfb5486 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/CDynamic/RTTI_example.c @@ -0,0 +1,158 @@ +/*++ + +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 +#include +#include +#include +#include "rtti_dynamic.h" + +void releaseWrapper(sRTTIDynamicWrapperTable* pWrapperTable) { + RTTIResult eResult = ReleaseRTTIWrapperTable(pWrapperTable); + if (RTTI_SUCCESS != eResult) { + printf("Failed to release wrapper table\n"); + } +} + +int main() +{ + // TODO: put a path to RTTI binary file here: + 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("Failed to initialize wrapper table\n"); + return eResult; + } + + eResult = LoadRTTIWrapperTable(&sWrapperTable, libpath); + if (RTTI_SUCCESS != eResult) { + 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("Failed to get version\n"); + releaseWrapper(&sWrapperTable); + return eResult; + } + printf("RTTI.Version = %d.%d.%d", nMajor, nMinor, nMicro); + + printf("\n"); + + RTTI_Zoo Zoo; + assert(RTTI_SUCCESS == sWrapperTable.m_CreateZoo(&Zoo)); + + RTTI_AnimalIterator Iterator; + 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 != 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 != 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 != 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 != 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 != 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 != 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 != 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 != 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 != 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 != 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 == NULL); + + eResult = ReleaseRTTIWrapperTable(&sWrapperTable); + if (RTTI_SUCCESS != eResult) { + printf("Failed to release wrapper table\n"); + return eResult; + } + + return 0; +} + 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/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..0d941855 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.cs @@ -0,0 +1,111 @@ +/*++ + +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(); + + RTTI.CAnimal Animal; + + // Animal name: Gerald Giraffe + Animal = Iterator.GetNextAnimal(); + 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() != 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() != 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() != 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() != 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() != 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() != 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() != 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() != 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() != 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() == IntPtr.Zero)) throw new Exception("Wrong data"); + } + catch (Exception e) + { + Console.WriteLine("Exception: \"" + e.Message + "\""); + System.Environment.Exit(1); + } + } + } +} + 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 @@ + + + + Exe + netstandard2.0 + RTTI_Example.RTTI_Example + + x64 + + + true + + + true + + + + + 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/Examples/RTTI/RTTI_component/Examples/CSharp/build.sh b/Examples/RTTI/RTTI_component/Examples/CSharp/build.sh new file mode 100755 index 00000000..6cdcb8c5 --- /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 obj +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/CMakeLists.txt b/Examples/RTTI/RTTI_component/Examples/Cpp/CMakeLists.txt new file mode 100644 index 00000000..a1108c3c --- /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(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 new file mode 100644 index 00000000..dec8b000 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Cpp/RTTI_example.cpp @@ -0,0 +1,110 @@ +/*++ + +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 +#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; + + PAnimal animal; + // Animal name: Gerald Giraffe + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Gerald Giraffe"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + + // Animal name: Timmy Tiger + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Timmy Tiger"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + std::dynamic_pointer_cast(animal)->Roar(); + + // Animal name: Tony Tiger + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Tony Tiger"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + std::dynamic_pointer_cast(animal)->Roar(); + + // Animal name: Sebastian Snake + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Sebastian Snake"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + + // Animal name: Tobias Turtle + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Tobias Turtle"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + + // Animal name: Theo Turtle + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Theo Turtle"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + + // Animal name: Tomás Turtle + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Tomás Turtle"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + + // Animal name: Slytherin Snake + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Slytherin Snake"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + + // Animal name: Travis Tiger + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Travis Tiger"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + std::dynamic_pointer_cast(animal)->Roar(); + + // Animal name: Gary Giraffe + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Gary Giraffe"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + + animal = iter->GetNextAnimal(); + assert(animal == nullptr); + } + catch (std::exception &e) + { + std::cout << e.what() << std::endl; + return 1; + } + return 0; +} + 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/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..3ee5e73f --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/CppDynamic/RTTI_example.cpp @@ -0,0 +1,123 @@ +/*++ + +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 +#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." +#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(); + + using namespace RTTI; + + PAnimal animal; + // Animal name: Gerald Giraffe + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Gerald Giraffe"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + + // Animal name: Timmy Tiger + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Timmy Tiger"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + std::dynamic_pointer_cast(animal)->Roar(); + + // Animal name: Tony Tiger + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Tony Tiger"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + std::dynamic_pointer_cast(animal)->Roar(); + + // Animal name: Sebastian Snake + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Sebastian Snake"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + + // Animal name: Tobias Turtle + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Tobias Turtle"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + + // Animal name: Theo Turtle + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Theo Turtle"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + + // Animal name: Tomás Turtle + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Tomás Turtle"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + + // Animal name: Slytherin Snake + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Slytherin Snake"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + + // Animal name: Travis Tiger + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Travis Tiger"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + std::dynamic_pointer_cast(animal)->Roar(); + + // Animal name: Gary Giraffe + animal = iter->GetNextAnimal(); + assert(animal != nullptr); + assert(animal->Name() == "Gary Giraffe"); + assert(std::dynamic_pointer_cast(animal) != nullptr); + + std::cout << "Trace 0" << std::endl; + + animal = iter->GetNextAnimal(); + assert(animal == nullptr); + + std::cout << "Trace 1" << std::endl; + } + catch (std::exception &e) + { + std::cout << e.what() << std::endl; + return 1; + } + return 0; +} + 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/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..a2e8df81 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Go/RTTI_example.go @@ -0,0 +1,56 @@ +/*++ + +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 ( + "os" + "fmt" + "log" + "../../Bindings/Go" +) + +func main() { + fmt.Println("Start") + wrapper, err := rtti.LoadLibrary(os.Args[1:][0]) + 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/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/RTTI_Example.java b/Examples/RTTI/RTTI_component/Examples/Java9/RTTI_Example.java new file mode 100644 index 00000000..bdf526ec --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Java9/RTTI_Example.java @@ -0,0 +1,102 @@ +/*++ + +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 void main(String[] args) throws RTTIException { + String libpath = args[0]; + 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(); + + 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); + + } +} + diff --git a/Examples/RTTI/RTTI_component/Examples/Java9/build.sh b/Examples/RTTI/RTTI_component/Examples/Java9/build.sh new file mode 100755 index 00000000..5c21c106 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Java9/build.sh @@ -0,0 +1,36 @@ +#!/bin/bash +set -euxo pipefail + +cd "$(dirname "$0")" +source ../../../../../Build/build.inc + +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 ] || 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 +echo "Compile Java example" +javac -encoding UTF8 -classpath $Classpath RTTI_Example.java + +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/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..1220abf7 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Pascal/RTTI_Example.lpr @@ -0,0 +1,106 @@ +(*++ + +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 := '.'; // TODO add the location of the shared library binary here + ARTTIWrapper := TRTTIWrapper.Create(ALibPath + '/' + 'rtti.dll'); // 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/Examples/Pascal/build.sh b/Examples/RTTI/RTTI_component/Examples/Pascal/build.sh new file mode 100755 index 00000000..03d0983a --- /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/RTTI_Example.py b/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py new file mode 100644 index 00000000..98ebaabf --- /dev/null +++ b/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py @@ -0,0 +1,102 @@ +'''++ + +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("") + + 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: + main() + except RTTI.ERTTIException as e: + print(e) 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/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..8654ffee --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_abi.hpp @@ -0,0 +1,214 @@ +/*++ + +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); + +/** +* 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 +**************************************************************************************************************************/ + +/** +* 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..32cff8a8 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaceexception.cpp @@ -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 C++ Implementation file with the basic internal + exception type in order to allow an easy use of RTTI + +Interface version: 1.0.0 + +*/ + + +#include <string> + +#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..0b153bb9 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaceexception.hpp @@ -0,0 +1,60 @@ +/*++ + +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 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 <exception> +#include <stdexcept> +#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..b0f1c576 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfaces.hpp @@ -0,0 +1,492 @@ +/*++ + +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 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 <string> +#include <memory> + +#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 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 { +private: + std::unique_ptr<ParameterCache> m_ParameterCache; +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; + + /** + * 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(); + } + + /** + * IBase::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + virtual RTTI_uint64 ClassTypeId() = 0; +}; + + +/** + Definition of a shared pointer class for IBase +*/ +template<class T> +class IBaseSharedPtr : public std::shared_ptr<T> +{ +public: + explicit IBaseSharedPtr(T* t = nullptr) + : std::shared_ptr<T>(t, IBase::ReleaseBaseClassInterface) + { + t->IncRefCount(); + } + + // Reset function, as it also needs to properly set the deleter. + void reset(T* t = nullptr) + { + std::shared_ptr<T>::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<IBase> PIBase; + + +/************************************************************************************************************************* + Class interface for Animal +**************************************************************************************************************************/ + +class IAnimal : public virtual IBase { +public: + /** + * IAnimal::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 ClassTypeId() override + { + return 0x8B40467DA6D327AFUL; // First 64 bits of SHA1 of a string: "RTTI::Animal" + } + + /** + * IAnimal::Name - Get the name of the animal + * @return + */ + virtual std::string Name() = 0; + +}; + +typedef IBaseSharedPtr<IAnimal> PIAnimal; + + +/************************************************************************************************************************* + Class interface for Mammal +**************************************************************************************************************************/ + +class IMammal : public virtual IAnimal { +public: + /** + * IMammal::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 ClassTypeId() override + { + return 0xBC9D5FA7750C1020UL; // First 64 bits of SHA1 of a string: "RTTI::Mammal" + } + +}; + +typedef IBaseSharedPtr<IMammal> PIMammal; + + +/************************************************************************************************************************* + Class interface for Reptile +**************************************************************************************************************************/ + +class IReptile : public virtual IAnimal { +public: + /** + * IReptile::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 ClassTypeId() override + { + return 0x6756AA8EA5802EC3UL; // First 64 bits of SHA1 of a string: "RTTI::Reptile" + } + +}; + +typedef IBaseSharedPtr<IReptile> PIReptile; + + +/************************************************************************************************************************* + Class interface for Giraffe +**************************************************************************************************************************/ + +class IGiraffe : public virtual IMammal { +public: + /** + * IGiraffe::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 ClassTypeId() override + { + return 0x9751971BD2C2D958UL; // First 64 bits of SHA1 of a string: "RTTI::Giraffe" + } + +}; + +typedef IBaseSharedPtr<IGiraffe> PIGiraffe; + + +/************************************************************************************************************************* + Class interface for Tiger +**************************************************************************************************************************/ + +class ITiger : public virtual IMammal { +public: + /** + * ITiger::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 ClassTypeId() override + { + return 0x8D007E7B5F7BAF4UL; // First 64 bits of SHA1 of a string: "RTTI::Tiger" + } + + /** + * ITiger::Roar - Roar like a tiger + */ + virtual void Roar() = 0; + +}; + +typedef IBaseSharedPtr<ITiger> PITiger; + + +/************************************************************************************************************************* + Class interface for Snake +**************************************************************************************************************************/ + +class ISnake : public virtual IReptile { +public: + /** + * ISnake::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 ClassTypeId() override + { + return 0x5F6826EF909803B2UL; // First 64 bits of SHA1 of a string: "RTTI::Snake" + } + +}; + +typedef IBaseSharedPtr<ISnake> PISnake; + + +/************************************************************************************************************************* + Class interface for Turtle +**************************************************************************************************************************/ + +class ITurtle : public virtual IReptile { +public: + /** + * ITurtle::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 ClassTypeId() override + { + return 0x8E551B208A2E8321UL; // First 64 bits of SHA1 of a string: "RTTI::Turtle" + } + +}; + +typedef IBaseSharedPtr<ITurtle> PITurtle; + + +/************************************************************************************************************************* + Class interface for AnimalIterator +**************************************************************************************************************************/ + +class IAnimalIterator : public virtual IBase { +public: + /** + * IAnimalIterator::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 ClassTypeId() override + { + return 0xF1917FE6BBE77831UL; // First 64 bits of SHA1 of a string: "RTTI::AnimalIterator" + } + + /** + * IAnimalIterator::GetNextAnimal - Return next animal + * @return + */ + 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; + + +/************************************************************************************************************************* + Class interface for Zoo +**************************************************************************************************************************/ + +class IZoo : public virtual IBase { +public: + /** + * IZoo::ClassTypeId - Get Class Type Id + * @return Class type as a 64 bits integer + */ + RTTI_uint64 ClassTypeId() override + { + return 0x2262ABE80A5E7878UL; // First 64 bits of SHA1 of a string: "RTTI::Zoo" + } + + /** + * IZoo::Iterator - Return an iterator over all zoo animals + * @return + */ + virtual IAnimalIterator * Iterator() = 0; + +}; + +typedef IBaseSharedPtr<IZoo> 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..c69c853d --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_interfacewrapper.cpp @@ -0,0 +1,549 @@ +/*++ + +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++ 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 <map> + +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 +**************************************************************************************************************************/ +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<IBase*>(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 +**************************************************************************************************************************/ +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<IAnimal*>(pIBaseClass); + if (!pIAnimal) + throw ERTTIInterfaceException(RTTI_ERROR_INVALIDCAST); + + bool isCacheCall = (pResultBuffer == nullptr); + if (isCacheCall) { + sResult = pIAnimal->Name(); + + pIAnimal->_setCache (new ParameterCache_1<std::string> (sResult)); + } + else { + auto cache = dynamic_cast<ParameterCache_1<std::string>*> (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 +**************************************************************************************************************************/ + +/************************************************************************************************************************* + 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<ITiger*>(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<IAnimalIterator*>(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); + } +} + +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 +**************************************************************************************************************************/ +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<IZoo*>(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_base_classtypeid") + *ppProcAddress = (void*) &rtti_base_classtypeid; + 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") + *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") + *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<IBase*>(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<IBase*>(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<IBase*>(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..cc0455f9 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Interfaces/rtti_types.hpp @@ -0,0 +1,125 @@ +/*++ + +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; +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 /** 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 { + +} // 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..133b8aee --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti.cpp @@ -0,0 +1,75 @@ +/*++ + +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" + +#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; + +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() +{ + auto zoo = new CZoo(); + + auto& animals = zoo->Animals(); + + 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 new file mode 100644 index 00000000..a77f4d28 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animal.cpp @@ -0,0 +1,36 @@ +/*++ + +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. +#include <iostream> + +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 new file mode 100644 index 00000000..9c839d0e --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animal.hpp @@ -0,0 +1,70 @@ +/*++ + +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. + */ + std::string m_sName; +protected: + + /** + * Put protected members here. + */ + CAnimal(); + ~CAnimal(); + explicit CAnimal(std::string sName); +public: + + /** + * Put additional public members here. They will not be visible in the external API. + */ + + + /** + * Public member functions to implement. + */ + std::string Name() override; + +}; + +} // 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..ea7be6a3 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.cpp @@ -0,0 +1,49 @@ +/*++ + +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. +#include "rtti_animal.hpp" + +using namespace RTTI::Impl; + +/************************************************************************************************************************* + Class definition of CAnimalIterator +**************************************************************************************************************************/ +CAnimalIterator::CAnimalIterator(std::vector<CAnimal*>::iterator begin, std::vector<CAnimal*>::iterator end) + : m_Current(begin) + , m_End(end) +{ +} + +IAnimal * CAnimalIterator::GetNextAnimal() +{ + if (m_Current != m_End) { + auto i = *(m_Current++); + i->IncRefCount(); + return i; + } else { + 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 new file mode 100644 index 00000000..b1cc9ec8 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_animaliterator.hpp @@ -0,0 +1,73 @@ +/*++ + +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. +#include <vector> + +namespace RTTI { +namespace Impl { + +class CAnimal; + +/************************************************************************************************************************* + Class declaration of CAnimalIterator +**************************************************************************************************************************/ + +class CAnimalIterator : public virtual IAnimalIterator, public virtual CBase { +private: + + /** + * Put private members here. + */ + std::vector<CAnimal *>::iterator m_Current; + std::vector<CAnimal *>::iterator m_End; +protected: + + /** + * Put protected members here. + */ + +public: + + /** + * Put additional public members here. They will not be visible in the external API. + */ + CAnimalIterator(std::vector<CAnimal *>::iterator begin, std::vector<CAnimal *>::iterator end); + + /** + * Public member functions to implement. + */ + + IAnimal * GetNextAnimal() override; + bool GetNextOptinalAnimal(IAnimal*& pAnimal) override; + bool GetNextMandatoryAnimal(IAnimal*& pAnimal) 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..a0ab41f5 --- /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. +#include <iostream> + +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 <vector> +#include <list> +#include <memory> + + +// Include custom headers here. + + +namespace RTTI { +namespace Impl { + + +/************************************************************************************************************************* + Class declaration of CBase +**************************************************************************************************************************/ + +class CBase : public virtual IBase { +private: + + std::unique_ptr<std::string> 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..6c90106a --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_giraffe.cpp @@ -0,0 +1,25 @@ +/*++ + +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 +**************************************************************************************************************************/ +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 new file mode 100644 index 00000000..7ee1c17d --- /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. + */ + explicit CGiraffe(std::string sName); + + /** + * 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..261208b2 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_snake.cpp @@ -0,0 +1,26 @@ +/*++ + +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 +**************************************************************************************************************************/ +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 new file mode 100644 index 00000000..d752f6cd --- /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. + */ + explicit CSnake(std::string sName); + + /** + * 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..a318e5aa --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_tiger.cpp @@ -0,0 +1,31 @@ +/*++ + +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. +#include <iostream> + +using namespace RTTI::Impl; + +/************************************************************************************************************************* + Class definition of CTiger +**************************************************************************************************************************/ +CTiger::CTiger(std::string sName) + : CAnimal(sName) +{ +} + +void CTiger::Roar() +{ + std::cout << "ROAAAAARRRRR!!" << std::endl; +} + 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..d49e2692 --- /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. + */ + explicit CTiger(std::string sName); + + /** + * 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..bc14a6ad --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_turtle.cpp @@ -0,0 +1,25 @@ +/*++ + +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 +**************************************************************************************************************************/ +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 new file mode 100644 index 00000000..dd2423c6 --- /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. + */ + explicit CTurtle(std::string sName); + + /** + * 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..6ea8fb50 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.cpp @@ -0,0 +1,39 @@ +/*++ + +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. +#include "rtti_animal.hpp" +#include "rtti_animaliterator.hpp" + +using namespace RTTI::Impl; + +/************************************************************************************************************************* + Class definition of CZoo +**************************************************************************************************************************/ +CZoo::~CZoo() +{ + for(auto &&i: m_Animals) + { + i->DecRefCount(); + } +} + +std::vector<CAnimal *> &CZoo::Animals() +{ + 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 new file mode 100644 index 00000000..1e1af969 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Cpp/Stub/rtti_zoo.hpp @@ -0,0 +1,73 @@ +/*++ + +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. +#include <vector> + +namespace RTTI { +namespace Impl { + +class CAnimal; +/************************************************************************************************************************* + Class declaration of CZoo +**************************************************************************************************************************/ + +class CZoo : public virtual IZoo, public virtual CBase { +private: + + /** + * Put private members here. + */ + std::vector<CAnimal*> m_Animals; + +protected: + + /** + * Put protected members here. + */ + +public: + + /** + * Put additional public members here. They will not be visible in the external API. + */ + ~CZoo(); + + std::vector<CAnimal*>& Animals(); + + + /** + * 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/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/Interfaces/rtti.lpr b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti.lpr new file mode 100644 index 00000000..5ddfdd2a --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti.lpr @@ -0,0 +1,51 @@ +(*++ + +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 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_animaliterator_getnextoptinalanimal, + rtti_animaliterator_getnextmandatoryanimal, + 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..97825104 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exception.pas @@ -0,0 +1,104 @@ +(*++ + +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 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..e8b361db --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_exports.pas @@ -0,0 +1,687 @@ +(*++ + +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 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; + +(** +* 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 +**************************************************************************************************************************) + +(** +* 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_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; + 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_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 + 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..3d7f1492 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_interfaces.pas @@ -0,0 +1,143 @@ +(*++ + +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 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; + function GetNextOptinalAnimal(out AAnimal: TObject): Boolean; + function GetNextMandatoryAnimal(out AAnimal: TObject): Boolean; +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..9a40dc21 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Interfaces/rtti_types.pas @@ -0,0 +1,66 @@ +(*++ + +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 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..bb281235 --- /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 := QWord($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..f1aa5418 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/Stub/rtti_impl_animaliterator.pas @@ -0,0 +1,76 @@ +(*++ + +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; + function GetNextOptinalAnimal(out AAnimal: TObject): Boolean; + function GetNextMandatoryAnimal(out AAnimal: TObject): Boolean; + + protected + end; + +implementation + +function TRTTIAnimalIterator.ClassTypeId(): QWord; +begin + Result := QWord($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; + +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. 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..37ebe69c --- /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 := 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 new file mode 100644 index 00000000..9f062c4c --- /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 := 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_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..fd8b04f6 --- /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 := QWord($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..63c2dca9 --- /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 := QWord($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/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/RTTI_component/Implementations/Pascal/rtti.def b/Examples/RTTI/RTTI_component/Implementations/Pascal/rtti.def new file mode 100644 index 00000000..3af35a45 --- /dev/null +++ b/Examples/RTTI/RTTI_component/Implementations/Pascal/rtti.def @@ -0,0 +1,15 @@ +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_animaliterator_getnextoptinalanimal +rtti_animaliterator_getnextmandatoryanimal +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..c11ac65c --- /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\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> + <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> + diff --git a/Examples/RTTI/RTTI_component/license.txt b/Examples/RTTI/RTTI_component/license.txt new file mode 100644 index 00000000..fa8920cb --- /dev/null +++ b/Examples/RTTI/RTTI_component/license.txt @@ -0,0 +1,5 @@ +Copyright (C) 2021 ADSK + +All rights reserved. + + 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 diff --git a/Source/buildbindingccpp.go b/Source/buildbindingccpp.go index 45cce48e..034a4d19 100644 --- a/Source/buildbindingccpp.go +++ b/Source/buildbindingccpp.go @@ -202,7 +202,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("") @@ -717,9 +721,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 = 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 = 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("}")) @@ -727,7 +732,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 = std::shared_ptr<%s>(dynamic_cast<%s*>(%s->polymorphicFactory(h%s)));", param.ParamName, CPPClass, CPPClass, makeSharedParameter, param.ParamName)) postCallCodeLines = append(postCallCodeLines, fmt.Sprintf("}")) } @@ -791,13 +796,13 @@ 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 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 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("}")) @@ -805,7 +810,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 std::shared_ptr<%s>(dynamic_cast<%s*>(%s->polymorphicFactory(h%s)));", CPPClass, CPPClass, makeSharedParameter, param.ParamName)) } case "basicarray": @@ -920,7 +925,7 @@ func writeDynamicCppBaseClassMethods(component ComponentDefinition, baseClass Co w.Writeln(" return m_pWrapper;") w.Writeln(" }") - w.Writeln(" ") + w.Writeln("") w.Writeln(" friend class CWrapper;") return nil } @@ -1067,7 +1072,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": @@ -1166,6 +1171,7 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln("#else // _WIN32") w.Writeln("#include <dlfcn.h>") w.Writeln("#endif // _WIN32") + w.Writeln("#include <array>") w.Writeln("#include <string>") w.Writeln("#include <memory>") w.Writeln("#include <vector>") @@ -1177,7 +1183,6 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s buildBindingCPPAllForwardDeclarations(component, w, NameSpace, cppClassPrefix, ClassIdentifier) - w.Writeln("") w.Writeln("/*************************************************************************************************************************") w.Writeln(" classParam Definition") @@ -1369,6 +1374,8 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s return err } } + w.Writeln("") + w.Writeln(" inline C%s* polymorphicFactory(%sHandle);", component.Global.BaseClassName, NameSpace) w.Writeln("") w.Writeln("private:") @@ -1407,6 +1414,7 @@ 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("") for i := 0; i < len(component.Classes); i++ { @@ -1460,6 +1468,38 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s w.Writeln("};") } + w.Writeln("") + w.Writeln("/*************************************************************************************************************************") + w.Writeln(" RTTI: Polymorphic Factory 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("* %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("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 { + 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] + classTypeId, chashHashString := class.classTypeId(NameSpace) + 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 new C%s(this, pHandle);", component.Global.BaseClassName) + w.Writeln("}") + for j := 0; j < len(global.Methods); j++ { method := global.Methods[j] diff --git a/Source/buildbindingcsharp.go b/Source/buildbindingcsharp.go index 30cefc02..6900291f 100644 --- a/Source/buildbindingcsharp.go +++ b/Source/buildbindingcsharp.go @@ -527,7 +527,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 = new 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) @@ -586,7 +588,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 new %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: @@ -965,6 +969,36 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW } w.Writeln(" throw new Exception(sMessage + \"(# \" + errorCode + \")\");") 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 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>(IntPtr Handle) where T : class") + w.Writeln(" {") + w.Writeln(" T Object;") + 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) + 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(" }") @@ -1219,7 +1253,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>") diff --git a/Source/buildbindinggo.go b/Source/buildbindinggo.go index 030fba7e..8eb41843 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) @@ -727,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.%s_pvoid", namespace) tp.CToGo = fmt.Sprintf("%s(%s)", tp.Type, paramName) tp.GoToC = fmt.Sprintf("(%s)(%s)", tp.CType, paramName) tp.Empty = "0" @@ -838,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 @@ -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 != nil {", param.ParamName)) if isGlobal { preOKReturn = append(preOKReturn, fmt.Sprintf(" _%sPtrVal := wrapper.New%s(%s)", param.ParamName, param.ParamClass, param.ParamName)) diff --git a/Source/buildbindingjava.go b/Source/buildbindingjava.go index 89628acc..0d018cc9 100644 --- a/Source/buildbindingjava.go +++ b/Source/buildbindingjava.go @@ -41,6 +41,7 @@ import ( "bytes" "os" "strconv" + "sort" ) type JavaParameter struct { @@ -68,7 +69,7 @@ func BuildBindingJavaDynamic(component ComponentDefinition, outputFolder string, if err != nil { return err; } - + JavaWrapperName := namespace + "Wrapper"; JavaWrapperPath := path.Join(JavaFolder, JavaWrapperName + ".java"); log.Printf("Creating \"%s\"", JavaWrapperPath) @@ -173,15 +174,20 @@ 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; + 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; @@ -263,6 +269,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,15 +291,15 @@ 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 ] || 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 \"${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; } @@ -302,9 +311,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 ] || 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) @@ -757,10 +768,10 @@ func writeJavaClassMethodImplementation(method ComponentDefinitionMethod, w Lang 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(value%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(" %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)) @@ -1181,6 +1192,79 @@ 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(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++ { + class := component.Classes[i] + classTypeId, _ := class.classTypeId(NameSpace) + 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 := 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++ { + 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(" default: obj = cls.getDeclaredConstructor(cArg).newInstance(this, handle); 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("") diff --git a/Source/buildbindingpascal.go b/Source/buildbindingpascal.go index e510dca1..33b387a5 100644 --- a/Source/buildbindingpascal.go +++ b/Source/buildbindingpascal.go @@ -413,12 +413,56 @@ func buildDynamicPascalImplementation(component ComponentDefinition, w LanguageW writeEnumConversionInterface(component, w, 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;") + + 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("") writeEnumConversionImplementation(component, w, NameSpace) - + w.Writeln("") + w.Writeln("(*************************************************************************************************************************") + 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;") + 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));", NameSpace) + w.Writeln(" case (ClassTypeId) of") + for i := 0; i < len(component.Classes); i++ { + classTypeId, chashHashString := component.Classes[i].classTypeId(NameSpace) + 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);") + 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") @@ -675,8 +719,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) @@ -864,7 +910,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")) @@ -1030,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%s%s.Create(%s, H%s);", 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) diff --git a/Source/buildbindingpython.go b/Source/buildbindingpython.go index 9eb7f0fd..1837f9db 100644 --- a/Source/buildbindingpython.go +++ b/Source/buildbindingpython.go @@ -365,6 +365,33 @@ 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):") + 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<len(componentdefinition.Classes); i++ { + classTypeId, chashHashString := componentdefinition.Classes[i].classTypeId(NameSpace) + w.Writeln(" def getObjectById_%016X(self, handle, wrapper): # First 64 bits of SHA1 of a string: \"%s\"", classTypeId, chashHashString) + 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()") + w.Writeln(" return factory.getObjectById(pClassTypeId, handle, self)") + w.Writeln(" ") + for i:=0; i<len(componentdefinition.Classes); i++ { w.Writeln("") w.Writeln("") @@ -740,6 +767,7 @@ func writePythonClass(component ComponentDefinition, class ComponentDefinitionCl } else { w.Writeln("class %s:", class.ClassName) + w.Writeln(" def __init__(self, handle, wrapper):") w.Writeln(" if not handle or not wrapper:") w.Writeln(" raise E%sException(ErrorCodes.INVALIDPARAM)", NameSpace) @@ -809,15 +837,15 @@ func writeMethod(method ComponentDefinitionMethod, w LanguageWriter, NameSpace s cCheckArguments = cCheckArguments + newArgument theWrapperReference := wrapperReference - subNameSpace, paramClassName, _ := decomposeParamClassName(param.ParamClass) + subNameSpace, _, _ := decomposeParamClassName(param.ParamClass) if len(subNameSpace) > 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, 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 7313bcd8..16acaee5 100644 --- a/Source/buildimplementationcpp.go +++ b/Source/buildimplementationcpp.go @@ -35,9 +35,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package main import ( + "errors" "fmt" "log" - "errors" "path" "strings" ) @@ -414,8 +414,32 @@ 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(" return 0x%XUL; // First 64 bits of SHA1 of a string: \"%s\"", classTypeId, chashHashString) + w.Writeln(" }") + w.Writeln("") + } + 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 @@ -560,7 +584,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 +642,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 @@ -719,8 +743,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 +875,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 } @@ -1701,7 +1726,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 { @@ -1767,7 +1792,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/buildimplementationpascal.go b/Source/buildimplementationpascal.go index 8e55f8ff..71c91620 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 := 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 { + 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 89affefd..24be9903 100644 --- a/Source/componentdefinition.go +++ b/Source/componentdefinition.go @@ -34,17 +34,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package main import ( - "strconv" - "fmt" - "errors" + "crypto/sha1" + "encoding/binary" "encoding/xml" - "regexp" - "strings" + "errors" + "fmt" + "io/ioutil" "log" "math" "os" - "io/ioutil" "path/filepath" + "regexp" + "strconv" + "strings" ) const ( @@ -119,6 +121,7 @@ type ComponentDefinitionGlobal struct { BaseClassName string `xml:"baseclassname,attr"` StringOutBaseClassName string `xml:"stringoutclassname,attr"` ErrorMethod string `xml:"errormethod,attr"` + ClassTypeIdMethod string `xml:"classtypeidmethod,attr"` ReleaseMethod string `xml:"releasemethod,attr"` AcquireMethod string `xml:"acquiremethod,attr"` SymbolLookupMethod string `xml:"symbollookupmethod,attr"` @@ -515,8 +518,10 @@ func (component *ComponentDefinition) checkClasses() (error) { classLowerNameList := make(map[string]bool, 0) classNameIndex := make(map[string]int, 0) + classTypeIdIndex := make(map[uint64]int, 0) for i := 0; i < len(classes); i++ { class := classes[i]; + classTypeHash, _ := class.classTypeId(component.NameSpace); if !nameIsValidIdentifier(class.ClassName) { return fmt.Errorf ("invalid class name \"%s\"", class.ClassName); } @@ -526,10 +531,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 := classTypeIdIndex[classTypeHash] + if hashExists { + 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 + classTypeIdIndex[classTypeHash] = i } // Check parent class definitions @@ -706,6 +716,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 @@ -715,7 +740,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) } @@ -958,6 +985,11 @@ func (component *ComponentDefinition) CheckComponentDefinition() (error) { return err } + err = component.checkBaseClassMethods() + if err != nil { + return err + } + err = component.checkClassMethods() if err != nil { return err @@ -1020,6 +1052,10 @@ func CheckHeaderSpecialFunction(method ComponentDefinitionMethod, global Compone return eSpecialMethodNone, errors.New ("No error method specified"); } + if (global.ClassTypeIdMethod == "") { + return eSpecialMethodNone, errors.New ("No ClassTypeId method specified"); + } + if (global.ReleaseMethod == global.JournalMethod) { return eSpecialMethodNone, errors.New ("Release method can not be the same as the Journal method"); } @@ -1163,7 +1199,6 @@ func CheckHeaderSpecialFunction(method ComponentDefinitionMethod, global Compone return eSpecialMethodNone, nil; } - // GetLastErrorMessageMethod returns the xml definition of the GetLastErrorMessage-method func GetLastErrorMessageMethod() (ComponentDefinitionMethod) { var method ComponentDefinitionMethod @@ -1370,3 +1405,23 @@ func (component *ComponentDefinition) countMaxOutParameters() (uint32) { return maxOutParameters; } +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 +} 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) diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 00000000..0e18e3aa --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,30 @@ +#!/bin/sh -l + +echo "Action selected: $1" +time=$(date) +echo "::set-output name=time::$time" +echo $(id -u) +echo $(id -g) + + +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 + +