我正在使用Delphi 2009而不是它对我正在做的事情有很大的影响.如果我还在2007年,我想我会遇到同样的情况.

我有一个scsi调用,它将数据输出到一个指针(错误的方式查看它,但我很难解释).

最初我使用Move来填充返回的数据的Byte静态数组,但是我想切换到一个动态数组,在调用时已经知道了它的长度.我尝试了几个不同结果的东西,有些得到了数据,但有疯狂的访问权限,其他人没有错误但得到无效的数据.

将setlength添加到数组然后使用move会导致第一个设置长度为空数组,然后第二个不能像OutputData [0]一样访问数据,就像我在静态时一样,在移动后的调试器中一切都表现为无可比拟的价值或其他.

下面是我在阅读了一篇文章之后尝试过的,该文章使得oposit采用动态数组并给出了一个指针.它提到了像孤儿数据这样的错误.

var
  Output: Pointer;
  OutputData: Array of byte;
  I: Integer;
begin
GetMem(Output,OutputLength.Value);
if SendPSPQuery(Char(DriveLetter[1]),cbxQuery.Items.IndexOf(cbxQuery.Text),Output,OutputLength.Value) = 0 then
  begin
    OutputData := @Output;
    for I := 0 to OutputLength.Value - 1 do
    begin
      edtString.Text := edtString.Text + Char(OutputData[I]);
    end;

使用输出数据还有其他各种因素,它会以字符串和十六进制和事物的形式输出.

无论如何,我如何使用指针将数据放入动态数组中,然后像处理数组一样获取数据.

谢谢.

解决方法

要使用带有 the Move procedure的动态数组,需要传递数组的第一个元素.例如:
var
  Source: Pointer;
  SourceSize: Integer;
  Destination: array of Byte;

SetLength(Destination,SourceSize);
Move(Source^,Destination[0],SourceSize);

另请注意,第二个参数取消引用指针.这是因为Move会获取您正在复制的值,而不是指向该值的指针.你正在复制指针指向的东西,这就是你需要传递给Move的东西.

顺便说一句,如果Destination也是静态数组,那么相同的语法也可以.你是对的,这不是特定于Delphi 2009的.它一直回到Delphi 4,这是在引入动态数组的时候.和Move永远有着同样奇怪的untyped parameter语法.

不要使用GetMem分配自己的内存,然后使用type-cast使编译器认为你拥有的是动态数组.不是.动态数组具有普通字节缓冲区不具有的引用计数和长度字段,并且由于您无法控制编译器为访问假定的动态数组而生成的所有代码,因此您的程序可能会尝试访问数据结构的不存在的数据.

您可以使PSP函数将其数据直接存储到动态数组中.这是一些代码:

var
  Output: array of Byte;

SetLength(Output,@Output[0],OutputLength.Value) = 0
then

之后无需释放记忆;当输出超出范围并且没有其他对数组的引用时,编译器会插入代码以释放动态数组.此代码采用动态数组并将其传递为普通缓冲区.这是有效的,因为动态数组实际上是普通旧缓冲区的子类型.该函数将接受指向数组第一个元素的指针,并将指针视为指向一堆字节的指针,因为它正是它的本质.该函数不需要知道在程序用于动态数组簿记的那些字节旁边发生了附加的东西.

如果您将数据放在缓冲区中并且希望将该缓冲区视为数组,而不是将数据复制到单独的数据结构中,那么您有两个选项.

>声明一个静态数组指针,然后将缓冲区指针类型转换为该类型.这是经典的技术,你可以看到它在代码中使用,特别是在Delphi 4之前的代码.例如:

type
  PByteArray = ^TByteArray;
  TByteArray = array[0..0] of Byte;
var
  ByteArray: PByteArray;

ByteArray := PByteArray(Output);
for i := 0 to Pred(OutputLength.Value) do begin
  {$R-}
  edtString.Text := edtString.Text + Chr(ByteArray[i]);
  {$R+}
end;

$R指令是为了确保该代码的范围检查被关闭,因为数组类型被声明为长度为1.数组声明的大小部分是为了作为你不是真的应该的线索声明该类型的变量.只能通过指针使用它.另一方面,如果您知道数据的最大大小是多少,则可以使用该大小来声明数组类型,然后可以打开范围检查. (如果您通常禁用范围检查,那么您只是在寻找麻烦.)
>将您的缓冲区声明为PByte而不是Pointer,然后使用Delphi的新版本(截至Delphi 2009)support for treating arbitrary pointer types as array pointers.在以前的版本中,只有PChar,PAnsiChar和PWideChar支持此语法.例如:

var
  Output: PByte;

for i := 0 to Pred(OutputLength.Value) do begin
  edtString.Text := edtString.Text + Chr(Output[i]);
end;

不需要$POINTERMATH编译器指令来为PByte启用此功能,因为在该指令生效时声明了该类型.如果要对其他指针类型执行类似C的指针操作,请在使用新扩展语法的代码之前放置{$POINTERMATH ON}.

最后要注意的是,您不需要一次为一个字符构建字符串.这在两个方面是浪费的.首先,您构建了许多字符串,每个字符串比前一个字符串大两个字节.第二,因为你将字符串结果存储在编辑控件中,所以你也强迫该控件的操作系统实现分配一堆新字符串.将您的数据放入一个字符串,然后将其全部追加到您的编辑控件:

var
  OutputString: AnsiString;

SetString(OutputString,PAnsiChar(Buffer),OutputLength.Value);
edtString.Text := edtString.Text + OutputString;

Delphi – 从无类型指针填充的动态数组中访问数据的更多相关文章

  1. html5利用canvas实现颜色容差抠图功能

    这篇文章主要介绍了html5利用canvas实现颜色容差抠图功能,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下

  2. html5使用canvas实现弹幕功能示例

    这篇文章主要介绍了html5使用canvas实现弹幕功能示例的相关资料,需要的朋友可以参考下

  3. 前端实现弹幕效果的方法总结(包含css3和canvas的实现方式)

    这篇文章主要介绍了前端实现弹幕效果的方法总结(包含css3和canvas的实现方式)的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. H5 canvas实现贪吃蛇小游戏

    本篇文章主要介绍了H5 canvas实现贪吃蛇小游戏,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. Html5实现首页动态视频背景的示例代码

    这篇文章主要介绍了Html5实现首页动态视频背景的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  6. ios – parse.com用于键,预期字符串的无效类型,但是得到了数组

    我尝试将我的数据保存到parse.com.我已经预先在parse.com上创建了一个名为’SomeClass’的类.它有一个名为’mySpecialColumn’的列,其数据类型为String.这是我尝试使用以下代码保存数据的代码:如果我运行这个我得到:错误:密钥mySpecialColumn的无效类型,预期字符串,但得到数组这就是我在parse.com上的核心外观:有谁知道我为什么会收到这个错误?

  7. ios – 上下文类型’NSFastEnumeration’不能与数组文字一起使用

    斯威夫特3,你会这样做吗?解决方法正如您所发现的,您不能使用as-casting将数组文字的类型指定为NSFastEnumeration.您需要找到一个符合NSFastEnumeration的正确类,在您的情况下它是NSArray.通常写这样的东西:

  8. ios – 在Swift中动态创建uiviewcontroller

    我想动态创建UIViewController而不创建类或使用Mainstoryboard.我希望它以编程方式发生.这可能吗?

  9. ios – Swift指针算术和解除引用;将一些类似C的地图代码转换为Swift

    我有一点似乎没有工作的Swift代码……解决方法您正在指定locationPointer指向新位置,但仍在下一行中使用ptr,并且ptr的值尚未更改.将您的最后一行更改为:或者你可以改变指向var的指针并推进它:

  10. ios – 获取资产目录文件夹中所有图像的数组

    在iOS中,是否可以获取资产目录文件夹中的图像数组?我不确定为什么会对此进行投票.我真的不知道从哪里开始.我的另一种方法是创建文件夹中所有文件的plist,但它似乎是多余的.我无法添加任何代码,因为我会添加什么?

随机推荐

  1. delphi – 主窗口按进程名称处理

    DelphiXe,Win7x64如何从进程名称(exe文件的完整路径)获取主窗口句柄,或至少一个类或窗口名称(如果该进程只有一个窗口).例:解决方法我同意Petesh的说法,你需要枚举顶级窗口并检查创建它的进程的模块文件名.为了帮助您开始枚举顶级窗口,这是一个delphi实现.首先,当你回调给你时,你需要一些与EnumWindows方法通信的方式.为此声明一条记录,该记录将保存您要查找的模块的文件

  2. 如何在Delphi中纯粹通过RTTI信息(即不使用任何实际对象实例)获取TObjectList的子项类型?

    我正在使用RTTI实现用于流式传输任意Delphi对象的通用代码,并且为了使其工作(更具体地说,为了使加载部分工作),我需要以某种方式获得TObjectList的子项类型<T>不使用任何实际对象实例的字段.要求不使用任何实际对象实例的明显原因是,在从流加载对象的情况下(仅基于要加载的对象的类类型的知识),我将不会有任何实例在加载完成之前完全可用–我宁愿只能访问相关类的纯RTTI数据.我希望能

  3. inno-setup – Inno Setup – 安装程序背景图片

    图像作为安装程序背景如何用inno5.5.9做到这一点?

  4. inno-setup – Inno Setup – 如何添加多个arc文件进行解压缩?

    使用InnoSetup解压缩弧文件.我希望有可能解压缩多个arc文件以从组件选择中安装文件(例如).但仍然显示所有提取的整体进度条.这可能吗?的回答的修改预备是相同的,参考其他答案.在ExtractArc中,为要提取的每个存档调用AddArchive.

  5. delphi – 如何在DataSet的帮助下在TAdvStringGrid中显示数据库中的BLOB图像

    解决方法CreateBlobStream正在创建一个TStream对象,而不是TMemoryStream.由于您不想将JPG写入数据库,因此应使用bmRead而不是bmReadWrite.我不习惯sqlite,但你必须确保使用合适的二进制日期类型.为了确保存储的图像真的是JPG,您应该编写JPG以进行测试,例如:

  6. inno-setup – 在Inno Setup的Code部分下载程序后运行程序

    如何运行我通过Internet下载的应用程序,在代码部分中使用,并等待该应用程序完成运行.我有,使用InnoTools下载程序,下载这两个文件,我想,在第二个完成下载后运行该下载,或jdk-8u111-windows-x64.exe,然后继续安装.解决方法使用其他下载插件,而不是ITD(请参阅下面的原因).例如,InnoDownloadPlugin.当您包含idp.iss时,它定义了一个全局IDP

  7. progress-bar – Inno Setup Run部分的简单进度页面

    我的安装程序非常简单,它基本上是:>欢迎页面>进展页面>最终页面欢迎页面和最终页面是标准页面.在Progress页面,我正在静默安装一堆其他程序.实际的脚本是在[Run]部分中安装每个程序.问题是酒吧达到100%然后停留在那里.我只能更改消息文本.我想要实现的是使用Pascal脚本显示进度,例如:这样我就可以显示更准确的进度条.这就是我所拥有的:问题是,当我构建安装程序时,它不显示欢迎页面.我做错了什么?

  8. delphi – 如何使“显示/隐藏桌面图标”设置生效?

    下面的代码调用SHGetSetSettings函数来隐藏桌面图标但它只是从视图菜单中取消选中“显示桌面图标”.我打电话给SHChangeNotify;更新桌面,但这不起作用?解决方法isa,要刷新桌面,您可以将F5键发送到progman窗口隐藏桌面图标的另一种方法是再次显示

  9. inno-setup – Inno Setup – 避免显示子安装程序的文件名

    我试图使用InnoSetup–Howtohidecertainfilenameswhileinstalling?(FilenameLabel)的想法Theonlysuresolutionistoavoidinstallingthefiles,youdonotwanttoshow,usingthe[Files]section.Installthemusingacodeinstead.UsetheEx

  10. inno-setup – Inno Setup磁力链接下载实施

    我目前正在使用InnoDownloadPlugin为我的安装程序下载文件,这个问题最大的问题是faila正确下载文件.因为连接不良等诸多原因.我想添加一种替代方法来下载文件,因此用户可以选择是否需要常规方式或torrent方式.我知道我可以使用aria2c.exe应用程序(https://aria2.github.io/),有人可以帮我实现它的inno设置代码吗?我需要的是使用torrent(ar

返回
顶部