473,406 Members | 2,208 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

A failing oif C#?

I have been using C# for some time now, and for the most part I am very
impressed, and prefer using it over C++. There is one area where C#/.Net
seem, at least to me, to be less than desirable compared to C/C++, and
that is in the area of communication with buffer mappings. I know about
interop, and have programmed a significant amount of code this way, but
it is a real pain compared to using C++, unless I am missing something,
which is quite possible.

My current problem domain is using pass-through commands to control a
SCSI device. It does not matter what the device is, as the issues I am
attempting to deal with are generic in nature.

The SCSI command protocol supports commands of various fixed length,
from 6 to 12 bytes. Many of the bytes have individual meaning, some have
per-bit meanings, and in other cases more than one byte are combined to
have meaning. For example, consider the 10-byte READ command, which is
defined as follows:

28 XX LL LL LL LL 00 TL TL 00

Where:
28 - is the 10-byte read command in hex
XX - is a byte where
bits 0:2 are reserved
bit 3 is the FUA bit
bit 4 is the DPO bit
bits 5-7 are the LUN (typically zero)
LL - these four bytes represent the logical block address
TL - these two bytes inidicate the number of sectors to be read

In C++ it is fairly simple, albeit tedious, to define a structure for
each of the different command structures, cast the actual command buffer
address to the appropriate structure pointer, and then fill in the
command buffer with some informative code. In C# the structures can each
be defined, but then one has to marshal the data into the buffer; there
does not seem to be any effective method by which the code can convert
the structure into a byte array, or vice versa.

While the commands can be handled using member functions that take
parameters and convert the information directly into a byte array, that
approach is not so clean for the results of a SCSI command.

Consider the MODE SENSE command, which can return one or more pages of
information. The return buffer is a byte stream that contains special
structures which are optionally present. For example, there is a buffer
header sructure that describes the overall content of the buffer,
followed by the specified number of data pages, which each have a
special header that identifies the actual page content, followed by the
page itself. Again, in C++ we can read the byte(s) that define the
specific page and then cast a structure pointer permitting us to access
the contents of the page in a meaningful manner. In C#, we can read the
individual byte(s) to determine the page type, but must then use interop
to copy the information from the buffer into a structure for reference.

Even worse is when I want to use a MODE SELECT command and pass two or
more pages of information. Creating the information in a structure
object (or a class) and then serializing it into the buffer is a pain c
compared to the methods I can use in C++.

Is there no way to avoid all this use of marshalling code to achieve
structured access to the contents of the data buffers? It seems to me
that the amount of code that I have to write to achieve this in C# is
almost twice what I can get away with in C++, which just seems wrong,
somehow. I know that pointers are not part of the C# landscape, but this
need to convert between a structure/class and a byte stream or array
seems to be something that should be made much easier than it is.
Especially because this is 'unsafe' code and must exist in a separate
assembly from my main code (or at least the compiler errors tell me so).

-ken
Nov 17 '05 #1
11 1329
You can infact mark a section of your c# code unsafe and use pointers
just like c++.

Nov 17 '05 #2

"Ken Allen" <ke******@sympatico.ca> wrote in message
news:eP**************@TK2MSFTNGP09.phx.gbl...
I have been using C# for some time now, and for the most part I am very
impressed, and prefer using it over C++. There is one area where C#/.Net
seem, at least to me, to be less than desirable compared to C/C++, and that
is in the area of communication with buffer mappings. I know about interop,
and have programmed a significant amount of code this way, but it is a real
pain compared to using C++, unless I am missing something, which is quite
possible.

My current problem domain is using pass-through commands to control a SCSI
device. It does not matter what the device is, as the issues I am
attempting to deal with are generic in nature.

The SCSI command protocol supports commands of various fixed length, from
6 to 12 bytes. Many of the bytes have individual meaning, some have
per-bit meanings, and in other cases more than one byte are combined to
have meaning. For example, consider the 10-byte READ command, which is
defined as follows:

28 XX LL LL LL LL 00 TL TL 00

Where:
28 - is the 10-byte read command in hex
XX - is a byte where
bits 0:2 are reserved
bit 3 is the FUA bit
bit 4 is the DPO bit
bits 5-7 are the LUN (typically zero)
LL - these four bytes represent the logical block address
TL - these two bytes inidicate the number of sectors to be read

In C++ it is fairly simple, albeit tedious, to define a structure for each
of the different command structures, cast the actual command buffer
address to the appropriate structure pointer, and then fill in the command
buffer with some informative code. In C# the structures can each be
defined, but then one has to marshal the data into the buffer; there does
not seem to be any effective method by which the code can convert the
structure into a byte array, or vice versa.

While the commands can be handled using member functions that take
parameters and convert the information directly into a byte array, that
approach is not so clean for the results of a SCSI command.

Consider the MODE SENSE command, which can return one or more pages of
information. The return buffer is a byte stream that contains special
structures which are optionally present. For example, there is a buffer
header sructure that describes the overall content of the buffer, followed
by the specified number of data pages, which each have a special header
that identifies the actual page content, followed by the page itself.
Again, in C++ we can read the byte(s) that define the specific page and
then cast a structure pointer permitting us to access the contents of the
page in a meaningful manner. In C#, we can read the individual byte(s) to
determine the page type, but must then use interop to copy the information
from the buffer into a structure for reference.

Even worse is when I want to use a MODE SELECT command and pass two or
more pages of information. Creating the information in a structure object
(or a class) and then serializing it into the buffer is a pain c compared
to the methods I can use in C++.

Is there no way to avoid all this use of marshalling code to achieve
structured access to the contents of the data buffers? It seems to me that
the amount of code that I have to write to achieve this in C# is almost
twice what I can get away with in C++, which just seems wrong, somehow. I
know that pointers are not part of the C# landscape, but this need to
convert between a structure/class and a byte stream or array seems to be
something that should be made much easier than it is. Especially because
this is 'unsafe' code and must exist in a separate assembly from my main
code (or at least the compiler errors tell me so).

-ken


You use the wrong language/framework for the Job, why not stick with C++ for
this?

Willy.


Nov 17 '05 #3
wa********@yahoo.com wrote:
You can infact mark a section of your c# code unsafe and use pointers
just like c++.

How does one mark a section unsafe and have the code before and after
that section as safe (managed) code?

How does one use pointers at all in C#? Even in unsafe code? If I have a
buffer, which is probably defined as a byte array, how do I 'cast' a
subset of that array to be treated as a structure with data members? The
only way I have seen is to marshal a (cast as IntPtr) specific subset of
the array into a structure.

-ken
Nov 17 '05 #4
Perhaps, but one must do as one must when a corporate standard is
imposed; in this case, the decision was made to use C# for a specific
set of projects, partially as an exercise to determine where all of the
'bones were buried' and to determine whether C# should be used for
corporate projects at all.

-ken

Willy Denoyette [MVP] wrote:
"Ken Allen" <ke******@sympatico.ca> wrote in message
news:eP**************@TK2MSFTNGP09.phx.gbl...

<snip/>

-ken

You use the wrong language/framework for the Job, why not stick with C++ for
this?

Willy.

Nov 17 '05 #5
Ken,
On the flip side to Willy's comments: It sounds like you are using wrong
project for the pilot. If this is a pilot project, I hope this project
typifies other corporate projects, otherwise you may be throwing out the
correct tool (C#), based on attempting to implement the wrong project.

I find it "Better" to use the correct tool for the correct job, rather then
attempt to show horn all jobs into a single tool. Of course its also
important not to collect TOO many tools...

In this case use C# for corporate projects, except were it makes sense to
use C++ for a class library or two...

Hope this helps
Jay

"Ken Allen" <ke******@sympatico.ca> wrote in message
news:%2******************@TK2MSFTNGP09.phx.gbl...
| Perhaps, but one must do as one must when a corporate standard is
| imposed; in this case, the decision was made to use C# for a specific
| set of projects, partially as an exercise to determine where all of the
| 'bones were buried' and to determine whether C# should be used for
| corporate projects at all.
|
| -ken
|
| Willy Denoyette [MVP] wrote:
| > "Ken Allen" <ke******@sympatico.ca> wrote in message
| > news:eP**************@TK2MSFTNGP09.phx.gbl...
| >
| > <snip/>
| >>
| >>-ken
| >
| >
| > You use the wrong language/framework for the Job, why not stick with C++
for
| > this?
| >
| > Willy.
| >
| >
| >
| >
Nov 17 '05 #6
Well IMO this "One tool fits it all" approach won't work. Most complex
projects or what you call 'corporate projects' will need more than one
language for the job, simply because one language is better suited for a
specific programming task than another.
The same is true for frameworks like .NET, some task will fit perfectly in
this environment, while others can't tolerate the presence of a runtime
component like the CLR (think of Kernel components, drivers etc..). Others
tasks will require a mixture of languages and frameworks, and in my opinion
your project will need the inclusion of C++, maybe managed maybe native, for
the task at hand. Note I'm talking about tasks, not complete projects.
IMO it's perfectly possible to have a mixture of C# and C++, where the C++
is better suited for low level device oriented C style API's usage, where
efficiency, both in terms of space (memory, CPU resources) and time (spent
in transitions between managed and unmanaged code/memory), is more important
than rapid development cycles where C# might be the tool of choice.
Note also that I didn't say it's not possible to use C# to drive some low
level stuff, I only said it's not the right tool to use and it might lead to
frustration when thing tend to be harder than expected.

Willy.

"Ken Allen" <ke******@sympatico.ca> wrote in message
news:%2******************@TK2MSFTNGP09.phx.gbl...
Perhaps, but one must do as one must when a corporate standard is imposed;
in this case, the decision was made to use C# for a specific set of
projects, partially as an exercise to determine where all of the 'bones
were buried' and to determine whether C# should be used for corporate
projects at all.

-ken

Willy Denoyette [MVP] wrote:
"Ken Allen" <ke******@sympatico.ca> wrote in message
news:eP**************@TK2MSFTNGP09.phx.gbl...

<snip/>

-ken

You use the wrong language/framework for the Job, why not stick with C++
for this?

Willy.


Nov 17 '05 #7

Ken Allen wrote:
wa********@yahoo.com wrote:
You can infact mark a section of your c# code unsafe and use pointers
just like c++.

How does one mark a section unsafe and have the code before and after
that section as safe (managed) code?

How does one use pointers at all in C#? Even in unsafe code? If I have a
buffer, which is probably defined as a byte array, how do I 'cast' a
subset of that array to be treated as a structure with data members? The
only way I have seen is to marshal a (cast as IntPtr) specific subset of
the array into a structure.

-ken


You can do anything in unsafe code, including writing C++ (more or
less) code:

unsafe
{
char s[200];
int x = 10;
memcpy(

Nov 17 '05 #8

"Matt" <ma********@sprynet.com> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com...

Ken Allen wrote:
wa********@yahoo.com wrote:
> You can infact mark a section of your c# code unsafe and use pointers
> just like c++.
>

How does one mark a section unsafe and have the code before and after
that section as safe (managed) code?

How does one use pointers at all in C#? Even in unsafe code? If I have a
buffer, which is probably defined as a byte array, how do I 'cast' a
subset of that array to be treated as a structure with data members? The
only way I have seen is to marshal a (cast as IntPtr) specific subset of
the array into a structure.

-ken


You can do anything in unsafe code, including writing C++ (more or
less) code:

unsafe
{
char s[200];
int x = 10;
memcpy(


No it's not, you can't call (not directly) unmanaged code like memcpy(...),
calling unmanaged code from C# is only possible through PInvoke and COM
interop.
unsafe doesn't mean "native" it's simply an indication that the block may
contains native C style pointers and can perform pointer arithmetics but
that's it, the code remains managed (compiled to IL) code and the data like
a char array is still GC heap allocated and JIT tracked data.
unsafe {
// allocates a managed array of type char
char[] s = new char[200];
// pin the array object and take the address of the first char in the array
fixed (char* ptr = &s[0])
{
// use ptr f.i as an argument in a call to unmanaged code using
PInvoke interop

}// un-pin the char array!!!
}

Willy.

Nov 17 '05 #9

Willy Denoyette [MVP] wrote:
"Matt" <ma********@sprynet.com> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com...

Ken Allen wrote:
wa********@yahoo.com wrote:
> You can infact mark a section of your c# code unsafe and use pointers
> just like c++.
>
How does one mark a section unsafe and have the code before and after
that section as safe (managed) code?

How does one use pointers at all in C#? Even in unsafe code? If I have a
buffer, which is probably defined as a byte array, how do I 'cast' a
subset of that array to be treated as a structure with data members? The
only way I have seen is to marshal a (cast as IntPtr) specific subset of
the array into a structure.

-ken
You can do anything in unsafe code, including writing C++ (more or
less) code:

unsafe
{
char s[200];
int x = 10;
memcpy(


No it's not, you can't call (not directly) unmanaged code like memcpy(...),
calling unmanaged code from C# is only possible through PInvoke and COM
interop.


Yes, I know. I was trying to delete that line and write my own copymem
when I hit "post" instead of return. Sorry about that. You are
absolutely right, of course.
unsafe doesn't mean "native" it's simply an indication that the block may
contains native C style pointers and can perform pointer arithmetics but
that's it, the code remains managed (compiled to IL) code and the data like
a char array is still GC heap allocated and JIT tracked data.
Yep. The point was that you *could* do what he wanted, using unsafe
code, if you really wanted to. I could think of a lot better ways to do
it, tho. Writing a single class to map each object to a block of
memory, and using the various conversion methods to extract the data
would be best.

Matt


unsafe {
// allocates a managed array of type char
char[] s = new char[200];
// pin the array object and take the address of the first char in the array
fixed (char* ptr = &s[0])
{
// use ptr f.i as an argument in a call to unmanaged code using
PInvoke interop

}// un-pin the char array!!!
}

Willy.


Nov 17 '05 #10
Hmm seems i'm qute late :)

Anyway , with unsafe code you can allocate things on stack
and do things faster ... pointer arrays are 2-3x faster on read/write
than normal managed arrays:)

unsafe void UnsafeTest()
{
//allocate on stack
byte* p= stackalloc byte[100];
uint* p2=(uint*)p;
uint v1=*p;
uint v2=p[12]+p2[11];

//allocate on unmanaged mem pool
uint
*unmanaged_mem=System.Runtime.InteropServices.Mars hal.AllocCoTaskMem(200
).ToPointer();

//free it too
System.Runtime.InteropServices.Marshal.FreeCoTaskM em(new
IntPtr(unmanaged_mem));
}

but indeed , c# is not the best language to use with that kind of code.
I prefer c# over c++ a lot (actualy i can't compile and/or read c++ code
; a mess of macro games and missing .h files..) so i use c# for (almost)
all my lowlevel code and i can tell teht it is as fast as c++ when you
use static functions , pointers and no .net clases.

If you like C# syntax but want it for something low level try the D
language.It is a litl bit faster that C++ , has C# style code , uses
modules/namespaces the same way c# does [almost] and has full
asm/pointer support (the GC can be turned off).

drkIIRaziel

*** Sent via Developersdex http://www.developersdex.com ***
Nov 17 '05 #11
Stef:

I'm not quite sure what the purpose of writing C# instead of C++, while
using only static functions, pointers (and thus unsafe blocks), and no
..NET framework classes. Isn't that effectively just writing C++, except
with the added overhead of the CLR? I'm not even sure why you would
prefer the syntax of C# over that of C++ in that situation.

At any rate, for what it's worth, I'd throw my weight onto the side
that says write the native code in C++ as a DLL and P/Invoke it from
managed code as necessary. C# is good for what it was designed for, and
C++ is good for what it was designed for. "When all you have is a
hammer, everything starts to look like a nail..."

Nate

Nov 17 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Sundeep Gawande | last post by:
I am facing a strange problem. I am trying to host a .NET(C#) control in a VC6 COM ocx. Now when I create the control using CreateControl(...) or CoCreateInstance(...) my call is failing with...
7
by: Kieran Simkin | last post by:
Hi all, I'm having some trouble with a linked list function and was wondering if anyone could shed any light on it. Basically I have a singly-linked list which stores pid numbers of a process's...
3
by: bob | last post by:
Hello, I've tried a few testing frameworks with C# but so far haven't found a way to debug into a failing test. I'm used to S Unit (Smalltalk) where when a test fails you just right click on it...
1
by: Frank Rizzo | last post by:
Hello, I have a bunch of thread in my app doing variuos things. One of them is failing at some point in the app and I can't (actually don't know how) figure out which one it is. Is there a way to...
3
by: Michael Tissington | last post by:
I'm using LoadLibrary to import a DLL in a asp.net application. The dll was written in c++ and is located in the bin folder I have been testing the website on my development machine and our...
18
by: Scott David Daniels | last post by:
There has been a bit of discussion about a way of providing test cases in a test suite that _should_ work but don't. One of the rules has been the test suite should be runnable and silent at every...
0
by: a_rajanikanth | last post by:
Hi, The following is the trigger which is failing when executing. Can you please tell me the reason why it is failing ? Trigger got created but throwing exception. CREATE TRIGGER TOBJ_U...
3
by: noon | last post by:
I'm runing an xmlHttpRequest to get the site's source code and then applying the regex xhr.responseText.split(/<body*>((?:.|\n)*)<\/body>/i) Works for google.com. Fails on yahoo.com and...
1
by: Kalyani Mallipe | last post by:
Hi All, My program is failing at MessageFormat::format call when libraries are built in release mode. Same is passing when libraries are built in debug (-g) mode. The format is calling is giving...
5
by: wzcxjiao | last post by:
'm currently fighting my way through an example of Single-Threaded Variable-Size Memory Manager in a chapter of the Efficient C++ book by Dov Bulka &David Mayhew. Unfortuantely, I'm starting to get...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
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,...
0
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...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
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...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.