468,765 Members | 1,471 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,765 developers. It's quick & easy.

marshal binary data file, written with C++, with my C# code

I need to read binary data file written by C++ program, using my C#
application.
How do i marshal the bytes i read with my C# code to .NET types.

The data is numbers (integers float doubles etc..) and strings.

I looked at the Marshal class but did not know how to use it with file.
Please add few code lines.

Thanks alot

Jan 19 '06 #1
14 3650
bb
here is something i use for reading a string stored by C++ as an IntPtr
public class MarshalUtil
{
IntPtr m_objData = IntPtr.Zero;
int m_nPosition = 0;

public MarshalUtil(IntPtr objData)
{
m_objData = objData;
}

public string ReadString()
{
ArrayList objBytes = new ArrayList();
byte byt;
string strData = "";

while((byt = Marshal.ReadByte(m_objData, m_nPosition)) != 0)
{
strData += (char) byt;
m_nPosition += 2;
}

m_nPosition += 2;

return strData;
}

public bool MoreData
{
get
{
return (Marshal.ReadByte(m_objData, m_nPosition) != 0);
}
}
}

Jan 19 '06 #2
Thanks bb,

And what about integers float and doubles, how to marshal them ?

:)

Jan 19 '06 #3
bb wrote:
here is something i use for reading a string stored by C++ as an IntPtr

