一个失败的oif C#? [英] A failing oif C#?

查看:47
本文介绍了一个失败的oif C#?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用C#已经有一段时间了,而且大部分时间我都非常感激,并且更喜欢在C ++上使用它。有一个区域,C#/。Net

似乎,至少在我看来,与C / C ++相比,不太理想,而且

属于C / C ++区域。与缓冲区映射通信。我知道

interop,并且用这种方式编写了大量的代码,但是与使用C ++相比,这是一个真正的痛苦,除非我遗漏了什么,<很可能。
很可能。


我当前的问题域是使用传递命令来控制

SCSI设备。设备是什么并不重要,因为我试图处理的问题本质上是通用的。


SCSI命令协议支持命令各种固定长度,从6到12个字节的
。许多字节具有单独的含义,有些具有每位含义的
,而在其他情况下,多个字节被组合成

有意义。例如,考虑10字节READ命令,其定义如下:


28 XX LL LL LL LL 00 TL TL 00

其中:

28 - 是十六进制的10字节读取命令

XX - 是一个字节,其中

位0:2保留

位3是FUA位

位4是DPO位

位5-7是LUN(通常为零)

LL - 这四个字节代表逻辑块地址

TL - 这两个字节表示要读取的扇区数


在C ++中,为每个不同的命令结构定义

的结构是相当简单的,尽管很乏味,强制转换实际命令缓冲区

地址到适当的结构指针,然后用一些信息性代码填写

命令缓冲区。在C#中,每个结构都可以定义,但是必须将数据编组到缓冲区中;那里

似乎不是任何有效的方法,代码可以将结构转换成字节数组,反之亦然。反之亦然。


虽然可以使用带有

参数的成员函数来处理命令,并将信息直接转换为字节数组,但是对于
方法来说并不是那么干净SCSI命令的结果。


考虑MODE SENSE命令,它可以返回一页或多页

信息。返回缓冲区是一个字节流,包含特殊的

结构,这些结构可选地存在。例如,有一个缓冲区

标头结构描述了缓冲区的整体内容,

后跟指定数量的数据页面,每个页面都有一个

标识实际页面内容的特殊标题,后跟

页面本身。同样,在C ++中,我们可以读取定义

特定页面的字节,然后构建一个结构指针,允许我们访问页面中的内容

有意义的方式在C#中,我们可以读取

单个字节以确定页面类型,但必须使用interop

将信息从缓冲区复制到一个结构中参考。


更糟糕的是当我想使用MODE SELECT命令并传递两个或多个
更多信息页面时。在结构中创建信息

对象(或类)然后将其序列化到缓冲区是一个痛苦的问题,与我在C ++中可以使用的方法相比,
。 br />

有没有办法避免所有这些使用编组代码来实现对数据缓冲区内容的结构化访问?在我看来,为了在C#中实现这一点,我必须编写的代码数量几乎是我在C ++中可以实现的两倍,这看起来似乎只是错了,
以某种方式
。我知道指针不是C#格局的一部分,但是这需要在结构/类和字节流或数组之间进行转换

似乎应该是应该的比它更容易。

特别是因为这是''不安全''代码,并且必须存在于我的主代码中的单独的

程序集中(或者至少是编译器错误告诉我如此)。


-ken

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

推荐答案

你可以事实上标记你的一部分c#代码不安全并使用指针

就像c ++一样。

You can infact mark a section of your c# code unsafe and use pointers
just like c++.




" Ken Allen" <柯****** @ sympatico.ca>在消息中写道

新闻:eP ************** @ TK2MSFTNGP09.phx.gbl ...

"Ken Allen" <ke******@sympatico.ca> wrote in message
news:eP**************@TK2MSFTNGP09.phx.gbl...
我一直在使用C#一段时间以来,在很大程度上,我印象非常深刻,并且更喜欢在C ++上使用它。至少对我而言,C#/ .Net似乎有一个区域比C / C ++更不可取,并且
与缓冲区映射的通信领域相比。我知道interop,
并且用这种方式编写了大量的代码,但与使用C ++相比,这是一个真正的痛苦,除非我遗漏了一些东西,这很可能。

我当前的问题域是使用传递命令来控制SCSI
设备。设备是什么并不重要,因为我试图处理的问题本质上是通用的。

SCSI命令协议支持各种固定长度的命令,来自
6到12个字节。许多字节具有单独的含义,有些具有每位含义,而在其他情况下,多个字节组合起来具有含义。例如,考虑10字节的READ命令,其定义如下:

28 XX LL LL LL LL 00 TL TL 00

其中:< 28 - 是十六进制的10字节读取命令
XX - 是一个保留位0:2的字节
位3是FUA位
bit 4是DPO位
位5-7是LUN(通常为零)
LL - 这四个字节代表逻辑块地址TL - 这两个字节表示要读取的扇区数

在C ++中,为每个不同的命令结构定义一个结构是相当简单的,虽然很乏味,将实际的命令缓冲区
地址转换为适当的结构指针,然后使用一些信息性代码填写命令
缓冲区。在C#中,每个结构都可以定义,但是必须将数据编组到缓冲区中;似乎没有任何有效的方法可以将代码转换为字节数组,反之亦然。

虽然命令可以使用成员处理采用
参数并将信息直接转换为字节数组的函数,对于SCSI命令的结果来说,这种方法并不是那么干净。

考虑MODE SENSE命令,它可以返回一页或多页
信息。返回缓冲区是一个字节流,包含可选的特殊结构。例如,有一个缓冲区
标头结构,描述缓冲区的整体内容,按照指定数量的数据页面,每个数据页面都有一个标识实际页面的特殊标题
内容,然后是页面本身。
同样,在C ++中我们可以读取定义特定页面的字节,然后构建一个允许我们访问
页面以有意义的方式。在C#中,我们可以读取单个字节来确定页面类型,但必须使用interop将信息从缓冲区复制到一个结构中供参考。

是有没有办法避免所有这些使用编组代码来实现对数据缓冲区内容的结构化访问?在我看来,为了在C#中实现这一点,我必须编写的代码量几乎是我在C ++中可以使用的两倍,这似乎是错误的,不知怎的。我知道指针不是C#格局的一部分,但是这需要在结构/类和字节流或数组之间进行转换似乎应该让事情变得更容易比它。特别是因为这是''不安全''代码,并且必须存在于我的主要代码的单独程序集中(或者至少编译器错误告诉我)。

- ken
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




您使用错误的语言/框架作为工作,为什么不坚持使用C ++ for

这个?


Willy。




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

Willy.



wa ******** @ yahoo.com 写道:
你可以将你的c#代码的一部分标记为不安全并使用指针
就像c ++。
You can infact mark a section of your c# code unsafe and use pointers
just like c++.



如何将一个部分标记为不安全并且在

之前和之后将该部分作为安全(托管)代码?


如何在C#中使用指针?即使在不安全的代码?如果我有一个

缓冲区,它可能被定义为一个字节数组,我如何转换该数组的一个

子集被视为一个结构与数据成员?我所看到的唯一方法就是将一个(演员为IntPtr)特定子集的数组编组成一个结构。


-ken


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


这篇关于一个失败的oif C#?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