|
The GetObjectBytes does not return the bytes as expected. Consider the following code.
using System;
using System.IO;
using System.Threading;
using System.Text;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace CBinFormatter
{
///
/// Summary description for Class1.
///
class CBinFormatter
{
[Serializable()]
public struct sValues
{
public int iFirst;
public int iSecond;
public int iThird;
}
///
/// The main entry point for the application.
///
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
sValues sVal = new sValues();
sVal.iFirst = 100;
sVal.iSecond = 300;
sVal.iThird = 400;
byte [] btVal = GetObjectBytes(sVal);
Console.WriteLine("The size of the btVal is " + btVal.Length);
}
static byte[] GetObjectBytes(object o)
{
MemoryStream memstream = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(memstream, o);
memstream.Close(); // Prevent further writing
return memstream.GetBuffer();
}
static object GetObjectFromBytes(byte [] bytes)
{
MemoryStream memstream = new MemoryStream(bytes);
IFormatter formatter = new BinaryFormatter();
object o = formatter.Deserialize(memstream);
memstream.Close(); return o;
}
}
}
The Binary Serializer will return a size which is greater than the three int variables from the structure. Plus, when looking at the byte values within the debugger, I can't find the 100, 300, 400. I would of expected that the bytes returned would of been the size of 12 bytes " 3 int values - 4 bytes each". Do you know what I am missing here?
Tom McDaniel
|
|
|
|
|
The binary serializer includes information so that it can deserialize the data correctly. It includes type information (so that it can instantiate the object then load the data into it).
Eric Gunnerson pointed out a way to convert from a byte array to the object which is extremely easy; I haven't figured out how to get the byte array as easily though.
Here is a test program which shows how it works; compile with the /unsafe compiler switch.
using System;
using System.Runtime.InteropServices;
namespace Test
{
public struct Data
{
public int i;
public int j;
public int k;
}
public class Driver
{
public static void Main(string [] args)
{
byte [] bytes;
Data data;
Data foo;
data.i = 1;
data.j = 2;
data.k = 3;
bytes = ToByteArray(data);
foo = FromByteArrayToData(bytes);
System.Console.WriteLine("{0}, {1}, {2}", foo.i, foo.j, foo.k);
}
private static byte[] ToByteArray(object data)
{
int sizeofData = Marshal.SizeOf(data);
IntPtr pHData = Marshal.AllocHGlobal(sizeofData);
Marshal.StructureToPtr(data, pHData, true);
byte [] bytes = new byte[sizeofData];
Marshal.Copy(pHData, bytes, 0, sizeofData);
Marshal.FreeHGlobal(pHData);
return bytes;
}
unsafe private static Data FromByteArrayToData(byte[] bytes)
{
fixed(byte* pBytes = bytes)
{
return *((Data*) pBytes);
}
}
}
}
I'd be interested in knowing if there is a "short and sweet" version of the ToByteArray method. It seems like unsafe code could do the conversions, since it has no problems converting a byte array to an object.
James
Simplicity Rules!
|
|
|
|
|
Thanks again James. This is what I expected to see out of the byte array. Yes, I would also be interested in knowing a "short and sweet" version of the ToByteArray. Before using this forum, I was trying to do the same thing with C# pointers; but, I could never get what I needed. Then I started looking for a "memcpy" function in C#. I am guessing that the Marshal Object sort of does the same thing as the C++ memcpy function.
Thanks again,
Tom McDaniel
|
|
|
|
|
Hi!
I have following structures:
[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
struct ISEG
{
public short soffset; // segment position (offset)
public short slength; // segment length
public short segmode; // segment mode
}
[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
struct IIDX
{
public short inumseg; // number of segments
public IntPtr seg; // (ISEG*) segment information
// + some other data
}
So IIDX structure contains pointer to array of ISEG structures, inumseg defines how many structures there is in array.
And I have following DLL function that uses IIDX structure:
// short (__cdecl * Open)( pIIDX indexPtr );
[DllImport( "mydll.dll")]
private static extern short Open( ref IIDX indexPtr );
In unmanaged C/C++ you would use structure following way:
IIDX udtIndex;
ISEG udtBseg[2];
udtIndex.inumseg = 2;
udtIndex.seg = udtBseg;
udtBseg[0].soffset = 1;
udtBseg[0].slength = 2;
udtBseg[0].segmode = 1;
udtBseg[1].soffset = 3;
udtBseg[1].slength = 2;
udtBseg[1].segmode = 1;
Open( &udtIndex );
So, my problem is how I marshal ISEG array pointer to IIDX structure in C#? Should I first allocate memory for two ISEG structures, and then marshal each ISEG structures to right positions in the allocated memory? Or is there easier way to do marshaling (like function or attribute)? Could I use unsafe blocks to get pointer to the array? Any samples?
Thank you!
|
|
|
|
|
I'm trying to load a xml into a XmlDocument that have a DTD with a default attribute. And I only obtain a xml without the attributes. What am I doing wrong???
My code is:
using System;
using System.Xml;
namespace ConsoleApplication1
{
public class SchemaCollectionSample
{
public static void Main ()
{
XmlDocument x =new XmlDocument();
XmlTextReader reader = new XmlTextReader("book4.xml");
XmlValidatingReader vreader =new XmlValidatingReader(reader);
x.Load(vreader);
System.Console.Out.WriteLine(x.LastChild.OuterXml);
}
}
}
the Book.dtd is:
<!ELEMENT book (title,price)>
<!ATTLIST book
genre CDATA "novel"
ISBN CDATA #REQUIRED>
<!ELEMENT title (#PCDATA)>
<!ELEMENT price (#PCDATA)>
the book4.xml is:
<!DOCTYPE book SYSTEM 'book.dtd'>
<book ISBN = '1-861001-57-5'>
<title>Pride And Prejudice</title>
<price>19.95</price>
</book>
Crivo
Automated Credit Assessment
|
|
|
|
|
Whaaaaaaaaaat is that?
I've heard it too many times to keep this question in my hands, I just have to ask!
And where to learn, I know a liiiiiiitle in what it is... and it interest me to try build my servers as Windows services.
Where to learn Windows services in C# and C++....
Rickard Andersson@Suza Computing
ICQ#: 50302279 (Add me!)
E-mail: nikado@pc.nu
I'm from the winter country SWEDEN!
|
|
|
|
|
|
Thanks man!
But I just read it through fast, could you tell me why I should use a Windows service?
Can I run a Windows service in the background and the user can't close my app?
Rickard Andersson@Suza Computing
C# and C++ programmer from SWEDEN!
UIN: 50302279
E-Mail: nikado@pc.nu
Speciality: I love C# and C++!
|
|
|
|
|
Rickard Andersson wrote:
could you tell me why I should use a Windows service?
They run even without a user having to log in! Thus if you want to write a web server or something like that, you can write it as a service and leave the machine turned on, but nobody logged in. People can login and logout without any problem
Nish
Regards,
Nish
Native CPian.
Born and brought up on CP.
With the CP blood in him.
|
|
|
|
|
Aaah!
Then I know how it works and what's so specific with it!
I will try it out!
Rickard Andersson@Suza Computing
C# and C++ programmer from SWEDEN!
UIN: 50302279
E-Mail: nikado@pc.nu
Speciality: I love C# and C++!
|
|
|
|
|
Rickard Andersson wrote:
I will try it out!
Good Luck!
Nish
Regards,
Nish
Native CPian.
Born and brought up on CP.
With the CP blood in him.
|
|
|
|
|
One more question... the InstallFirstService, is it the program that "config the OS to start a service" when starting the OS, if you know what I mean?!
Rickard Andersson@Suza Computing
C# and C++ programmer from SWEDEN!
UIN: 50302279
E-Mail: nikado@pc.nu
Speciality: I love C# and C++!
|
|
|
|
|
Rickard Andersson wrote:
One more question... the InstallFirstService, is it the program that "config the OS to start a service" when starting the OS, if you know what I mean?!
InstallFirstService registers the service with the service control manager. Take a look at this class of mine which makes it easier for you to install/de-install services as well as start/stop/pause/continue services
CServiceHelper
Nish
Regards,
Nish
Native CPian.
Born and brought up on CP.
With the CP blood in him.
|
|
|
|
|
Nish - Native CPian wrote:
People can login and logout without any problem
Thats not exactly one of its strong selling points but hey its a point
|
|
|
|
|
When I associate a ContextMenu with a NotifyIcon, the MenuItems' Popup event doesn't fire, can anyone tell me if this is a bug inside the framework or am I doing something wrong ? I'm quite confused here...
|
|
|
|
|
See if this article helps. Else post some code snippets.
http://www.codeproject.com/csharp/trayiconmenu01.asp
Nish
Regards,
Nish
Native CPian.
Born and brought up on CP.
With the CP blood in him.
|
|
|
|
|
This article does't cover this I think Nish... Too bad I can't attach a file to this post.
But if you want to try it, or anyone else, just create a blank C# project, create a notifyicon, create a contextmenu with a child menuitem that has a childmenuitem on it's own. Now attach a popup event to the first menuitem (the one that contains a child). If you now attach this context menu to the form, this popup event fires, but if you attach it to the notifyicon, the event doesn't fire at all
|
|
|
|
|
If you make sure the trayicons' "Icon" property is set to a valid icon, you should be able to copy-paste the code below in an empty C# project:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace NotifyMenu
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.NotifyIcon TrayIcon;
private System.Windows.Forms.ContextMenu MnuContext;
private System.Windows.Forms.MenuItem MnuItem1;
private System.Windows.Forms.MenuItem MnuItem2;
private System.ComponentModel.IContainer components;
public Form1()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1));
this.TrayIcon = new System.Windows.Forms.NotifyIcon(this.components);
this.MnuContext = new System.Windows.Forms.ContextMenu();
this.MnuItem1 = new System.Windows.Forms.MenuItem();
this.MnuItem2 = new System.Windows.Forms.MenuItem();
//
// TrayIcon
//
this.TrayIcon.ContextMenu = this.MnuContext;
this.TrayIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("TrayIcon.Icon")));
this.TrayIcon.Text = "NotifyMenu Tray";
this.TrayIcon.Visible = true;
//
// MnuContext
//
this.MnuContext.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.MnuItem1});
//
// MnuItem1
//
this.MnuItem1.Index = 0;
this.MnuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.MnuItem2});
this.MnuItem1.Text = "Item 1";
this.MnuItem1.Popup += new System.EventHandler(this.MnuItem1_Popup);
//
// MnuItem2
//
this.MnuItem2.Index = 0;
this.MnuItem2.Text = "Item 2";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.ContextMenu = this.MnuContext;
this.Name = "Form1";
this.Text = "Form1";
}
#endregion
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void MnuItem1_Popup(object sender, System.EventArgs e)
{
MessageBox.Show(this, "Event Fired");
}
}
}
|
|
|
|
|
I am looking for something (in .NET and c#) like the good old ActiveX EXE: a component that loads its data at the first instantiation, but stays alive and doesn't have to be loaded the next time.
How can this be done in .NET with C#?
-Øyvind
|
|
|
|
|
I have an exercise:
Write any program in C#, but it must manage database. Examples: Program manage air flights, or manage trains, or manage a company...
Up to now, I don't know any things of C# ( I knew C++, MFC, Java before)
Can you give me any source code of C# about my problem that you have.
Thanks
Hung Son
A Vietnamese student
i-g.hypermart.net
dlhson2001@yahoo.com
|
|
|
|
|
There are all kinds of articles on here that describe how to do database work within C#. If you have a particular problem let someone know. I highly dought that you will find someone to do your exercise without pay.
Nick Parker
Actually, real programmers don't need the enter key- they just type in 00001101."
|
|
|
|
|
http://www.codeproject.com/useritems/csadoread01.asp
http://www.codeproject.com/useritems/csadodbintro01.asp
Nish
Regards,
Nish
Native CPian.
Born and brought up on CP.
With the CP blood in him.
|
|
|
|
|
Nish
Are you sick?
You always used to have the links click-able!
Rickard Andersson@Suza Computing
ICQ#: 50302279 (Add me!)
E-mail: nikado@pc.nu
I'm from the winter country SWEDEN!
|
|
|
|
|
Rickard Andersson wrote:
You always used to have the links click-able!
I am getting old, Rickard!
Nish
Regards,
Nish
Native CPian.
Born and brought up on CP.
With the CP blood in him.
|
|
|
|
|
Here's an article on a data abstraction component that'll help you out with connecting to and using a database.
HTH
Cheers,
Simon
"Every good work of software starts by scratching a developer's personal itch.", Eric S. Raymond
|
|
|
|