I'm trying to do a static_cast at runtime in C# and as I understand it,
"as" is the keyword to use. Unfortunately, the compiler is trying to do
the cast a compilation time. See below.
/* TestA.cs */
namespace TEST {
class TestA {
public ushort val1;
public ushort val2;
public ushort val3;
}
}
/* Main Program */
namespace TEST {
class Program {
static void Main(string[] args) {
TestA test = null;
byte[] testArray = new byte[6];
for (int i = 0; i < testArray.Lengt h; i++) {
testArray[i] = (byte)(i + 1);
}
// Trying to do a C++-style static_cast
// Compilation error:
// Cannot convert type 'byte[]' to 'TEST.TestA'
// via a built-in conversion
test = testArray as TestA;
}
}
}
What am I doing wrong? 12 3314
Your assuming the data is sequentially stored and no other data exist in the
class, both assumptions are incorrect.
Normally you can serialize your class and desterilized but if the data needs
to be in a compact byte array which I have found need for several times you
will need to parse the data manually. I think you can overload the
serialization function but I have found the below simpler.
class TestA {
public ushort val1;
public ushort val2;
public ushort val3;
public TestA(byte[] data)
{
val1 = BitConverter.To UInt16(0);
val2 = BitConverter.To UInt16(2);
val3 = BitConverter.To UInt16(4);
}
public ToArray
{
get {
MemoryStream ms = new MemoryStream();
ms.Wirte(BitCon verter.GetBytes (val1, 0, 2);
ms.Wirte(BitCon verter.GetBytes (val2, 0, 2);
ms.Wirte(BitCon verter.GetBytes (val3, 0, 2);
ms.Capacity = ms.Length;
return ms.ToArray();
}
}
}
Regards,
John
"O.B." <fu******@bells outh.netwrote in message
news:12******** *****@corp.supe rnews.com...
I'm trying to do a static_cast at runtime in C# and as I understand it,
"as" is the keyword to use. Unfortunately, the compiler is trying to do
the cast a compilation time. See below.
/* TestA.cs */
namespace TEST {
class TestA {
public ushort val1;
public ushort val2;
public ushort val3;
}
}
/* Main Program */
namespace TEST {
class Program {
static void Main(string[] args) {
TestA test = null;
byte[] testArray = new byte[6];
for (int i = 0; i < testArray.Lengt h; i++) {
testArray[i] = (byte)(i + 1);
}
// Trying to do a C++-style static_cast
// Compilation error:
// Cannot convert type 'byte[]' to 'TEST.TestA'
// via a built-in conversion
test = testArray as TestA;
}
}
}
What am I doing wrong?
O.B. <fu******@bells outh.netwrote:
I'm trying to do a static_cast at runtime in C# and as I understand it,
"as" is the keyword to use. Unfortunately, the compiler is trying to do
the cast a compilation time. See below.
You can't do that in C# (thank goodness, IMO). You should either look
at serialization, or add a method to TestA to convert an array of bytes
(or a stream) into an instance of TestA.
--
Jon Skeet - <sk***@pobox.co m> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Oh by the way if you convert to a structure and set the offsets manually you
can then do a memory copy to accomplish what you did in C.
Sort of like this, don't do it as often so a little fuzzer on how.
[StructLayout(La youtKind.Explic it)]
public struct TestA
{
[FieldOffset(0)] public ushort Val1;
[FieldOffset(2)] public ushort Val2;
[FieldOffset(4)] public ushort Val2;
}
Marshal.Copy(Da ta, 0, IntPtr <TestA>, 6);
Regards,
John
"O.B." <fu******@bells outh.netwrote in message
news:12******** *****@corp.supe rnews.com...
I'm trying to do a static_cast at runtime in C# and as I understand it,
"as" is the keyword to use. Unfortunately, the compiler is trying to do
the cast a compilation time. See below.
/* TestA.cs */
namespace TEST {
class TestA {
public ushort val1;
public ushort val2;
public ushort val3;
}
}
/* Main Program */
namespace TEST {
class Program {
static void Main(string[] args) {
TestA test = null;
byte[] testArray = new byte[6];
for (int i = 0; i < testArray.Lengt h; i++) {
testArray[i] = (byte)(i + 1);
}
// Trying to do a C++-style static_cast
// Compilation error:
// Cannot convert type 'byte[]' to 'TEST.TestA'
// via a built-in conversion
test = testArray as TestA;
}
}
}
What am I doing wrong?
John J. Hughes II <no@invalid.com wrote:
Your assuming the data is sequentially stored and no other data exist in the
class, both assumptions are incorrect.
Normally you can serialize your class and desterilized but if the data needs
to be in a compact byte array which I have found need for several times you
will need to parse the data manually. I think you can overload the
serialization function but I have found the below simpler.
Note that for your solution, the line
ms.Capacity = ms.Length;
is unnecessary.
Personally, I'd prefer to create the 6 byte array to start with, and
then populate it. The "standard" BitConverter doesn't have any way to
convert into the middle of an existing array, but my own one does :)
See http://www.pobox.com/~skeet/csharp/miscutil and the
EndianBitConver ter class.
In this case, the code might be (converting it to a method rather than
a property);
public byte[] ToArray()
{
EndianBitConver ter converter = EndianBitConver ter.Little;
byte[] ret = new byte[6];
converter.CopyB ytes (val1, ret, 0);
converter.CopyB ytes (val2, ret, 2);
converter.CopyB ytes (val3, ret, 4);
return ret;
}
--
Jon Skeet - <sk***@pobox.co m> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Actually, the code is bit more complex than what I posted. I'm reading
data off of socket. In C++, I used a static_cast to cast the data to a
union. In C#, I have used StructLayout and FieldOffset to acquire the
"union" behavior. I just need the ability to overlay a structure
(perhaps better than a class for this use case) on top of that byte array.
The problem that I have with "as" when I use a struct is the following
error:
The as operator must be used with a reference type ('TEST.TestA' is a
value type)
Also, I really can't do an assignment on a per attribute basis. The
data received over the socket is in big endian. I prefer to store it in
big-endian and not waste any CPU cycles to convert it to little endian
(speed is key in this application). The implicit and explicit operators
are overridden to query header information from the data received. The
data is then forwarded over many other socket connections in big-endian
format; thus no byte-swapping conversions are required for the majority
of the received data.
Is there no way in C# to map a struct directly on top of a block of memory?
John J. Hughes II wrote:
Your assuming the data is sequentially stored and no other data exist in the
class, both assumptions are incorrect.
Normally you can serialize your class and desterilized but if the data needs
to be in a compact byte array which I have found need for several times you
will need to parse the data manually. I think you can overload the
serialization function but I have found the below simpler.
class TestA {
public ushort val1;
public ushort val2;
public ushort val3;
public TestA(byte[] data)
{
val1 = BitConverter.To UInt16(0);
val2 = BitConverter.To UInt16(2);
val3 = BitConverter.To UInt16(4);
}
public ToArray
{
get {
MemoryStream ms = new MemoryStream();
ms.Wirte(BitCon verter.GetBytes (val1, 0, 2);
ms.Wirte(BitCon verter.GetBytes (val2, 0, 2);
ms.Wirte(BitCon verter.GetBytes (val3, 0, 2);
ms.Capacity = ms.Length;
return ms.ToArray();
}
}
}
Regards,
John
"O.B." <fu******@bells outh.netwrote in message
news:12******** *****@corp.supe rnews.com...
>I'm trying to do a static_cast at runtime in C# and as I understand it, "as" is the keyword to use. Unfortunately, the compiler is trying to do the cast a compilation time. See below.
/* TestA.cs */ namespace TEST { class TestA { public ushort val1; public ushort val2; public ushort val3; } }
/* Main Program */ namespace TEST { class Program { static void Main(string[] args) { TestA test = null; byte[] testArray = new byte[6]; for (int i = 0; i < testArray.Lengt h; i++) { testArray[i] = (byte)(i + 1); } // Trying to do a C++-style static_cast // Compilation error: // Cannot convert type 'byte[]' to 'TEST.TestA' // via a built-in conversion test = testArray as TestA; } } }
What am I doing wrong?
This is *real* close to what I want. The only drawback is that I'm
having to instantiate new memory for the TestA structure before calling
Marshal. The UdpClient is already returning an allocated byte array.
This application has to run as close to real-time as possible.
TestA test;
byte[] testArray = new byte[6];
for (int i = 0; i < testArray.Lengt h; i++) {
testArray[i] = (byte)(i + 1);
}
Marshal.Copy(te stArray, 0, (IntPtr)(&test) , 6);
John J. Hughes II wrote:
Oh by the way if you convert to a structure and set the offsets manually you
can then do a memory copy to accomplish what you did in C.
Sort of like this, don't do it as often so a little fuzzer on how.
[StructLayout(La youtKind.Explic it)]
public struct TestA
{
[FieldOffset(0)] public ushort Val1;
[FieldOffset(2)] public ushort Val2;
[FieldOffset(4)] public ushort Val2;
}
Marshal.Copy(Da ta, 0, IntPtr <TestA>, 6);
Regards,
John
"O.B." <fu******@bells outh.netwrote in message
news:12******** *****@corp.supe rnews.com...
>I'm trying to do a static_cast at runtime in C# and as I understand it, "as" is the keyword to use. Unfortunately, the compiler is trying to do the cast a compilation time. See below.
/* TestA.cs */ namespace TEST { class TestA { public ushort val1; public ushort val2; public ushort val3; } }
/* Main Program */ namespace TEST { class Program { static void Main(string[] args) { TestA test = null; byte[] testArray = new byte[6]; for (int i = 0; i < testArray.Lengt h; i++) { testArray[i] = (byte)(i + 1); } // Trying to do a C++-style static_cast // Compilation error: // Cannot convert type 'byte[]' to 'TEST.TestA' // via a built-in conversion test = testArray as TestA; } } }
What am I doing wrong?
See my other post with [StructLayout(La youtKind.Explic it)] and Marshal.Copy.
Regards,
John
"O.B." <fu******@bells outh.netwrote in message
news:12******** *****@corp.supe rnews.com...
Actually, the code is bit more complex than what I posted. I'm reading
data off of socket. In C++, I used a static_cast to cast the data to a
union. In C#, I have used StructLayout and FieldOffset to acquire the
"union" behavior. I just need the ability to overlay a structure (perhaps
better than a class for this use case) on top of that byte array.
The problem that I have with "as" when I use a struct is the following
error:
The as operator must be used with a reference type ('TEST.TestA' is a
value type)
Also, I really can't do an assignment on a per attribute basis. The data
received over the socket is in big endian. I prefer to store it in
big-endian and not waste any CPU cycles to convert it to little endian
(speed is key in this application). The implicit and explicit operators
are overridden to query header information from the data received. The
data is then forwarded over many other socket connections in big-endian
format; thus no byte-swapping conversions are required for the majority of
the received data.
Is there no way in C# to map a struct directly on top of a block of
memory?
John J. Hughes II wrote:
>Your assuming the data is sequentially stored and no other data exist in the class, both assumptions are incorrect.
Normally you can serialize your class and desterilized but if the data needs to be in a compact byte array which I have found need for several times you will need to parse the data manually. I think you can overload the serialization function but I have found the below simpler.
class TestA { public ushort val1; public ushort val2; public ushort val3;
public TestA(byte[] data) { val1 = BitConverter.To UInt16(0); val2 = BitConverter.To UInt16(2); val3 = BitConverter.To UInt16(4); } public ToArray { get { MemoryStream ms = new MemoryStream(); ms.Wirte(BitCon verter.GetBytes (val1, 0, 2); ms.Wirte(BitCon verter.GetBytes (val2, 0, 2); ms.Wirte(BitCon verter.GetBytes (val3, 0, 2); ms.Capacity = ms.Length; return ms.ToArray(); } } }
Regards, John
"O.B." <fu******@bells outh.netwrote in message news:12******* ******@corp.sup ernews.com...
>>I'm trying to do a static_cast at runtime in C# and as I understand it, "as" is the keyword to use. Unfortunately, the compiler is trying to do the cast a compilation time. See below.
/* TestA.cs */ namespace TEST { class TestA { public ushort val1; public ushort val2; public ushort val3; } }
/* Main Program */ namespace TEST { class Program { static void Main(string[] args) { TestA test = null; byte[] testArray = new byte[6]; for (int i = 0; i < testArray.Lengt h; i++) { testArray[i] = (byte)(i + 1); } // Trying to do a C++-style static_cast // Compilation error: // Cannot convert type 'byte[]' to 'TEST.TestA' // via a built-in conversion test = testArray as TestA; } } }
What am I doing wrong?
Jon,
Most of my solutions (problems) have the wrong Endean so I also have a class
for converting. Maybe someday when I have time I will look at yours, you
might have some better ways of handling problems.
Yes you are correct about the ToArray, when I first write the function I was
using the GetBuffer function which was returning the entire capacity. I
later switch to the ToArray function and never removed it, thanks for the
pointer.
Regards,
John
"Jon Skeet [C# MVP]" <sk***@pobox.co mwrote in message
news:MP******** *************** *@msnews.micros oft.com...
John J. Hughes II <no@invalid.com wrote:
>Your assuming the data is sequentially stored and no other data exist in the class, both assumptions are incorrect.
Normally you can serialize your class and desterilized but if the data needs to be in a compact byte array which I have found need for several times you will need to parse the data manually. I think you can overload the serializatio n function but I have found the below simpler.
Note that for your solution, the line
ms.Capacity = ms.Length;
is unnecessary.
Personally, I'd prefer to create the 6 byte array to start with, and
then populate it. The "standard" BitConverter doesn't have any way to
convert into the middle of an existing array, but my own one does :)
See http://www.pobox.com/~skeet/csharp/miscutil and the
EndianBitConver ter class.
In this case, the code might be (converting it to a method rather than
a property);
public byte[] ToArray()
{
EndianBitConver ter converter = EndianBitConver ter.Little;
byte[] ret = new byte[6];
converter.CopyB ytes (val1, ret, 0);
converter.CopyB ytes (val2, ret, 2);
converter.CopyB ytes (val3, ret, 4);
return ret;
}
--
Jon Skeet - <sk***@pobox.co m> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
O.B. wrote:
I'm trying to do a static_cast at runtime in C# and as I understand it,
"as" is the keyword to use. Unfortunately, the compiler is trying to do
the cast a compilation time. See below.
/* TestA.cs */
namespace TEST {
class TestA {
public ushort val1;
public ushort val2;
public ushort val3;
}
}
/* Main Program */
namespace TEST {
class Program {
static void Main(string[] args) {
TestA test = null;
byte[] testArray = new byte[6];
for (int i = 0; i < testArray.Lengt h; i++) {
testArray[i] = (byte)(i + 1);
}
// Trying to do a C++-style static_cast
// Compilation error:
// Cannot convert type 'byte[]' to 'TEST.TestA'
// via a built-in conversion
test = testArray as TestA;
}
}
}
What am I doing wrong?
O.B.,
The other guys have explained quite well why you can't do it; and why you
shouldn't do it. You've got to remember C# is a managed programming
language, it doesn't usually have access to raw memory and the same types
of clevery you can do with C++, et al.
However, this is how you do it:
Firstly, define your TestA as a struct, and give it the attribute of
LayoutKind.Sequ ential:
///
[StructLayout(La youtKind.Sequen tial)]
public struct TestA
{
public ushort val1;
public ushort val2;
public ushort val3;
}
///
Then your new test method should read:
///
static void Main( string[] args )
{
TestA test;
byte[] testArray = new byte[6];
for ( int i = 0; i < testArray.Lengt h; i++ )
testArray[i] = (byte)(i + 1);
IntPtr arrayPtr = Marshal.UnsafeA ddrOfPinnedArra yElement( testArray, 0 );
test = (TestA) Marshal.PtrToSt ructure( p, typeof( TestA ) );
}
///
So, the start of the code is the same (loading your array), then the next
two lines perform the magic. The first gets a pointer to the start of the
byte array, and stores it in arrayPtr. The second then generates the
structure, given that pointer and the type of structure being generated.
--
Hope this helps,
Tom Spink
Google first, ask later. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Kevin |
last post by:
Hi
I try the following program and I get InvalidCastException at the line
MyByte b = (MyByte)obj;
If I change it to
MyByte b = (MyByte)d;
|
by: Jacob Jensen |
last post by:
This question has probably been asked a million time, but here it comes
again. I want to learn the difference between the three type cast operators:
static_cast, reinterpret_cast, dynamic_cast. A good way to do this is by
example. So I will give an example and please tell me what you think:
I have a base
class A
with a virtual destructor, and a
class B
that is it inherits publicly from A and defines som extra stuff.
|
by: vertigo |
last post by:
Hello
I have:
struct packet{
byte type; /*my byte is unsigned char*/
int len;
}
struct packet *p = new struct packet;
p->type=10;
p->len=0;
|
by: Harry |
last post by:
Hi ppl
Some problem regarding pointer:
ULONG *addr;
CHAR *ptr=NULL;
addr=new ULONG;
//calling a function and getting the addr value
//ULONG is 4 bytes. I am getting the Ip address which is naturally 4
|
by: Tamir Khason |
last post by:
Follwing the struct:
public struct TpSomeMsgRep
{
public uint SomeId;
| |
by: The Last Gunslinger |
last post by:
We have an enum:
public enum EnumDays
{
Sun = 1,
Mon = 2,
...
}
We can store it as a byte:
|
by: Ken Allen |
last post by:
I am relatively new to .Net, but have been using VB and C/C++ for years.
One of the drawbacks with VB6 and earlier was the difficulty in casting a
'record' to a different 'shape' so one could perform different manipulations
on it. For example, I have a complex data structure, which I can represent
in a VB6 TYPE declaration, but I cannot easily convert that to a fixed
length array of unsigned bytes so that I could perform a checksum...
|
by: Stacey Levine |
last post by:
I have a webservice that has the below procedure. Basically a procedure to
called a stored procedure and return the results. When I try to call the
webservice from my program I get the error. Both my calling code and the
webservice code are below. Thanks for your help.
D:\Projects .NET\StoreBO\frmVoids.vb(182): Value of type '1-dimensional
array of System.Data.SqlClient.SqlParameter' cannot be converted to
'1-dimensional array of...
|
by: AMP |
last post by:
Hello,
First, Thanks for ALL your help.
Second, another question:
I have some c code i am turning into c#:(truncated)
WORD calcChecksum(BYTE data, WORD length)
/* Calculates a checksum of "data".
*/
{
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
| |
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |