Solved

serializing an object of the managed C++ wrapper class

Posted on 2006-10-27
11
511 Views
Last Modified: 2013-12-03
Hello,
I am working on an ASP.NET web application in C# in which I had to use a native (pure) C++ class as it was.  So I created a managed C++ wrapper class for this class. I create an object of this wrapper class and serialize it and pass it over the network using sockets.  The problem is serialization of this object produces a runtime error.
This is my code.
--------------------------------
#pragma once                 //(listParam.h)      this is the unmanaged class  
class listParam        
{
    char name[31];
    public:
     listParam(void){};
     int getSize(){return 0};
};
------------------------------

#pragma once               //(managed_cpp.h)     this is the wrapper class.
using namespace System;
#include "..\native_cpp\listparam.h"
namespace managed_cpp
{
     public __gc class MlistParam
     {
            public:
               MlistParam()     { m_pC = new listParam(); }
               int MgetSize() { return m_pC->getSize(); }
            private:
               listParam * m_pC;                                              //I think C# can't serialize it because of this member.
     };
}
----------------------------------------------------------
//serialization code
managed_cpp.MlistParam packet = new managed_cpp.MlistParam();
System.IO.MemoryStream ms = new System.IO.MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, packet);                                                     //This line produces the following runtime error.
------------------------------------------------------------

Exception Details: System.Runtime.Serialization.SerializationException: The type System.Reflection.Pointer in Assembly mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 is not marked as serializable.

Please help. Thank you.

0
Comment
Question by:engg
  • 6
  • 4
11 Comments
 
LVL 2

Expert Comment

by:andrewjmears
ID: 17824372
This article looks like it might point you in the right direction?
http://www.codeproject.com/dotnet/Surrogate_Serialization.asp
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 17824698
If you don't need to serialize m_pC member, mark is with NonSerialized attribute.
If you need to serialize it by some custom way, derive MlistParam from ISerializable and implement your own serialization logic in ISerializable functions.
0
 

Author Comment

by:engg
ID: 17833917
Thanks.

I need to serialize the object of the listParam (native C++ class) because ultimately I need to send that object over the network. How do I do that?
Do I need to serialize the object of its managed C++ wrapper class which contains just a pointer (m_pC ) to its native C++ object? Do I need to serialize the pointer? because that pointer is causing the problem.
Please help.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 17834103
You need to convert this pointer to some well-known type, like String^. Pointer itself cannot be serialized, because after deserialization it points to arbitrary memory location. Read about serialization here:
http://www.codeproject.com/csharp/objserial.asp

This is C#, but any C++ developer understands C#. Read "Define Serialization functions" paragraph. When object is serialized (GetObjectData), extract name from m_pC, convert is to String^ and write to SerializationInfo. When object is deserialized (constructor with SerializationInfo parameter), read String^ from SerializationInfo, create new listParam instance,  convert String^ to char* and fill name field.
0
 

Author Comment

by:engg
ID: 17834197
Thanks Alex. I am going to read it now.

The native C++ class listParam contains 4 private members and a few functions, which I didn't mention before.
Sorry about that. I just want to make sure if that changes the way its serialization should be implemented.

class listParam
{
    char name[31];
    bool include;
    short size;
    char dummy[64*1024];

    public:
    listParam(void);
    ~listParam(void);
    bool isInclude();
    int getSize();
    void addString(const char *str);
    const char *getString(char **p);
}
      

0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 48

Expert Comment

by:AlexFM
ID: 17834229
Convert all these members to something that .NET knows: String^, array<Byte>^ etc. and implement serialization/deserialization code.
0
 

Author Comment

by:engg
ID: 17834701
Thanks. When I send it over the network, on the other side, there is going to be just the native C++ class (listParam) code. There is no C# once the object is sent, so it will be deserialized using C++. My job is just to send it from my side.
0
 

Author Comment

by:engg
ID: 17834943
so should I convert all these members of the C++ class to their .NET equivalent in the wrapper? How will C++ deserialize the native C++ class object then?
0
 
LVL 48

Accepted Solution

by:
AlexFM earned 500 total points
ID: 17836156
If deserialization is done by unmanaged C++ class, this changes requirements to algorithm. You need to define protocol by the way that object serialized by .NET code can be read by unmanaged code. The simplest way is to redirect serialization to unmanaged class. For example, you can add two functions to unmanaged class:
int GetSize();   // return number of bytes required by serialization
void Serialize(char* buffer);   // serialize to buffer allocated by caller

C++/.NET class asks unmanaged class for required size, allocates Array<Byte>^ of required size, and calls m_PC->Serialize with pinned pointer to byte array. m_PC writes itself to this array, and .NET class writes array to SerializationInfo.
Write also function Deserialize in listParam class which restores class member from char* buffer.

0
 

Author Comment

by:engg
ID: 17837820
Thanks Alex. I will try this out.  I have been given something else to work on right now.  Thanks for your quick responses.
I will get back to you soon.
0
 

Author Comment

by:engg
ID: 17893840
I am looking into messagequeue class in .NET.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Summary: Persistence is the capability of an application to store the state of objects and recover it when necessary. This article compares the two common types of serialization in aspects of data access, readability, and runtime cost. A ready-to…
We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now