public class MarshalUtil
{
IntPtr m_objData = IntPtr.Zero;
int m_nPosition = 0;

public MarshalUtil(IntPtr objData)
{
m_objData = objData;
}

public string ReadString()
{
ArrayList objBytes = new ArrayList();
byte byt;
string strData = "";

while((byt = Marshal.ReadByte(m_objData, m_nPosition)) != 0)
{
strData += (char) byt;
m_nPosition += 2;
}

m_nPosition += 2;

return strData;
}


That will be hideously inefficient with large strings - you should at
the very least be using a StringBuilder. You also seem to be ignoring
every other byte - I don't believe the above will work with strings
containing Unicode characters above U+00FF. Instead, you should read
*two* bytes, and shift one left by 8 bits.

Jon

Jan 19 '06 #4
Vertilka wrote:
And what about integers float and doubles, how to marshal them ?


Have a look at Marshal.ReadInt32 (etc) for integers. For doubles you
should use Marshal.ReadInt64 and then call
BitConverter.Int64BitsToDouble. I'm not guaranteeing it will work, but
it's certainly worth a try.

Unfortunately there's no direct equivalent for that process for floats
(at least not in 1.1 - I haven't checked 2.0) - instead you'd probably
want to use BitConverter.ToSingle(byte[]) having read 4 bytes into a
byte array first.

Jon

Jan 19 '06 #5
You can always use the overload of the static Copy method which takes an
IntPtr and populates an array of doubles (or floats, there is an overload
for that as well). If you want one double/float, you can just declare an
array of one element (a little overkill, I know, but less code, right?).

Also, if the OP is willing to use unsafe code, then it could be much
easier (just cast to the appropriate pointer type and dereference).
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:11********************@g44g2000cwa.googlegrou ps.com...
Vertilka wrote:
And what about integers float and doubles, how to marshal them ?


Have a look at Marshal.ReadInt32 (etc) for integers. For doubles you
should use Marshal.ReadInt64 and then call
BitConverter.Int64BitsToDouble. I'm not guaranteeing it will work, but
it's certainly worth a try.

Unfortunately there's no direct equivalent for that process for floats
(at least not in 1.1 - I haven't checked 2.0) - instead you'd probably
want to use BitConverter.ToSingle(byte[]) having read 4 bytes into a
byte array first.

Jon

Jan 19 '06 #6
Jon, Nicholas,
Thanks for your answers.

Can you both post code snippets.
Lets say that i have 8 bytes that i want to get a bouble from them.

Thanks.

Jan 19 '06 #7
bb
yes its just used to get a known small length string from my device
driver

although im not sure thats an excuse for hideous code ;-)

Jan 19 '06 #8
Jon,

I tried you advise.
How do i convert array of bytes to IntPtr, to use with
Marshal.ReadInt32 ?

=== Code snippet ===

FileStream fs = new FileStream(@"C:\myfile.bin", FileMode.Open);

byte[] buffer = new byte[1024];
fs.Read(buffer, 0, 8);

Marshal.ReadInt64( ???? );

??? BitConverter.Int64BitsToDouble();

=== Code snippet ===

Jan 19 '06 #9

"Vertilka" <ve******@gmail.com> wrote in message
news:11**********************@g44g2000cwa.googlegr oups.com...
| Jon,
|
| I tried you advise.
| How do i convert array of bytes to IntPtr, to use with
| Marshal.ReadInt32 ?
|
| === Code snippet ===
|
| FileStream fs = new FileStream(@"C:\myfile.bin", FileMode.Open);
|
| byte[] buffer = new byte[1024];
| fs.Read(buffer, 0, 8);
|
| Marshal.ReadInt64( ???? );
|
| ??? BitConverter.Int64BitsToDouble();
|
| === Code snippet ===
|

Use the BinaryReader and wrap your FileStream, there is no need to call
Marshal methods, you simply need to call the right read method. Just beware
of the char encoding when reading cjar array's and strings.
string s1;
byte b1;
int i1;
float f1;
double d1;
char[] ca;

....
using(BinaryReader binReader =
new BinaryReader(File.Open(@".\myfile.bin", FileMode.Open)))
{
try {
while (true)
{
s1 = binReader.ReadString();
b1 = binReader.ReadByte();
i1 = binReader.ReadInt32();
f1 = binReader.ReadSingle();
d1 = binReader.ReadDouble();
ca = binReader.ReadChars(5);
Console.WriteLine(f1);
}
}
catch(EndOfStreamException ex)
{
// end of file reached
}
}

Willy.

Jan 19 '06 #10
Willy,

I don't know if you notice but the binary data file was written by C++.
I am not sure that type bits written into the binary file, using C++,
is the same as type bits writen using .NET.

Vertilka

Jan 19 '06 #11

"Vertilka" <ve******@gmail.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
| Willy,
|
| I don't know if you notice but the binary data file was written by C++.
| I am not sure that type bits written into the binary file, using C++,
| is the same as type bits writen using .NET.
|
| Vertilka
|

This is the first thing you should try to find out, right? You can't read a
file if you don't know the data types used in the file.
You said it's a binary data file, where is the data file written? On what
system (Windows, Unix, mainframe). Things to look for are endianess, char
encoding and eventual padding. If the file is written on Windows system,
then you are almost certain that the binary and floating point types are
exactly the same, more problematic are the char arrays and strings (which
are basically the same as arrays of chars once serialized), here you have to
know the encoding used so that you know how to read and to decode them.

Willy.


Jan 19 '06 #12
Vertilka <ve******@gmail.com> wrote:
Jon, Nicholas,
Thanks for your answers.

Can you both post code snippets.
Lets say that i have 8 bytes that i want to get a bouble from them.


double d = BitConverter.Int64BitsToDouble(Marshall.ReadInt64( ...));

Of course, that assumes it's in the right format. Worth trying to see.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 19 '06 #13
again, friends...

i have a byte array with data.
i know for example that the first 8 bytes are double.

now.
with this line:
double d = BitConverter.Int64BitsToDouble(Marshall.ReadInt64( ...));
i need to give intptr to ReadInt64.
how to convert byte array to intptr

thanks.

Jan 20 '06 #14
Vertilka <ve******@gmail.com> wrote:
again, friends...

i have a byte array with data.
i know for example that the first 8 bytes are double.
In that case I'm not sure where the Marshal class comes in at all.
That's what's been confusing us, I suspect.
now.
with this line:
double d = BitConverter.Int64BitsToDouble(Marshall.ReadInt64( ...));
i need to give intptr to ReadInt64.
how to convert byte array to intptr


Use BitConverter.ToDouble then.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 20 '06 #15

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by knapak | last post: by
4 posts views Thread by Michael McGarry | last post: by
21 posts views Thread by Mike | last post: by
2 posts views Thread by Edvin | last post: by
3 posts views Thread by masood.iqbal | last post: by
13 posts views Thread by swetha | last post: by
10 posts views Thread by rory | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by Marin | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.