IGNITE-1680: CPP: Implemented API for user entry point lookup. This closes 
#1430.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/1410900f
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/1410900f
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/1410900f

Branch: refs/heads/ignite-3477-merge2.0
Commit: 1410900f2c0e2f8819a1fb945109ca0d88f3a2f9
Parents: 9ce099c
Author: isapego <igors...@gmail.com>
Authored: Fri Feb 10 15:52:02 2017 +0300
Committer: devozerov <voze...@gridgain.com>
Committed: Fri Feb 10 15:52:02 2017 +0300

----------------------------------------------------------------------
 .../platform/PlatformProcessorImpl.java         |   9 -
 .../cache/PlatformCacheEntryProcessorImpl.java  |   6 +-
 .../include/ignite/binary/binary_object.h       |  22 +-
 .../binary/include/ignite/binary/binary_type.h  |   8 +-
 .../include/ignite/impl/binary/binary_common.h  |   6 +
 .../ignite/impl/binary/binary_object_header.h   |   9 +-
 .../ignite/impl/binary/binary_object_impl.h     |  61 +-
 .../ignite/impl/binary/binary_reader_impl.h     |  29 +-
 .../ignite/impl/binary/binary_type_updater.h    |   2 +-
 .../binary/binary_array_identity_resolver.cpp   |   2 +-
 .../src/impl/binary/binary_object_header.cpp    |  26 +-
 .../src/impl/binary/binary_object_impl.cpp      |  61 +-
 .../src/impl/binary/binary_type_manager.cpp     |   2 +-
 modules/platforms/cpp/common/Makefile.am        |   1 +
 .../common/include/ignite/common/concurrent.h   |  29 +-
 .../include/ignite/common/platform_utils.h      |   6 +-
 .../cpp/common/include/ignite/ignite_error.h    |   2 +-
 .../include/ignite/common/dynamic_load_os.h     | 131 +++++
 .../os/linux/src/common/dynamic_load_os.cpp     |  90 +++
 .../os/linux/src/common/platform_utils.cpp      |  18 +-
 .../win/include/ignite/common/dynamic_load_os.h | 133 +++++
 .../os/win/src/common/dynamic_load_os.cpp       | 115 ++++
 .../common/os/win/src/common/platform_utils.cpp |  26 +-
 .../cpp/common/project/vs/common.vcxproj        |   2 +
 .../common/project/vs/common.vcxproj.filters    |   6 +
 .../platforms/cpp/common/src/common/utils.cpp   |   3 +-
 .../platforms/cpp/common/src/ignite_error.cpp   |  68 +--
 modules/platforms/cpp/core-test/Makefile.am     |   5 +-
 .../core-test/include/ignite/binary_test_defs.h | 106 ++--
 .../cpp/core-test/project/vs/core-test.vcxproj  |   2 +
 .../project/vs/core-test.vcxproj.filters        |   6 +
 .../cpp/core-test/src/binary_object_test.cpp    |   6 +-
 .../src/binary_reader_writer_raw_test.cpp       |  23 +-
 .../cpp/core-test/src/cache_invoke_test.cpp     | 553 +++++++++++++++++++
 .../platforms/cpp/core-test/src/cache_test.cpp  |   5 +-
 .../cpp/core-test/src/cluster_test.cpp          |  98 ++++
 .../cpp/core-test/src/interop_memory_test.cpp   |   3 +-
 modules/platforms/cpp/core/Makefile.am          |   1 +
 modules/platforms/cpp/core/include/Makefile.am  |   8 +
 .../cpp/core/include/ignite/cache/cache.h       | 217 ++++++--
 .../ignite/cache/cache_entry_processor.h        | 111 ++++
 .../include/ignite/cache/mutable_cache_entry.h  | 176 ++++++
 .../include/ignite/cache/query/query_cursor.h   |   2 +-
 .../platforms/cpp/core/include/ignite/ignite.h  |  18 +
 .../cpp/core/include/ignite/ignite_binding.h    | 119 ++++
 .../include/ignite/ignite_binding_context.h     |  88 +++
 .../core/include/ignite/ignite_configuration.h  |   2 -
 .../impl/binary/binary_type_updater_impl.h      |   2 +-
 .../impl/cache/cache_entry_processor_holder.h   | 282 ++++++++++
 .../core/include/ignite/impl/cache/cache_impl.h |  71 +--
 .../ignite/impl/cluster/cluster_group_impl.h    |  77 +++
 .../include/ignite/impl/ignite_binding_impl.h   | 121 ++++
 .../include/ignite/impl/ignite_environment.h    |  61 +-
 .../cpp/core/include/ignite/impl/ignite_impl.h  |  50 +-
 .../ignite/impl/interop/interop_target.h        |  37 +-
 .../core/include/ignite/impl/module_manager.h   | 131 +++++
 .../cpp/core/include/ignite/impl/operations.h   |  62 +--
 .../platforms/cpp/core/project/vs/core.vcxproj  |   9 +
 .../cpp/core/project/vs/core.vcxproj.filters    |  30 +
 modules/platforms/cpp/core/src/ignite.cpp       |  12 +-
 modules/platforms/cpp/core/src/ignition.cpp     | 343 +++++++-----
 .../impl/binary/binary_type_updater_impl.cpp    |   2 +-
 .../cpp/core/src/impl/cache/cache_impl.cpp      |  66 ++-
 .../continuous/continuous_query_handle_impl.cpp |   2 +-
 .../core/src/impl/cache/query/query_impl.cpp    |   8 +-
 .../src/impl/cluster/cluster_group_impl.cpp     |  64 +++
 .../cpp/core/src/impl/ignite_environment.cpp    |  92 ++-
 .../platforms/cpp/core/src/impl/ignite_impl.cpp |  32 +-
 .../core/src/impl/interop/interop_target.cpp    |  49 +-
 .../src/impl/transactions/transactions_impl.cpp |  14 +-
 .../platforms/cpp/jni/include/ignite/jni/java.h |   2 +-
 .../cpp/jni/include/ignite/jni/utils.h          |  69 ++-
 .../platforms/cpp/jni/os/linux/src/utils.cpp    | 221 ++++----
 modules/platforms/cpp/jni/os/win/src/utils.cpp  | 227 ++++----
 modules/platforms/cpp/jni/src/java.cpp          |  53 +-
 .../Impl/Unmanaged/UnmanagedCallbacks.cs        |   5 +-
 76 files changed, 3821 insertions(+), 795 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
