Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / September 2004

Tip: Looking for answers? Try searching our database.

Little Problem

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Angel J. Hern?ndez M - 13 Sep 2004 18:28 GMT
Hi folks! I'm having a little problem and I'm a bit confused about it.
See... I'm working on this VoIP project (I need to use make direct calls to
Windows API). I started working using C# but since I've got to access the
API constantly I'd rather write all low-level stuff in C++ and create the UI
using C#. So far so good... I created a sniffer socket (in order to
determine if it's H.323 compliant). This routine was written firstly in C#
but since I want to have all low level stuff in C++ I ported it to. Ok... My
problem is the next...

I have somthing like this (This code works OK)...

  protected virtual unsafe object[] ParseIPHeader(byte[] packet, int
length) {
   short src_port = 0, dst_port = 0;
   object[] retval = new object[6];

   fixed(byte* packetdata = packet) {
    CCommon.IPHeader* ipheader = (CCommon.IPHeader*) packetdata;
   // Rest of code goes here...
}

Here IPHeader is a struct I use to store IP packet's header... Then I have
the new C++ code...

Object* CRawSocket::ParseIPHeader(Byte packet[], int length)[] {
    short src_port = 0, dst_port = 0;
    System::Text::StringBuilder *src_address, *dst_address;
    Object *retval[] = new Object*[6];
    src_address = new System::Text::StringBuilder();
    dst_address = new System::Text::StringBuilder();

    Byte  *packeddata =    __try_cast< Byte *>(&packet[0]) ;
    CCommon::IPHeader *ipheader =  (CCommon::IPHeader *)  &packeddata;
    // Rest of code goes here...
}

My problem is that I don't get the same results even though it's almost the
same code :s

As we all know in C# we pass "addresses" so there's no need to write

fixed(byte* packetdata = &packet) // wrong!

but in the C++ world I need to pass the address

I've tried this...

Byte* packeddata =  packet; // I get error C2440: 'initializing' : cannot
convert from 'unsigned char  __gc[]' to 'unsigned char __gc *'
Byte  *packeddata =    __try_cast< Byte *>(&packet[0]); // This compiles OK
but it doesn't get the address I need :but the char value instead :s

I need some help with this... Any Ideas?

Thanks in advance

Byte  *packeddata =    __try_cast< Byte *>(&packet[0]) ;
Ben Schwehn - 13 Sep 2004 21:31 GMT
> fixed(byte* packetdata = &packet) // wrong!
>
> but in the C++ world I need to pass the address
>
> I've tried this...

I'm not entirly sure what you're trying to do but instead of c#'s fixed
what you'll probably want to do is use __pin something like

int __pin* p = &packet[0];

to get the address of packet and also pin the entire array

hth
Signature

Ben
http://bschwehn.de

Angel J. Hern?ndez M - 13 Sep 2004 21:57 GMT
Hi there... That's not the problem...

I've got a code written in C# and works fine but I call a lot of API
functions so I decided to write the low-level stuff in C++. My problem is
(not about __pin cuz I already try that). I have a struct which is
responsible for storing packet's IP Header. It's defined like this...

           [StructLayout(LayoutKind::Explicit)]
            __value struct IPHeader {
                [FieldOffset(0)] Byte verlen; // IP Version & IP Header
length
                [FieldOffset(1)] Byte tos; // Type of service
                [FieldOffset(2)] UInt16 length; // Packet's total length
                [FieldOffset(4)] UInt16 id; // Unique identifier
                [FieldOffset(6)] UInt16 offset; // Flags & Offset
                [FieldOffset(8)] Byte ttl; // Time To Live
                [FieldOffset(9)] Byte protocol; // Protocol (TCP, UDP, any
other)
                [FieldOffset(10)] UInt16 checksum; // IP Header checksum
                [FieldOffset(12)] Int64 source; // Source address
                [FieldOffset(16)] Int64 destination; // Destination address
                };

What I want to do (like I did in C# code) is... Fill all of the structs
fields by using a pointer...  In C# I have this code

protected virtual unsafe object[] ParseIPHeader(byte[] packet, int length)
{
   short src_port = 0, dst_port = 0;
   object[] retval = new object[6];

   fixed(byte* packetdata = packet) {
    CCommon.IPHeader* ipheader = (CCommon.IPHeader*) packetdata;
   // Rest of code goes here...
}

As you can see I fix my pointer and it's initialized with packet's address.
In C# I don't have to use the & operator for an operation like the one shown
above. My problem is that... I want to get the same result in C++.

Object* CRawSocket::ParseIPHeader(Byte packet[], int length)[] {
    short src_port = 0, dst_port = 0;
    System::Text::StringBuilder *src_address, *dst_address;
    Object *retval[] = new Object*[6];
    src_address = new System::Text::StringBuilder();
    dst_address = new System::Text::StringBuilder();

    Byte  *packeddata =    __try_cast< Byte *>(&packet[0]) ;
    CCommon::IPHeader *ipheader =  (CCommon::IPHeader *)  &packeddata;
    // Rest of code goes here...
}

I open two instances of VS Debugger (C# & C++ projects). The ipheader points
to  packeddata which in turn points to  the first element of the array
packet. This works perfectly in C# but it doesn't seem to work in C++. When
I compare both structures (C# & C++) the information contaned in them is
totally different when the data received from the socket is the same.

TIA

> > fixed(byte* packetdata = &packet) // wrong!
> >
[quoted text clipped - 10 lines]
>
> hth
Ben Schwehn - 13 Sep 2004 22:33 GMT
I would either use __pin to get an raw pointer and then use an unmanaged
native c++ struct (not a __value class) to reinterpret_cast to, or use
Marshal::PtrToStructure to get a managed struct. Don't know if this
helps you at all, sorry if it does not.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.