D在Windows/Linux上打开本机设备 我对D非常陌生,我有C++背景。

D在Windows/Linux上打开本机设备 我对D非常陌生,我有C++背景。,d,D,我想尝试使用D lang发送SCSI CDB。D中是否有一个类允许我在Windows中打开与此函数类似的本机设备?我正在寻找类似的D的东西 有什么想法可以让我玩吗?如果D不能这样做,我知道我可以编写C++代码并从D.< /P> < p>链接到它。你可以直接调用Windows CealFeFiels/Cuff>函数(尽管你可能需要使用 CuraFiele< /Cube >或 CreateFileW < /Cord>,因为D不总是定义像C++那样的便利名称。有三种方法: 1) 一些操作系统标题包含

我想尝试使用D lang发送SCSI CDB。D中是否有一个类允许我在Windows中打开与此函数类似的本机设备?我正在寻找类似的D的东西


有什么想法可以让我玩吗?如果D不能这样做,我知道我可以编写C++代码并从D.< /P> < p>链接到它。你可以直接调用Windows <代码> CealFeFiels/Cuff>函数(尽管你可能需要使用<代码> CuraFiele< /Cube >或<代码> CreateFileW < /Cord>,因为D不总是定义像C++那样的便利名称。有三种方法:

1) 一些操作系统标题包含在D下载中<代码>导入core.sys.windows.windows将适用于
CreateFileA
(或W,它是宽字符(unicode)版本)<代码>写文件与许多其他基本功能一起也在其中

对于Unix头文件,
import core.sys.posix.unistd和朋友可以帮助。如果要在C中使用
#include
,请尝试
import core.sys.posix.foo在D中

2) D附带的Windows标题实际上是最小的。你可以从这里下载更多完整的

对于其他库,请尝试在此处进行快速搜索,也许您也会找到绑定

3) 如果失败,您可以将函数和结构定义从C复制/粘贴到D。例如,如果需要
ReadFileEx
,您会发现它不在
core.sys.windows.windows
中。只需将其添加到文件中即可调用:

    extern(Windows)
            BOOL ReadFileEx(HANDLE, LPVOID, DWORD, OVERLAPPED*, void*);
您可以从MSDN获得的定义,其中删除了一些额外的宏等。您编写的不是
WINAPI
,而是
extern(Windows)
,那么函数的大部分其余部分都是相同的。(尽管如此,请确保仍然导入core.sys.windows.windows,这样您就有了DWORD之类的定义。)

然后您可以正常调用该函数。您还可以对其他库中的Unix函数执行
extern(C)
。但是,当您在c中看到
long
unsigned long
时,一定要使用
c\u long
,因为它们不一定与D中的
long
相同。这些类型可以在
import core.stdc.config中找到


类似地,可以根据需要将结构复制/粘贴到D中并使其可用,同样,只需将成员类型转换为等效的D,确保它们保持相同的顺序。提示:如果结构总是由指针使用,那么只需传递
void*
而不是实际的定义就可以了。你会失去一点类型安全性,但它通常是有效的。

要补充亚当的答案:


从DMD 2.066开始,您可以使用该功能将任何窗口
句柄
(通过
CreateFile
)与
std.stdio.File
关联。这应该允许您将D的
std.stdio
用于任意Windows句柄对象(设备、管道等)。

在Adam的帮助下,我想出了以下代码():

import core.sys.posix.sys.ioctl:ioctl;
导入core.stdc.errno:errno;
导入std.stdio:write,writef,writeln,writefln,File;
导入std.xml:isChar;
常量int SG_IO=0x2285;
const int SG_DXFER_FROM_DEV=-3;
consuint SG\u INFO\u OK\u MASK=1;
consuint SG_INFO_OK=0;
consuint INQ_LEN=6;
结构(sg)io(hdr)
{
SCSI通用接口的int接口_id;/*[i]'S(必需)*/
int dxfer_方向;/*[i]数据传输方向*/
ubyte cmd_len;/*[i]SCSI命令长度(无超时(单位:毫秒)*/
uint标志;/*[i]0->默认值,请参阅SG_标志*/
int pack_id;/*[i->o]内部未使用(正常)*/
void*usr\u ptr;/*[i->o]内部未使用*/
ubyte状态;/*[o]scsi状态*/
ubyte屏蔽_状态;/*[o]移位,屏蔽scsi状态*/
ubyte msg_状态;/*[o]消息级别数据(可选)*/
实际写入sbp的ubyte sb_len_wr;/*[o]字节计数*/
USHOST_status;/*[o]主机适配器错误*/
ushort driver_status;/*[o]来自软件驱动程序的错误*/
整数剩余;/*[o]dxfer\u len-实际转移*/
uint持续时间;/*[o]cmd所用的时间(单位:毫秒)*/
uint信息;/*[o]辅助信息*/
}/*64字节长(在i386上)*/
void writeBuffer(字符[]buff,整数长度)
{
对于(int k=0;k0)&(0==(k%8)))
{
writeln();
}
//在字符范围内中断非字符的输出,但在这段代码中谁在乎呢
if(isChar(buff[k]))
{
写(“,cast(char)(buff[k]),”);
}
其他的
{
writef(“%02x”,buff[k]);
}
}
}
int main()
{
_sg_io_hdr io_hdr;
char[INQ_LEN]cdb=0;
char[32]senseBuffer=0;
字符[96]inqBuffer=0;
cdb[0]=0x12;
cdb[4]=cdb.长度;
io_hdr.interface_id='S';
io_hdr.cmd_len=cdb.length;
io_hdr.cmdp=cast(ubyte*)(cdb);
io_hdr.mx_sb_len=senseBuffer.length;
io_hdr.sbp=铸件(ubyte*)(senseBuffer);
io_hdr.dxfer_len=inqBuffer.length;
io_hdr.dxferp=cast(ubyte*)(inqBuffer);
io_hdr.dxfer_direction=SG_dxfer_FROM_DEV;
io_hdr.timeout=5000;
自动文件=文件(“/dev/sdb”,“rb”);
int res=ioctl(file.fileno()、SG_IO和IO_hdr);
file.close();
如果(res<0)
{
写入(“错误:查询SG_IO ioctl错误”,错误号);
}
如果((io_hdr.info和SG_info_OK_MASK)!=SG_info_OK)
{
写入(“错误:io_hdr.info不正常”);
}
writefln(“查询持续时间=%u毫秒,剩余=%d\n”,
io_hdr.持续时间,io_hdr.剩余时间);
writeln(“查询缓冲区:”);
writeBuffer(inqBuffer,inqBuffer.length);
writeln(“\n”);
返回0;
}

很酷,这很有帮助!
import core.sys.posix.sys.ioctl  : ioctl;
import core.stdc.errno           : errno;
import std.stdio                 : write, writef, writeln, writefln, File;
import std.xml                   : isChar;

const int SG_IO = 0x2285;
const int SG_DXFER_FROM_DEV = -3;
const uint SG_INFO_OK_MASK = 1;
const uint SG_INFO_OK = 0;
const uint INQ_LEN = 6;

struct _sg_io_hdr
{
   int interface_id; /* [i] 'S' for SCSI generic (required) */
   int dxfer_direction; /* [i] data transfer direction  */
   ubyte cmd_len; /* [i] SCSI command length ( <= 16 bytes) */
   ubyte mx_sb_len; /* [i] max length to write to sbp */
   ushort iovec_count; /* [i] 0 implies no scatter gather */
   uint dxfer_len; /* [i] byte count of data transfer */
   void * dxferp; /* [i], [*io] points to data transfer memory
                  or scatter gather list */
   ubyte * cmdp; /* [i], [*i] points to command to perform */
   ubyte * sbp; /* [i], [*o] points to sense_buffer memory */
   uint timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */
   uint flags; /* [i] 0 -> default, see SG_FLAG... */
   int pack_id; /* [i->o] unused internally (normally) */
   void * usr_ptr; /* [i->o] unused internally */
   ubyte status; /* [o] scsi status */
   ubyte masked_status;/* [o] shifted, masked scsi status */
   ubyte msg_status; /* [o] messaging level data (optional) */
   ubyte sb_len_wr; /* [o] byte count actually written to sbp */
   ushort host_status; /* [o] errors from host adapter */
   ushort driver_status;/* [o] errors from software driver */
   int resid; /* [o] dxfer_len - actual_transferred */
   uint duration; /* [o] time taken by cmd (unit: millisec) */
   uint info; /* [o] auxiliary information */
} /* 64 bytes long (on i386) */

void writeBuffer(char[] buff, int length)
{
   for (int k = 0; k < buff.length; ++k)
   {
      if ((k > 0) && (0 == (k % 8)))
      {
         writeln();
      }
      // breaks output of non-chars in char range, but who cares in this code
      if (isChar(buff[k]))
      {
         write(" ", cast(char)(buff[k]), " ");
      }
      else
      {
         writef("%02x ", buff[k]);
      }
   }
}


int main()
{
   _sg_io_hdr io_hdr;

   char[INQ_LEN] cdb = 0;
   char[32] senseBuffer = 0;
   char[96] inqBuffer = 0;

   cdb[0] = 0x12;
   cdb[4] = cdb.length;

   io_hdr.interface_id      = 'S';
   io_hdr.cmd_len           = cdb.length;
   io_hdr.cmdp              = cast(ubyte*)(cdb);
   io_hdr.mx_sb_len         = senseBuffer.length;
   io_hdr.sbp               = cast(ubyte*)(senseBuffer);
   io_hdr.dxfer_len         = inqBuffer.length;
   io_hdr.dxferp            = cast(ubyte*)(inqBuffer);
   io_hdr.dxfer_direction   = SG_DXFER_FROM_DEV;
   io_hdr.timeout           = 5000;

   auto file = File("/dev/sdb", "rb");
   int res = ioctl(file.fileno(), SG_IO, &io_hdr);
   file.close();

   if (res < 0)
   {
      writeln("ERROR: inquiry SG_IO ioctl error ", errno);
   }
   if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK)
   {
      writeln("ERROR: io_hdr.info is not OK");
   }

   writefln("INQUIRY duration=%u millisecs, resid=%d\n",
      io_hdr.duration, io_hdr.resid);

   writeln("INQUIRY inquiry buffer: ");
   writeBuffer(inqBuffer, inqBuffer.length);
   writeln("\n");
   return 0;
}