index 63fdc18..a3d01c3 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
@@ -214,15 +214,6 @@ public class PlatformProcessorImpl extends 
GridProcessorAdapter implements Platf
 
     /** {@inheritDoc} */
     @Override public PlatformContext context() {
-        // This method is a single point of entry for all remote closures
-        // CPP platform does not currently support remote code execution
-        // Therefore, all remote execution attempts come from .NET
-        // Throw an error if current platform is not .NET
-        if (!PlatformUtils.PLATFORM_DOTNET.equals(interopCfg.platform())) {
-            throw new IgniteException(".NET platform is not available 
[nodeId=" + ctx.grid().localNode().id() + "] " +
-                "(Use Apache.Ignite.Core.Ignition.Start() or Apache.Ignite.exe 
to start Ignite.NET nodes).");
-        }
-
         return platformCtx;
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCacheEntryProcessorImpl.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCacheEntryProcessorImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCacheEntryProcessorImpl.java
index 31dd267..9388855 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCacheEntryProcessorImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCacheEntryProcessorImpl.java
@@ -143,9 +143,6 @@ public class PlatformCacheEntryProcessorImpl implements 
PlatformCacheEntryProces
      * @param writer Writer.
      */
     private void writeEntryAndProcessor(MutableEntry entry, BinaryRawWriter 
writer) {
-        writer.writeObject(entry.getKey());
-        writer.writeObject(entry.getValue());
-
         if (ptr != 0) {
             // Execute locally - we have a pointer to native processor.
             writer.writeBoolean(true);
@@ -156,6 +153,9 @@ public class PlatformCacheEntryProcessorImpl implements 
PlatformCacheEntryProces
             writer.writeBoolean(false);
             writer.writeObject(proc);
         }
+
+        writer.writeObject(entry.getKey());
+        writer.writeObject(entry.getValue());
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/include/ignite/binary/binary_object.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/binary/binary_object.h 
b/modules/platforms/cpp/binary/include/ignite/binary/binary_object.h
index 08b503e..12ac938 100644
--- a/modules/platforms/cpp/binary/include/ignite/binary/binary_object.h
+++ b/modules/platforms/cpp/binary/include/ignite/binary/binary_object.h
@@ -39,7 +39,7 @@ namespace ignite
          * This is a thin wrapper over the memory area that contains serialized
          * binary object. Provides method that allows deserialize object.
          */
-        class IGNITE_IMPORT_EXPORT BinaryObject : private 
impl::binary::BinaryObjectImpl
+        class IGNITE_IMPORT_EXPORT BinaryObject
         {
             friend class BinaryArrayIdentityResolver;
         public:
@@ -47,11 +47,22 @@ namespace ignite
             /**
              * Constructor.
              *
+             * @param impl Implementation.
+             */
+            BinaryObject(const impl::binary::BinaryObjectImpl& impl) :
+                impl(impl)
+            {
+                // No-op.
+            };
+
+            /**
+             * Constructor.
+             *
              * @param mem Binary object memory.
              * @param start Object starting position in memory.
              */
-            BinaryObject(impl::interop::InteropMemory& mem, int32_t start) : 
-                BinaryObjectImpl(mem, start)
+            BinaryObject(impl::interop::InteropMemory& mem, int32_t start) :
+                impl(mem, start)
             {
                 // No-op.
             };
@@ -66,10 +77,13 @@ namespace ignite
             template<typename T>
             T Deserialize() const
             {
-                return impl::binary::BinaryObjectImpl::Deserialize<T>();
+                return impl.Deserialize<T>();
             }
 
         private:
+            /** Implementation. */
+            impl::binary::BinaryObjectImpl impl;
+
             IGNITE_NO_COPY_ASSIGNMENT(BinaryObject)
         };
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/include/ignite/binary/binary_type.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/binary/binary_type.h 
b/modules/platforms/cpp/binary/include/ignite/binary/binary_type.h
index 1c37f6d..f65c652 100644
--- a/modules/platforms/cpp/binary/include/ignite/binary/binary_type.h
+++ b/modules/platforms/cpp/binary/include/ignite/binary/binary_type.h
@@ -172,7 +172,7 @@ namespace ignite
              *
              * @return Type name.
              */
-            std::string GetTypeName() 
+            std::string GetTypeName()
             {
                 IGNITE_ERROR_1(IgniteError::IGNITE_ERR_BINARY, "GetTypeName 
function is not defined for binary type.");
             }
@@ -244,9 +244,9 @@ namespace ignite
             /**
              * Constructor.
              */
-            BinaryType()
+            BinaryType() : typ()
             {
-                typ = BinaryType<T>();
+                // No-op.
             }
 
             int32_t GetTypeId()
@@ -285,7 +285,7 @@ namespace ignite
 
             T* GetNull()
             {
-                return NULL;
+                return 0;
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_common.h
----------------------------------------------------------------------
diff --git 
a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_common.h 
b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_common.h
index 462bc5b..aa15cc5 100644
--- a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_common.h
+++ b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_common.h
@@ -62,6 +62,12 @@ namespace ignite
             /** Full header length. */
             const int32_t IGNITE_DFLT_HDR_LEN = 24;
 
+            /** Binary header length. */
+            const int32_t IGNITE_BINARY_HDR_LEN = 5;
+
+            /** Common header length. */
+            const int32_t IGNITE_COMMON_HDR_LEN = 1;
+
             /** Type: object. */
             const int8_t IGNITE_TYPE_OBJECT = IGNITE_HDR_FULL;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_header.h
----------------------------------------------------------------------
diff --git 
a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_header.h
 
b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_header.h
index 5ba1960..8e74de6 100644
--- 
a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_header.h
+++ 
b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_header.h
@@ -43,7 +43,7 @@ namespace ignite
             /**
              * Binary object header layout.
              */
-            struct IGNITE_IMPORT_EXPORT BinaryObjectHeaderLayout
+            struct BinaryObjectHeaderLayout
             {
                 int8_t  headerType;
                 int8_t  version;
@@ -239,6 +239,13 @@ namespace ignite
                     return GetFooterOffset() - SIZE;
                 }
 
+                /**
+                 * Get underlying memory.
+                 *
+                 * @return Underlying memory.
+                 */
+                int8_t* GetMem();
+
             private:
                 /** Header layout */
                 BinaryObjectHeaderLayout* header;

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_impl.h
----------------------------------------------------------------------
diff --git 
a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_impl.h 
b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_impl.h
index efe1f49..0eb0dd6 100644
--- 
a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_impl.h
+++ 
b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_impl.h
@@ -54,6 +54,42 @@ namespace ignite
                 BinaryObjectImpl(interop::InteropMemory& mem, int32_t start);
 
                 /**
+                 * Copy constructor.
+                 *
+                 * @param other Another instance.
+                 */
+                BinaryObjectImpl(const BinaryObjectImpl& other);
+
+                /**
+                 * Assignment operator.
+                 *
+                 * @param other Another instance.
+                 * @return *this.
+                 */
+                BinaryObjectImpl& operator=(const BinaryObjectImpl& other);
+
+                /**
+                 * Create from InteropMemory instance.
+                 * @throw IgniteError if the memory at the specified offset
+                 *    is not a valid BinaryObject.
+                 *
+                 * @param mem Memory.
+                 * @param offset Offset in memory.
+                 * @return BinaryObjectImpl instance.
+                 */
+                static BinaryObjectImpl FromMemory(interop::InteropMemory& 
mem, int32_t offset);
+
+                /**
+                 * Create from InteropMemory instance.
+                 * @warning Does not check memory for validity.
+                 *
+                 * @param mem Memory.
+                 * @param offset Offset in memory.
+                 * @return BinaryObjectImpl instance.
+                 */
+                static BinaryObjectImpl 
FromMemoryUnsafe(interop::InteropMemory& mem, int32_t offset);
+
+                /**
                  * Deserialize object.
                  * @throw IgniteError if the object can not be deserialized to 
specified type.
                  *
@@ -62,7 +98,7 @@ namespace ignite
                 template<typename T>
                 T Deserialize() const
                 {
-                    interop::InteropInputStream stream(&mem);
+                    interop::InteropInputStream stream(mem);
 
                     stream.Position(start);
                     BinaryReaderImpl reader(&stream);
@@ -71,6 +107,17 @@ namespace ignite
                 }
 
                 /**
+                 * Get binary object field.
+                 *
+                 * @warning Works only if all object fields are objects.
+                 *     Otherwise behavior is undefined.
+                 *
+                 * @param idx Field index. Starts from 0.
+                 * @return Binary object field.
+                 */
+                BinaryObjectImpl GetField(int32_t idx);
+
+                /**
                  * Get object data.
                  *
                  * @return Pointer to object data.
@@ -86,6 +133,14 @@ namespace ignite
                 int32_t GetLength() const;
 
                 /**
+                 * Get type ID.
+                 * @throw IgniteError if the object is not in a valid state.
+                 *
+                 * @return Type ID.
+                 */
+                int32_t GetTypeId() const;
+
+                /**
                  * Get object hash code.
                  * @throw IgniteError if the object is not in a valid state.
                  *
@@ -94,10 +149,8 @@ namespace ignite
                 int32_t GetHashCode() const;
 
             private:
-                IGNITE_NO_COPY_ASSIGNMENT(BinaryObjectImpl)
-
                 /** Underlying object memory. */
-                interop::InteropMemory& mem;
+                interop::InteropMemory* mem;
 
                 /** Object starting position in memory. */
                 int32_t start;

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_reader_impl.h
----------------------------------------------------------------------
diff --git 
a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_reader_impl.h 
b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_reader_impl.h
index cd32203..814651d 100644
--- 
a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_reader_impl.h
+++ 
b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_reader_impl.h
@@ -808,6 +808,28 @@ namespace ignite
                 }
 
                 /**
+                 * Try read object.
+                 * Reads value, stores it to res and returns true if the value 
is
+                 * not null. Otherwise just returns false.
+                 *
+                 * @param res Read value is placed here if non-null.
+                 * @return True if the non-null value has been read and false
+                 *     otherwise.
+                 */
+                template<typename T>
+                bool TryReadObject(T& res)
+                {
+                    CheckRawMode(true);
+
+                    if (SkipIfNull())
+                        return false;
+
+                    res = ReadObject<T>();
+
+                    return true;
+                }
+
+                /**
                  * Set raw mode.
                  */
                 void SetRawMode();
@@ -896,7 +918,8 @@ namespace ignite
 
                             int32_t footerEnd;
 
-                            if (flags & IGNITE_BINARY_FLAG_HAS_RAW)
+                            if (flags & IGNITE_BINARY_FLAG_HAS_RAW &&
+                                flags & IGNITE_BINARY_FLAG_HAS_SCHEMA)
                             {
                                 // 4 is the size of RawOffset field at the end 
of the packet.
                                 footerEnd = pos + len - 4;
@@ -910,7 +933,7 @@ namespace ignite
                                 rawOff = schemaOrRawOff;
                             }
 
-                            bool usrType = flags & 
IGNITE_BINARY_FLAG_USER_TYPE;
+                            bool usrType = (flags & 
IGNITE_BINARY_FLAG_USER_TYPE) != 0;
 
                             ignite::binary::BinaryType<T> type;
                             TemplatedBinaryIdResolver<T> idRslvr(type);
@@ -929,7 +952,7 @@ namespace ignite
                         default:
                         {
                             
IGNITE_ERROR_2(ignite::IgniteError::IGNITE_ERR_BINARY, 
-                                           "Unexpected header during 
deserialization: ", static_cast<int>(hdr));
+                                           "Unexpected header during 
deserialization: ", (hdr & 0xFF));
                         }
                     }
                 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_updater.h
----------------------------------------------------------------------
diff --git 
a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_updater.h 
b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_updater.h
index 5bd1d7e..6bded74 100644
--- 
a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_updater.h
+++ 
b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_updater.h
@@ -44,7 +44,7 @@ namespace ignite
                  * @param snapshot Snapshot.
                  * @param err Error.
                  */
-                virtual bool Update(Snap* snapshot, IgniteError* err) = 0;
+                virtual bool Update(Snap* snapshot, IgniteError& err) = 0;
             };
         }
     }    

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/src/binary/binary_array_identity_resolver.cpp
----------------------------------------------------------------------
diff --git 
a/modules/platforms/cpp/binary/src/binary/binary_array_identity_resolver.cpp 
b/modules/platforms/cpp/binary/src/binary/binary_array_identity_resolver.cpp
index 1d4e384..6338842 100644
--- a/modules/platforms/cpp/binary/src/binary/binary_array_identity_resolver.cpp
+++ b/modules/platforms/cpp/binary/src/binary/binary_array_identity_resolver.cpp
@@ -36,7 +36,7 @@ namespace ignite
 
         int32_t BinaryArrayIdentityResolver::GetHashCode(const BinaryObject& 
obj)
         {
-            return impl::binary::BinaryUtils::GetDataHashCode(obj.GetData(), 
obj.GetLength());
+            return 
impl::binary::BinaryUtils::GetDataHashCode(obj.impl.GetData(), 
obj.impl.GetLength());
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/src/impl/binary/binary_object_header.cpp
----------------------------------------------------------------------
diff --git 
a/modules/platforms/cpp/binary/src/impl/binary/binary_object_header.cpp 
b/modules/platforms/cpp/binary/src/impl/binary/binary_object_header.cpp
index aef095f..3a9d182 100644
--- a/modules/platforms/cpp/binary/src/impl/binary/binary_object_header.cpp
+++ b/modules/platforms/cpp/binary/src/impl/binary/binary_object_header.cpp
@@ -18,6 +18,7 @@
 #include <ignite/ignite_error.h>
 
 #include <ignite/impl/binary/binary_object_header.h>
+#include <ignite/impl/binary/binary_utils.h>
 
 namespace ignite
 {
@@ -31,20 +32,31 @@ namespace ignite
                 {
                     
IGNITE_ERROR_FORMATTED_3(ignite::IgniteError::IGNITE_ERR_MEMORY,
                         "Not enough data in the binary object", "memPtr", 
mem.PointerLong(),
-                        "len", mem.Length(), "headerLen", SIZE);
+                        "len", (mem.Length() - offset), "headerLen", 
static_cast<int>(SIZE));
                 }
 
-                BinaryObjectHeader hdr(mem.Data() + offset);
+                int8_t type = BinaryUtils::UnsafeReadInt8(mem, offset);
+                if (type == impl::binary::IGNITE_TYPE_BINARY)
+                {
+                    int32_t binLen = BinaryUtils::UnsafeReadInt32(mem, offset 
+ IGNITE_COMMON_HDR_LEN);
+                    int32_t binOff = BinaryUtils::ReadInt32(mem, offset + 
IGNITE_BINARY_HDR_LEN + binLen);
 
-                int8_t type = hdr.GetType();
-                if (type != impl::binary::IGNITE_TYPE_OBJECT)
+                    return BinaryObjectHeader::FromMemory(mem, offset + 
IGNITE_BINARY_HDR_LEN + binOff);
+                }
+                else if (type != impl::binary::IGNITE_TYPE_OBJECT)
                 {
                     
IGNITE_ERROR_FORMATTED_3(ignite::IgniteError::IGNITE_ERR_MEMORY,
-                        "Not enough data in the binary object", "memPtr", 
mem.PointerLong(),
-                        "type", type, "expected", 
impl::binary::IGNITE_TYPE_OBJECT);
+                        "Not expected type header of the binary object", 
"memPtr", mem.PointerLong(),
+                        "type", (type & 0xFF),
+                        "expected", (impl::binary::IGNITE_TYPE_OBJECT & 0xFF));
                 }
 
-                return hdr;
+                return BinaryObjectHeader(mem.Data() + offset);
+            }
+
+            int8_t* BinaryObjectHeader::GetMem()
+            {
+                return reinterpret_cast<int8_t*>(header);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/src/impl/binary/binary_object_impl.cpp
----------------------------------------------------------------------
diff --git 
a/modules/platforms/cpp/binary/src/impl/binary/binary_object_impl.cpp 
b/modules/platforms/cpp/binary/src/impl/binary/binary_object_impl.cpp
index 8167f8b..0b397b1 100644
--- a/modules/platforms/cpp/binary/src/impl/binary/binary_object_impl.cpp
+++ b/modules/platforms/cpp/binary/src/impl/binary/binary_object_impl.cpp
@@ -26,28 +26,79 @@ namespace ignite
     {
         namespace binary
         {
-            BinaryObjectImpl::BinaryObjectImpl(impl::interop::InteropMemory& 
mem, int32_t start) :
-                mem(mem),
+            BinaryObjectImpl::BinaryObjectImpl(interop::InteropMemory& mem, 
int32_t start) :
+                mem(&mem),
                 start(start)
             {
                 // No-op.
             }
 
+            BinaryObjectImpl::BinaryObjectImpl(const BinaryObjectImpl& other) :
+                mem(other.mem),
+                start(other.start)
+            {
+                // No-op.
+            }
+
+            BinaryObjectImpl& BinaryObjectImpl::operator=(const 
BinaryObjectImpl& other)
+            {
+                mem = other.mem;
+
+                return *this;
+            }
+
+            BinaryObjectImpl 
BinaryObjectImpl::FromMemory(interop::InteropMemory& mem, int32_t offset)
+            {
+                BinaryObjectHeader header = 
BinaryObjectHeader::FromMemory(mem, offset);
+
+                int32_t adjustedStart = static_cast<int32_t>(header.GetMem() - 
mem.Data());
+
+                assert(adjustedStart >= 0);
+
+                return BinaryObjectImpl(mem, adjustedStart);
+            }
+
+            BinaryObjectImpl 
BinaryObjectImpl::FromMemoryUnsafe(interop::InteropMemory& mem, int32_t offset)
+            {
+                return BinaryObjectImpl(mem, offset);
+            }
+
+            BinaryObjectImpl BinaryObjectImpl::GetField(int32_t idx)
+            {
+                int32_t offset = start + BinaryObjectHeader::SIZE;
+
+                for (int32_t i = 0; i < idx; ++i)
+                {
+                    BinaryObjectHeader fieldHeader = 
BinaryObjectHeader::FromMemory(*mem, offset);
+
+                    offset += fieldHeader.GetLength();
+                }
+
+                return BinaryObjectImpl::FromMemory(*mem, offset);
+            }
+
             const int8_t* BinaryObjectImpl::GetData() const
             {
-                return mem.Data() + start + BinaryObjectHeader::SIZE;
+                return mem->Data() + start + BinaryObjectHeader::SIZE;
             }
 
             int32_t BinaryObjectImpl::GetLength() const
             {
-                BinaryObjectHeader header = 
BinaryObjectHeader::FromMemory(mem, start);
+                BinaryObjectHeader header(mem->Data() + start);
 
                 return header.GetDataLength();
             }
 
+            int32_t BinaryObjectImpl::GetTypeId() const
+            {
+                BinaryObjectHeader header(mem->Data() + start);
+
+                return header.GetTypeId();
+            }
+
             int32_t BinaryObjectImpl::GetHashCode() const
             {
-                BinaryObjectHeader header = 
BinaryObjectHeader::FromMemory(mem, start);
+                BinaryObjectHeader header(mem->Data() + start);
 
                 return header.GetHashCode();
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp
----------------------------------------------------------------------
diff --git 
a/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp 
b/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp
index a6692d1..2a7b617 100644
--- a/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp
+++ b/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp
@@ -113,7 +113,7 @@ namespace ignite
                 {
                     Snap* pendingSnap = it->Get();
 
-                    if (updater->Update(pendingSnap, err))
+                    if (updater->Update(pendingSnap, *err))
                     {
                         // Perform copy-on-write update of snapshot collection.
                         std::map<int32_t, SPSnap>* newSnapshots = new 
std::map<int32_t, SPSnap>();

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/Makefile.am 
b/modules/platforms/cpp/common/Makefile.am
index 8c79c3e..c4f4827 100644
--- a/modules/platforms/cpp/common/Makefile.am
+++ b/modules/platforms/cpp/common/Makefile.am
@@ -44,6 +44,7 @@ libignite_common_la_LDFLAGS = \
 libignite_common_la_SOURCES = \
     os/linux/src/common/concurrent_os.cpp \
     os/linux/src/common/platform_utils.cpp \
+    os/linux/src/common/dynamic_load_os.cpp \
     src/common/big_integer.cpp \
     src/common/concurrent.cpp \
     src/common/decimal.cpp \

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/include/ignite/common/concurrent.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/include/ignite/common/concurrent.h 
b/modules/platforms/cpp/common/include/ignite/common/concurrent.h
index ff0e54a..84a1f0e 100644
--- a/modules/platforms/cpp/common/include/ignite/common/concurrent.h
+++ b/modules/platforms/cpp/common/include/ignite/common/concurrent.h
@@ -401,7 +401,7 @@ namespace ignite
                  * @param lock Lockable object.
                  */
                 LockGuard(T& lock) :
-                    lock(lock)
+                    lock(&lock)
                 {
                     lock.Enter();
                 }
@@ -411,11 +411,34 @@ namespace ignite
                  */
                 ~LockGuard()
                 {
-                    lock.Leave();
+                    if (lock)
+                        lock->Leave();
+                }
+
+                /**
+                 * Releases control over lock without unlocking it.
+                 */
+                void Forget()
+                {
+                    lock = 0;
+                }
+
+                /**
+                 * Releases control over lock and unlocks it as if it would
+                 * go out of scope.
+                 */
+                void Reset()
+                {
+                    if (lock)
+                    {
+                        lock->Leave();
+
+                        Forget();
+                    }
                 }
 
             private:
-                T& lock;
+                T* lock;
             };
 
             typedef LockGuard<CriticalSection> CsLockGuard;

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/include/ignite/common/platform_utils.h
----------------------------------------------------------------------
diff --git 
a/modules/platforms/cpp/common/include/ignite/common/platform_utils.h 
b/modules/platforms/cpp/common/include/ignite/common/platform_utils.h
index 273a5e0..8674ce3 100644
--- a/modules/platforms/cpp/common/include/ignite/common/platform_utils.h
+++ b/modules/platforms/cpp/common/include/ignite/common/platform_utils.h
@@ -61,10 +61,10 @@ namespace ignite
          * Read system environment variable taking thread-safety in count.
          *
          * @param name Environment variable name.
-         * @param found Whether environment variable with such name was found.
-         * @return Environment variable value.
+         * @param val Environment variable value.
+         * @return True if the environment variable with such name was found.
          */
-        IGNITE_IMPORT_EXPORT std::string GetEnv(const std::string& name, bool& 
found);
+        IGNITE_IMPORT_EXPORT bool GetEnv(const std::string& name, std::string& 
val);
 
         /**
          * Ensure that file on the given path exists in the system.

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/include/ignite/ignite_error.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/include/ignite/ignite_error.h 
b/modules/platforms/cpp/common/include/ignite/ignite_error.h
index 4c5c06e..cecaf3f 100644
--- a/modules/platforms/cpp/common/include/ignite/ignite_error.h
+++ b/modules/platforms/cpp/common/include/ignite/ignite_error.h
@@ -277,7 +277,7 @@ namespace ignite
          * @param jniMsg Error message.
          * @param err Error. Can not be NULL.
          */
-        static void SetError(const int jniCode, const char* jniCls, const 
char* jniMsg, IgniteError* err);
+        static void SetError(const int jniCode, const char* jniCls, const 
char* jniMsg, IgniteError& err);
     private:
         /** Error code. */
         int32_t code;    

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/os/linux/include/ignite/common/dynamic_load_os.h
----------------------------------------------------------------------
diff --git 
a/modules/platforms/cpp/common/os/linux/include/ignite/common/dynamic_load_os.h 
b/modules/platforms/cpp/common/os/linux/include/ignite/common/dynamic_load_os.h
new file mode 100644
index 0000000..af07e57
--- /dev/null
+++ 
b/modules/platforms/cpp/common/os/linux/include/ignite/common/dynamic_load_os.h
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _IGNITE_COMMON_DYNAMIC_LOAD
+#define _IGNITE_COMMON_DYNAMIC_LOAD
+
+#include <string>
+
+#include "ignite/common/common.h"
+
+namespace ignite
+{
+    namespace common
+    {
+        namespace dynamic
+        {
+            /**
+             * Represents dynamically loadable program module such as dymanic
+             * or shared library.
+             */
+            class IGNITE_IMPORT_EXPORT Module
+            {
+            public:
+                /**
+                 * Default constructor.
+                 */
+                Module();
+
+                /**
+                 * Handle constructor.
+                 *
+                 * @param handle Os-specific Module handle.
+                 */
+                Module(void* handle);
+
+                /**
+                 * Destructor.
+                 */
+                ~Module();
+
+                /**
+                 * Copy constructor.
+                 *
+                 * @param other Other instance.
+                 */
+                Module(const Module& other);
+
+                /**
+                 * Copy constructor.
+                 *
+                 * @param other Other instance.
+                 * @return This.
+                 */
+                Module& operator=(const Module& other);
+
+                /**
+                 * Load symbol from Module.
+                 *
+                 * @param name Name of the symbol to load.
+                 * @return Pointer to symbol if found and NULL otherwise.
+                 */
+                void* FindSymbol(const char* name);
+
+                /**
+                 * Load symbol from Module.
+                 *
+                 * @param name Name of the symbol to load.
+                 * @return Pointer to symbol if found and NULL otherwise.
+                 */
+                void* FindSymbol(const std::string& name)
+                {
+                    return FindSymbol(name.c_str());
+                }
+
+                /**
+                 * Check if the instance is loaded.
+                 *
+                 * @return True if the instance is loaded.
+                 */
+                bool IsLoaded() const;
+
+                /**
+                 * Unload module.
+                 */
+                void Unload();
+
+            private:
+                void* handle;
+            };
+
+            /**
+             * Load Module by the specified path.
+             *
+             * @param path Path to the Module to load.
+             * @return Module instance.
+             */
+            IGNITE_IMPORT_EXPORT Module LoadModule(const char* path);
+
+            /**
+             * Load Module by the specified path.
+             *
+             * @param path Path to the Module to load.
+             * @return Module instance.
+             */
+            IGNITE_IMPORT_EXPORT Module LoadModule(const std::string& path);
+
+            /**
+             * Returns Module associated with the calling process itself.
+             *
+             * @return Module for the calling process.
+             */
+            IGNITE_IMPORT_EXPORT Module GetCurrent();
+        }
+    }
+}
+
+#endif

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/os/linux/src/common/dynamic_load_os.cpp
----------------------------------------------------------------------
diff --git 
a/modules/platforms/cpp/common/os/linux/src/common/dynamic_load_os.cpp 
b/modules/platforms/cpp/common/os/linux/src/common/dynamic_load_os.cpp
new file mode 100644
index 0000000..3ba562e
--- /dev/null
+++ b/modules/platforms/cpp/common/os/linux/src/common/dynamic_load_os.cpp
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dlfcn.h>
+
+#include <sstream>
+#include "ignite/common/dynamic_load_os.h"
+
+namespace ignite
+{
+    namespace common
+    {
+        namespace dynamic
+        {
+            Module::Module() : handle(NULL)
+            {
+                // No-op.
+            }
+
+            Module::Module(void* handle) : handle(handle)
+            {
+                // No-op.
+            }
+
+            Module::~Module()
+            {
+                // No-op.
+            }
+
+            Module::Module(const Module& other) : handle(other.handle)
+            {
+                // No-op.
+            }
+
+            Module& Module::operator=(const Module& other)
+            {
+                handle = other.handle;
+
+                return *this;
+            }
+
+            void* Module::FindSymbol(const char* name)
+            {
+                return dlsym(handle, name);
+            }
+
+            bool Module::IsLoaded() const
+            {
+                return handle != NULL;
+            }
+
+            void Module::Unload()
+            {
+                if (IsLoaded())
+                    dlclose(handle);
+            }
+
+            Module LoadModule(const char* path)
+            {
+                void* handle = dlopen(path, RTLD_NOW);
+
+                return Module(handle);
+            }
+
+            Module LoadModule(const std::string& path)
+            {
+                return LoadModule(path.c_str());
+            }
+
+            Module GetCurrent()
+            {
+                return LoadModule(NULL);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp
----------------------------------------------------------------------
diff --git 
a/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp 
b/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp
index a3e1d17..3e8d0c9 100644
--- a/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp
+++ b/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp
@@ -51,22 +51,16 @@ namespace ignite
             return localtime_r(&in, &out) == 0;
         }
 
-        std::string GetEnv(const std::string& name, bool& found)
+        bool GetEnv(const std::string& name, std::string& val)
         {
-            char* val = std::getenv(name.c_str());
+            char* val0 = std::getenv(name.c_str());
 
-            if (val)
-            {
-                found = true;
+            if (!val0)
+                return false;
 
-                return std::string(val);
-            }
-            else
-            {
-                found = false;
+            val = val0;
 
-                return std::string();
-            }
+            return true;
         }
 
         bool FileExists(const std::string& path)

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/os/win/include/ignite/common/dynamic_load_os.h
----------------------------------------------------------------------
diff --git 
a/modules/platforms/cpp/common/os/win/include/ignite/common/dynamic_load_os.h 
b/modules/platforms/cpp/common/os/win/include/ignite/common/dynamic_load_os.h
new file mode 100644
index 0000000..1936e21
--- /dev/null
+++ 
b/modules/platforms/cpp/common/os/win/include/ignite/common/dynamic_load_os.h
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _IGNITE_COMMON_DYNAMIC_LOAD
+#define _IGNITE_COMMON_DYNAMIC_LOAD
+
+#include <Windows.h>
+
+#include <string>
+
+#include "ignite/common/common.h"
+
+namespace ignite
+{
+    namespace common
+    {
+        namespace dynamic
+        {
+            /**
+             * Represents dynamically loadable program module such as dymanic
+             * or shared library.
+             */
+            class IGNITE_IMPORT_EXPORT Module
+            {
+            public:
+                /**
+                 * Default constructor.
+                 */
+                Module();
+
+                /**
+                 * Handle constructor.
+                 *
+                 * @param handle Os-specific Module handle.
+                 */
+                Module(HMODULE handle);
+
+                /**
+                 * Destructor.
+                 */
+                ~Module();
+
+                /**
+                 * Copy constructor.
+                 *
+                 * @param other Other instance.
+                 */
+                Module(const Module& other);
+
+                /**
+                 * Copy constructor.
+                 *
+                 * @param other Other instance.
+                 * @return This.
+                 */
+                Module& operator=(const Module& other);
+
+                /**
+                 * Load symbol from Module.
+                 *
+                 * @param name Name of the symbol to load.
+                 * @return Pointer to symbol if found and NULL otherwise.
+                 */
+                void* FindSymbol(const char* name);
+
+                /**
+                 * Load symbol from Module.
+                 *
+                 * @param name Name of the symbol to load.
+                 * @return Pointer to symbol if found and NULL otherwise.
+                 */
+                void* FindSymbol(const std::string& name)
+                {
+                    return FindSymbol(name.c_str());
+                }
+
+                /**
+                 * Check if the instance is loaded.
+                 *
+                 * @return True if the instance is loaded.
+                 */
+                bool IsLoaded() const;
+
+                /**
+                 * Unload module.
+                 */
+                void Unload();
+
+            private:
+                HMODULE handle;
+            };
+
+            /**
+             * Load Module by the specified path.
+             *
+             * @param path Path to the Module to load.
+             * @return Module instance.
+             */
+            IGNITE_IMPORT_EXPORT Module LoadModule(const char* path);
+
+            /**
+             * Load Module by the specified path.
+             *
+             * @param path Path to the Module to load.
+             * @return Module instance.
+             */
+            IGNITE_IMPORT_EXPORT Module LoadModule(const std::string& path);
+
+            /**
+             * Returns Module associated with the calling process itself.
+             *
+             * @return Module for the calling process.
+             */
+            IGNITE_IMPORT_EXPORT Module GetCurrent();
+        }
+    }
+}
+
+#endif

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/os/win/src/common/dynamic_load_os.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/os/win/src/common/dynamic_load_os.cpp 
b/modules/platforms/cpp/common/os/win/src/common/dynamic_load_os.cpp
new file mode 100644
index 0000000..f7812cd
--- /dev/null
+++ b/modules/platforms/cpp/common/os/win/src/common/dynamic_load_os.cpp
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sstream>
+#include <vector>
+
+#include "ignite/common/dynamic_load_os.h"
+
+namespace
+{
+    std::wstring StringToWstring(const std::string& str)
+    {
+        int wslen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), 
static_cast<int>(str.size()), NULL, 0);
+
+        if (!wslen)
+            return std::wstring();
+
+        std::vector<WCHAR> converted(wslen);
+
+        MultiByteToWideChar(CP_UTF8, 0, str.c_str(), 
static_cast<int>(str.size()), &converted[0], wslen);
+
+        std::wstring res(converted.begin(), converted.end());
+
+        return res;
+    }
+}
+
+namespace ignite
+{
+    namespace common
+    {
+        namespace dynamic
+        {
+            Module::Module() : handle(NULL)
+            {
+                // No-op.
+            }
+
+            Module::Module(HMODULE handle) : handle(handle)
+            {
+                // No-op.
+            }
+
+            Module::~Module()
+            {
+                // No-op.
+            }
+
+            Module::Module(const Module& other) : handle(other.handle)
+            {
+                // No-op.
+            }
+
+            Module& Module::operator=(const Module& other)
+            {
+                handle = other.handle;
+
+                return *this;
+            }
+
+            void* Module::FindSymbol(const char* name)
+            {
+                return GetProcAddress(handle, name);
+            }
+
+            bool Module::IsLoaded() const
+            {
+                return handle != NULL;
+            }
+
+            void Module::Unload()
+            {
+                if (IsLoaded())
+                    FreeLibrary(handle);
+            }
+
+            Module LoadModule(const char* path)
+            {
+                std::string strPath(path);
+
+                return LoadModule(strPath);
+            }
+
+            Module LoadModule(const std::string& path)
+            {
+                std::wstring convertedPath = StringToWstring(path);
+
+                HMODULE handle = LoadLibrary(convertedPath.c_str());
+
+                return Module(handle);
+            }
+
+            Module GetCurrent()
+            {
+                HMODULE handle = GetModuleHandle(NULL);
+
+                return Module(handle);
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp 
b/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp
index 16fd6ec..b8a445c 100644
--- a/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp
+++ b/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp
@@ -49,24 +49,18 @@ namespace ignite
             return localtime_s(&out, &in) == 0;
         }
 
-        std::string GetEnv(const std::string& name, bool& found)
+        bool GetEnv(const std::string& name, std::string& val)
         {
             char res0[32767];
 
-            DWORD envRes = GetEnvironmentVariableA(name.c_str(), res0, 32767);
+            DWORD envRes = GetEnvironmentVariableA(name.c_str(), res0, 
sizeof(res0) / sizeof(res0[0]));
 
-            if (envRes != 0)
-            {
-                found = true;
+            if (envRes == 0)
+                return false;
 
-                return std::string(res0);
-            }
-            else
-            {
-                found = false;
+            val.assign(res0);
 
-                return std::string();
-            }
+            return true;
         }
 
         bool FileExists(const std::string& path)
@@ -77,12 +71,10 @@ namespace ignite
 
             if (hnd == INVALID_HANDLE_VALUE)
                 return false;
-            else
-            {
-                FindClose(hnd);
 
-                return true;
-            }
+            FindClose(hnd);
+
+            return true;
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/project/vs/common.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/project/vs/common.vcxproj 
b/modules/platforms/cpp/common/project/vs/common.vcxproj
index 7a57ac0..ab9ce53 100644
--- a/modules/platforms/cpp/common/project/vs/common.vcxproj
+++ b/modules/platforms/cpp/common/project/vs/common.vcxproj
@@ -182,10 +182,12 @@
     <ClInclude Include="..\..\include\ignite\timestamp.h" />
     <ClInclude Include="..\..\os\win\include\ignite\common\common.h" />
     <ClInclude Include="..\..\os\win\include\ignite\common\concurrent_os.h" />
+    <ClInclude Include="..\..\os\win\include\ignite\common\dynamic_load_os.h" 
/>
     <ClInclude Include="targetver.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\os\win\src\common\concurrent_os.cpp" />
+    <ClCompile Include="..\..\os\win\src\common\dynamic_load_os.cpp" />
     <ClCompile Include="..\..\os\win\src\common\platform_utils.cpp" />
     <ClCompile Include="..\..\src\common\big_integer.cpp" />
     <ClCompile Include="..\..\src\common\bits.cpp" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/project/vs/common.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/project/vs/common.vcxproj.filters 
b/modules/platforms/cpp/common/project/vs/common.vcxproj.filters
index f08471e..063edd0 100644
--- a/modules/platforms/cpp/common/project/vs/common.vcxproj.filters
+++ b/modules/platforms/cpp/common/project/vs/common.vcxproj.filters
@@ -64,6 +64,9 @@
     <ClInclude Include="..\..\include\ignite\reference.h">
       <Filter>Code</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\os\win\include\ignite\common\dynamic_load_os.h">
+      <Filter>Code\common</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\include\ignite\common\platform_utils.h">
       <Filter>Code\common</Filter>
     </ClInclude>
@@ -96,6 +99,9 @@
     <ClCompile Include="..\..\src\common\bits.cpp">
       <Filter>Code\common</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\os\win\src\common\dynamic_load_os.cpp">
+      <Filter>Code\common</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\os\win\src\common\platform_utils.cpp">
       <Filter>Code\common</Filter>
     </ClCompile>

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/src/common/utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/src/common/utils.cpp 
b/modules/platforms/cpp/common/src/common/utils.cpp
index 27d2473..2b425c1 100644
--- a/modules/platforms/cpp/common/src/common/utils.cpp
+++ b/modules/platforms/cpp/common/src/common/utils.cpp
@@ -66,11 +66,12 @@ namespace ignite
                 return dest;
             }
 
-            return NULL;
+            return 0;
         }
 
         void ReleaseChars(char* val)
         {
+            // Its OK to delete null-pointer.
             delete[] val;
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/src/ignite_error.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/src/ignite_error.cpp 
b/modules/platforms/cpp/common/src/ignite_error.cpp
index 3076d7a..d20eda8 100644
--- a/modules/platforms/cpp/common/src/ignite_error.cpp
+++ b/modules/platforms/cpp/common/src/ignite_error.cpp
@@ -95,10 +95,10 @@ namespace ignite
         return GetText();
     }
 
-    void IgniteError::SetError(const int jniCode, const char* jniCls, const 
char* jniMsg, IgniteError* err)
+    void IgniteError::SetError(const int jniCode, const char* jniCls, const 
char* jniMsg, IgniteError& err)
     {
         if (jniCode == IGNITE_JNI_ERR_SUCCESS)
-            *err = IgniteError();
+            err = IgniteError();
         else if (jniCode == IGNITE_JNI_ERR_GENERIC)
         {
             // The most common case when we have Java exception "in hands" and 
must map it to respective code.
@@ -114,8 +114,8 @@ namespace ignite
 
                     if (jniMsg)
                         stream << ": " << jniMsg;
-                    
-                    *err = IgniteError(IGNITE_ERR_JVM_NO_CLASS_DEF_FOUND, 
stream.str().c_str());
+
+                    err = IgniteError(IGNITE_ERR_JVM_NO_CLASS_DEF_FOUND, 
stream.str().c_str());
                 }
                 else if (jniCls0.compare("java.lang.NoSuchMethodError") == 0)
                 {
@@ -126,58 +126,58 @@ namespace ignite
                     if (jniMsg)
                         stream << ": " << jniMsg;
 
-                    *err = IgniteError(IGNITE_ERR_JVM_NO_SUCH_METHOD, 
stream.str().c_str());
+                    err = IgniteError(IGNITE_ERR_JVM_NO_SUCH_METHOD, 
stream.str().c_str());
                 }
                 else if (jniCls0.compare("java.lang.IllegalArgumentException") 
== 0)
-                    *err = IgniteError(IGNITE_ERR_ILLEGAL_ARGUMENT, jniMsg);
+                    err = IgniteError(IGNITE_ERR_ILLEGAL_ARGUMENT, jniMsg);
                 else if (jniCls0.compare("java.lang.IllegalStateException") == 
0)
-                    *err = IgniteError(IGNITE_ERR_ILLEGAL_STATE, jniMsg);
+                    err = IgniteError(IGNITE_ERR_ILLEGAL_STATE, jniMsg);
                 else if 
(jniCls0.compare("java.lang.UnsupportedOperationException") == 0)
-                    *err = IgniteError(IGNITE_ERR_UNSUPPORTED_OPERATION, 
jniMsg);
+                    err = IgniteError(IGNITE_ERR_UNSUPPORTED_OPERATION, 
jniMsg);
                 else if (jniCls0.compare("java.lang.InterruptedException") == 
0)
-                    *err = IgniteError(IGNITE_ERR_INTERRUPTED, jniMsg);
+                    err = IgniteError(IGNITE_ERR_INTERRUPTED, jniMsg);
                 else if 
(jniCls0.compare("org.apache.ignite.cluster.ClusterGroupEmptyException") == 0)
-                    *err = IgniteError(IGNITE_ERR_CLUSTER_GROUP_EMPTY, jniMsg);
+                    err = IgniteError(IGNITE_ERR_CLUSTER_GROUP_EMPTY, jniMsg);
                 else if 
(jniCls0.compare("org.apache.ignite.cluster.ClusterTopologyException") == 0)
-                    *err = IgniteError(IGNITE_ERR_CLUSTER_TOPOLOGY, jniMsg);
+                    err = IgniteError(IGNITE_ERR_CLUSTER_TOPOLOGY, jniMsg);
                 else if 
(jniCls0.compare("org.apache.ignite.compute.ComputeExecutionRejectedException") 
== 0)
-                    *err = IgniteError(IGNITE_ERR_COMPUTE_EXECUTION_REJECTED, 
jniMsg);
+                    err = IgniteError(IGNITE_ERR_COMPUTE_EXECUTION_REJECTED, 
jniMsg);
                 else if 
(jniCls0.compare("org.apache.ignite.compute.ComputeJobFailoverException") == 0)
-                    *err = IgniteError(IGNITE_ERR_COMPUTE_JOB_FAILOVER, 
jniMsg);
+                    err = IgniteError(IGNITE_ERR_COMPUTE_JOB_FAILOVER, jniMsg);
                 else if 
(jniCls0.compare("org.apache.ignite.compute.ComputeTaskCancelledException") == 
0)
-                    *err = IgniteError(IGNITE_ERR_COMPUTE_TASK_CANCELLED, 
jniMsg);
+                    err = IgniteError(IGNITE_ERR_COMPUTE_TASK_CANCELLED, 
jniMsg);
                 else if 
(jniCls0.compare("org.apache.ignite.compute.ComputeTaskTimeoutException") == 0)
-                    *err = IgniteError(IGNITE_ERR_COMPUTE_TASK_TIMEOUT, 
jniMsg);
+                    err = IgniteError(IGNITE_ERR_COMPUTE_TASK_TIMEOUT, jniMsg);
                 else if 
(jniCls0.compare("org.apache.ignite.compute.ComputeUserUndeclaredException") == 
0)
-                    *err = 
IgniteError(IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, jniMsg);
+                    err = 
IgniteError(IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, jniMsg);
                 else if (jniCls0.compare("javax.cache.CacheException") == 0)
-                    *err = IgniteError(IGNITE_ERR_CACHE, jniMsg);
+                    err = IgniteError(IGNITE_ERR_CACHE, jniMsg);
                 else if 
(jniCls0.compare("javax.cache.integration.CacheLoaderException") == 0)
-                    *err = IgniteError(IGNITE_ERR_CACHE_LOADER, jniMsg);
+                    err = IgniteError(IGNITE_ERR_CACHE_LOADER, jniMsg);
                 else if 
(jniCls0.compare("javax.cache.integration.CacheWriterException") == 0)
-                    *err = IgniteError(IGNITE_ERR_CACHE_WRITER, jniMsg);
+                    err = IgniteError(IGNITE_ERR_CACHE_WRITER, jniMsg);
                 else if 
(jniCls0.compare("javax.cache.processor.EntryProcessorException") == 0)
-                    *err = IgniteError(IGNITE_ERR_ENTRY_PROCESSOR, jniMsg);
+                    err = IgniteError(IGNITE_ERR_ENTRY_PROCESSOR, jniMsg);
                 else if 
(jniCls0.compare("org.apache.ignite.cache.CacheAtomicUpdateTimeoutException") 
== 0)
-                    *err = IgniteError(IGNITE_ERR_CACHE_ATOMIC_UPDATE_TIMEOUT, 
jniMsg);
+                    err = IgniteError(IGNITE_ERR_CACHE_ATOMIC_UPDATE_TIMEOUT, 
jniMsg);
                 else if 
(jniCls0.compare("org.apache.ignite.cache.CachePartialUpdateException") == 0)
-                    *err = IgniteError(IGNITE_ERR_CACHE_PARTIAL_UPDATE, 
jniMsg);
+                    err = IgniteError(IGNITE_ERR_CACHE_PARTIAL_UPDATE, jniMsg);
                 else if 
(jniCls0.compare("org.apache.ignite.transactions.TransactionOptimisticException")
 == 0)
-                    *err = IgniteError(IGNITE_ERR_TX_OPTIMISTIC, jniMsg);
+                    err = IgniteError(IGNITE_ERR_TX_OPTIMISTIC, jniMsg);
                 else if 
(jniCls0.compare("org.apache.ignite.transactions.TransactionTimeoutException") 
== 0)
-                    *err = IgniteError(IGNITE_ERR_TX_TIMEOUT, jniMsg);
+                    err = IgniteError(IGNITE_ERR_TX_TIMEOUT, jniMsg);
                 else if 
(jniCls0.compare("org.apache.ignite.transactions.TransactionRollbackException") 
== 0)
-                    *err = IgniteError(IGNITE_ERR_TX_ROLLBACK, jniMsg);
+                    err = IgniteError(IGNITE_ERR_TX_ROLLBACK, jniMsg);
                 else if 
(jniCls0.compare("org.apache.ignite.transactions.TransactionHeuristicException")
 == 0)
-                    *err = IgniteError(IGNITE_ERR_TX_HEURISTIC, jniMsg);
+                    err = IgniteError(IGNITE_ERR_TX_HEURISTIC, jniMsg);
                 else if 
(jniCls0.compare("org.apache.ignite.IgniteAuthenticationException") == 0)
-                    *err = IgniteError(IGNITE_ERR_AUTHENTICATION, jniMsg);
+                    err = IgniteError(IGNITE_ERR_AUTHENTICATION, jniMsg);
                 else if 
(jniCls0.compare("org.apache.ignite.plugin.security.GridSecurityException") == 
0)
-                    *err = IgniteError(IGNITE_ERR_SECURITY, jniMsg);
+                    err = IgniteError(IGNITE_ERR_SECURITY, jniMsg);
                 else if (jniCls0.compare("org.apache.ignite.IgniteException") 
== 0)
-                    *err = IgniteError(IGNITE_ERR_GENERIC, jniMsg);
+                    err = IgniteError(IGNITE_ERR_GENERIC, jniMsg);
                 else if 
(jniCls0.compare("org.apache.ignite.IgniteCheckedException") == 0)
-                    *err = IgniteError(IGNITE_ERR_GENERIC, jniMsg);
+                    err = IgniteError(IGNITE_ERR_GENERIC, jniMsg);
                 else
                 {
                     std::stringstream stream;
@@ -189,13 +189,13 @@ namespace ignite
 
                     stream << "]";
 
-                    *err = IgniteError(IGNITE_ERR_UNKNOWN, 
stream.str().c_str());
+                    err = IgniteError(IGNITE_ERR_UNKNOWN, 
stream.str().c_str());
                 }                    
             }
             else
             {
                 // JNI class name is not available. Something really weird.
-                *err = IgniteError(IGNITE_ERR_UNKNOWN);
+                err = IgniteError(IGNITE_ERR_UNKNOWN);
             }
         }
         else if (jniCode == IGNITE_JNI_ERR_JVM_INIT)
@@ -218,9 +218,9 @@ namespace ignite
 
             stream << "]";
 
-            *err = IgniteError(IGNITE_ERR_JVM_INIT, stream.str().c_str());
+            err = IgniteError(IGNITE_ERR_JVM_INIT, stream.str().c_str());
         }
         else if (jniCode == IGNITE_JNI_ERR_JVM_ATTACH)
-            *err = IgniteError(IGNITE_ERR_JVM_ATTACH, "Failed to attach to 
JVM.");
+            err = IgniteError(IGNITE_ERR_JVM_ATTACH, "Failed to attach to 
JVM.");
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core-test/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/Makefile.am 
b/modules/platforms/cpp/core-test/Makefile.am
index 566a827..05b00b7 100644
--- a/modules/platforms/cpp/core-test/Makefile.am
+++ b/modules/platforms/cpp/core-test/Makefile.am
@@ -49,7 +49,8 @@ ignite_tests_LDADD = \
     -lboost_chrono
 
 ignite_tests_LDFLAGS = \
-    -static-libtool-libs
+    -static-libtool-libs \
+    -rdynamic
 
 ignite_tests_SOURCES = \
     src/reference_test.cpp \
@@ -62,6 +63,8 @@ ignite_tests_SOURCES = \
     src/ignition_test.cpp \
     src/interop_memory_test.cpp \
     src/interop_test.cpp \
+    src/cluster_test.cpp \
+    src/cache_invoke_test.cpp \
     src/handle_registry_test.cpp \
     src/ignite_error_test.cpp \
     src/binary_test_defs.cpp \

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h 
b/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
index 42f4539..2965797 100644
--- a/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
+++ b/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
@@ -84,6 +84,27 @@ namespace ignite_test
                 }
             };
 
+            struct PureRaw
+            {
+                std::string val1;
+                int32_t val2;
+
+                PureRaw() : val1(), val2()
+                {
+                    // No-op.
+                }
+
+                PureRaw(std::string val1, int32_t val2) : val1(val1), 
val2(val2)
+                {
+                    // No-op.
+                }
+
+                friend bool operator==(const PureRaw& one, const PureRaw& two)
+                {
+                    return one.val1 == two.val1 && one.val2 == two.val2;
+                }
+            };
+
             class DummyIdResolver : public 
ignite::impl::binary::BinaryIdResolver
             {
             public:
@@ -115,49 +136,41 @@ namespace ignite
         template<>
         struct BinaryType<gt::BinaryDummy>
         {
-            /** <inheritdoc /> */
             int32_t GetTypeId()
             {
                 return GetBinaryStringHashCode("BinaryDummy");
             }
 
-            /** <inheritdoc /> */
             std::string GetTypeName()
             {
                 return "BinaryDummy";
             }
 
-            /** <inheritdoc /> */
             int32_t GetFieldId(const char* name)
             {
                 return GetBinaryStringHashCode(name);
             }
 
-            /** <inheritdoc /> */
             int32_t GetHashCode(const gt::BinaryInner& obj)
             {
                 return obj.GetValue();
             }
 
-            /** <inheritdoc /> */
             bool IsNull(const gt::BinaryInner& obj)
             {
                 return obj.GetValue() == 0;
             }
 
-            /** <inheritdoc /> */
             gt::BinaryInner GetNull()
             {
                 return gt::BinaryInner(0);
             }
 
-            /** <inheritdoc /> */
             void Write(BinaryWriter& writer, const gt::BinaryDummy& obj)
             {
                 // No-op.
             }
 
-            /** <inheritdoc /> */
             gt::BinaryDummy Read(BinaryReader& reader)
             {
                 return gt::BinaryDummy();
@@ -167,49 +180,41 @@ namespace ignite
         template<> 
         struct BinaryType<gt::BinaryInner>
         {
-            /** <inheritdoc /> */
             int32_t GetTypeId() 
             { 
                 return GetBinaryStringHashCode("BinaryInner"); 
             }
 
-            /** <inheritdoc /> */
             std::string GetTypeName()
             {
                 return "BinaryInner";
             }
 
-            /** <inheritdoc /> */
             int32_t GetFieldId(const char* name) 
             { 
                 return GetBinaryStringHashCode(name); 
             }
 
-            /** <inheritdoc /> */
             int32_t GetHashCode(const gt::BinaryInner& obj)
             {
                 return obj.GetValue();
             }
 
-            /** <inheritdoc /> */
             bool IsNull(const gt::BinaryInner& obj)
             {
                 return obj.GetValue() == 0;
             }
 
-            /** <inheritdoc /> */
             gt::BinaryInner GetNull()
             {
                 return gt::BinaryInner(0);
             }
 
-            /** <inheritdoc /> */
             void Write(BinaryWriter& writer, const gt::BinaryInner& obj)
             {
                 writer.WriteInt32("val", obj.GetValue());
             }
 
-            /** <inheritdoc /> */
             gt::BinaryInner Read(BinaryReader& reader)
             {
                 int val = reader.ReadInt32("val");
@@ -221,50 +226,42 @@ namespace ignite
         template<>
         struct BinaryType<gt::BinaryOuter>
         {
-            /** <inheritdoc /> */
             int32_t GetTypeId()
             {
                 return GetBinaryStringHashCode("BinaryOuter");
             }
 
-            /** <inheritdoc /> */
             std::string GetTypeName()
             {
                 return "BinaryOuter";
             }
 
-            /** <inheritdoc /> */
             int32_t GetFieldId(const char* name)
             {
                 return GetBinaryStringHashCode(name);
             }
 
-            /** <inheritdoc /> */
             int32_t GetHashCode(const gt::BinaryOuter& obj)
             {
                 return obj.GetValue() + obj.GetInner().GetValue();
             }
 
-            /** <inheritdoc /> */
             bool IsNull(const gt::BinaryOuter& obj)
             {
                 return obj.GetValue() == 0 && obj.GetInner().GetValue();
             }
 
-            /** <inheritdoc /> */
             gt::BinaryOuter GetNull()
             {
                 return gt::BinaryOuter(0, 0);
             }
 
-            /** <inheritdoc /> */
             void Write(BinaryWriter& writer, const gt::BinaryOuter& obj)
             {
                 writer.WriteObject("inner", obj.GetInner());
                 writer.WriteInt32("val", obj.GetValue());                
             }
 
-            /** <inheritdoc /> */
             gt::BinaryOuter Read(BinaryReader& reader)
             {
                 gt::BinaryInner inner = 
reader.ReadObject<gt::BinaryInner>("inner");
@@ -277,43 +274,36 @@ namespace ignite
         template<>
         struct BinaryType<gt::BinaryFields>
         {
-            /** <inheritdoc /> */
             int32_t GetTypeId()
             {
                 return GetBinaryStringHashCode("BinaryFields");
             }
 
-            /** <inheritdoc /> */
             std::string GetTypeName()
             {
                 return "BinaryFields";
             }
 
-            /** <inheritdoc /> */
             int32_t GetFieldId(const char* name)
             {
                 return GetBinaryStringHashCode(name);
             }
 
-            /** <inheritdoc /> */
             int32_t GetHashCode(const gt::BinaryFields& obj)
             {
                 return obj.val1 + obj.val2 + obj.rawVal1 + obj.rawVal2;
             }
 
-            /** <inheritdoc /> */
             bool IsNull(const gt::BinaryFields& obj)
             {
                 return false;
             }
 
-            /** <inheritdoc /> */
             gt::BinaryFields GetNull()
             {
                 throw std::runtime_error("Must not be called.");
             }
 
-            /** <inheritdoc /> */
             void Write(BinaryWriter& writer, const gt::BinaryFields& obj)
             {
                 writer.WriteInt32("val1", obj.val1);
@@ -325,7 +315,6 @@ namespace ignite
                 rawWriter.WriteInt32(obj.rawVal2);
             }
 
-            /** <inheritdoc /> */
             gt::BinaryFields Read(BinaryReader& reader)
             {
                 int32_t val1 = reader.ReadInt32("val1");
@@ -339,6 +328,59 @@ namespace ignite
                 return gt::BinaryFields(val1, val2, rawVal1, rawVal2);
             }
         };
+
+        template<>
+        struct BinaryType<gt::PureRaw>
+        {
+            int32_t GetTypeId()
+            {
+                return GetBinaryStringHashCode("PureRaw");
+            }
+
+            std::string GetTypeName()
+            {
+                return "PureRaw";
+            }
+
+            int32_t GetFieldId(const char* name)
+            {
+                return GetBinaryStringHashCode(name);
+            }
+
+            int32_t GetHashCode(const gt::PureRaw& obj)
+            {
+                return GetBinaryStringHashCode(obj.val1.c_str()) ^ obj.val2;
+            }
+
+            bool IsNull(const gt::PureRaw& obj)
+            {
+                return false;
+            }
+
+            gt::PureRaw GetNull()
+            {
+                throw std::runtime_error("Must not be called.");
+            }
+
+            void Write(BinaryWriter& writer, const gt::PureRaw& obj)
+            {
+                BinaryRawWriter rawWriter = writer.RawWriter();
+
+                rawWriter.WriteString(obj.val1);
+                rawWriter.WriteInt32(obj.val2);
+            }
+
+            gt::PureRaw Read(BinaryReader& reader)
+            {
+                BinaryRawReader rawReader = reader.RawReader();
+
+                gt::PureRaw res;
+                res.val1 = rawReader.ReadString();
+                res.val2 = rawReader.ReadInt32();
+
+                return res;
+            }
+        };
     }
 }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj 
b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
index d39746e..607b5a0 100644
--- a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
+++ b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
@@ -42,6 +42,8 @@
     <ClCompile Include="..\..\src\binary_object_test.cpp" />
     <ClCompile Include="..\..\src\binary_identity_resolver_test.cpp" />
     <ClCompile Include="..\..\src\cache_test.cpp" />
+    <ClCompile Include="..\..\src\cluster_test.cpp" />
+    <ClCompile Include="..\..\src\cache_invoke_test.cpp" />
     <ClCompile Include="..\..\src\concurrent_test.cpp" />
     <ClCompile Include="..\..\src\decimal_test.cpp" />
     <ClCompile Include="..\..\src\dynamic_size_array_test.cpp" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
----------------------------------------------------------------------
diff --git 
a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters 
b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
index 22048b1..9c333eb 100644
--- a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
+++ b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
@@ -55,9 +55,15 @@
     <ClCompile Include="..\..\src\dynamic_size_array_test.cpp">
       <Filter>Code</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\cache_invoke_test.cpp">
+      <Filter>Code</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\src\interop_test.cpp">
       <Filter>Code</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\cluster_test.cpp">
+      <Filter>Code</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\src\continuous_query_test.cpp">
       <Filter>Code</Filter>
     </ClCompile>

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core-test/src/binary_object_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/binary_object_test.cpp 
b/modules/platforms/cpp/core-test/src/binary_object_test.cpp
index 0a8f948..fb3725f 100644
--- a/modules/platforms/cpp/core-test/src/binary_object_test.cpp
+++ b/modules/platforms/cpp/core-test/src/binary_object_test.cpp
@@ -53,7 +53,7 @@ void CheckSimple(const T& value)
 
     FillMem<T>(mem, value);
 
-    BinaryObject obj(mem, 0);
+    BinaryObject obj(BinaryObjectImpl::FromMemory(mem, 0));
 
     T actual = obj.Deserialize<T>();
 
@@ -67,7 +67,7 @@ void CheckSimpleNP(const T& value)
 
     FillMem<T>(mem, value);
 
-    BinaryObject obj(mem, 0);
+    BinaryObject obj(BinaryObjectImpl::FromMemory(mem, 0));
 
     T actual = obj.Deserialize<T>();
 
@@ -100,7 +100,7 @@ void CheckData(const T& obj)
     InteropUnpooledMemory mem(1024);
     FillMem<T>(mem, obj);
 
-    BinaryObjectImpl binObj(mem, 0);
+    BinaryObjectImpl binObj(BinaryObjectImpl::FromMemory(mem, 0));
 
     BOOST_REQUIRE_EQUAL(binObj.GetLength(), objData.GetSize());
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core-test/src/binary_reader_writer_raw_test.cpp
----------------------------------------------------------------------
diff --git 
a/modules/platforms/cpp/core-test/src/binary_reader_writer_raw_test.cpp 
b/modules/platforms/cpp/core-test/src/binary_reader_writer_raw_test.cpp
index b6d9eab..fbd0ce5 100644
--- a/modules/platforms/cpp/core-test/src/binary_reader_writer_raw_test.cpp
+++ b/modules/platforms/cpp/core-test/src/binary_reader_writer_raw_test.cpp
@@ -51,7 +51,7 @@ void CheckRawPrimitive(T val)
     BinaryRawReader rawReader(&reader);
 
     T readVal = Read<T>(rawReader);
-    
+
     BOOST_REQUIRE(readVal == val);
 }
 
@@ -1714,4 +1714,25 @@ BOOST_AUTO_TEST_CASE(TestMapTyped)
     CheckRawMap(&typ);
 }
 
+BOOST_AUTO_TEST_CASE(TestUserType)
+{
+    PureRaw expected("Hello Ignite from", 2017);
+
+    InteropUnpooledMemory mem(1024);
+
+    InteropOutputStream out(&mem);
+    BinaryWriterImpl writer(&out, NULL);
+
+    writer.WriteObject<PureRaw>(expected);
+
+    out.Synchronize();
+
+    InteropInputStream in(&mem);
+    BinaryReaderImpl reader(&in);
+
+    PureRaw actual = reader.ReadObject<PureRaw>();
+
+    BOOST_REQUIRE(actual == expected);
+}
+
 BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file

Reply via email to