如何在Delphi中将数组转换为指针并返回?

Lar*_*gen 10 arrays delphi combobox casting

我有一个所有者绘制的组合框,在列中显示字符串.如果我可以以某种方式将列规范传递给OnDrawItem事件,则可以跨组合共享绘图例程.这样做的一种自然方法是传递ComboBox.Tag属性中的列宽数组,然后将其强制转换回数组.

当我将列数组定义为:

const arrWidth :array[1..4] of integer = (100,100,100,70);
Run Code Online (Sandbox Code Playgroud)

并将Tag属性设置为:

ComboBox.Tag := integer(@arrWidth);
Run Code Online (Sandbox Code Playgroud)

然后在OnDrawItem事件中,将其强制转换为数组:

Widths :array of integer;
Widths := pointer(ComboBox.Tag);
Run Code Online (Sandbox Code Playgroud)

我可以看到数组元素很好,但数组不知道它的长度.各种随机值似乎要长得多.

我尝试过使用动态数组,但后来我甚至没有得到正确的列值.

Dav*_*nan 20

演员是危险的,因为你走出类型检查系统.那抓住了你.问题是,array[1..4] of integer并且array of integer不是同一类型.

您需要将数组声明为这样的不同类型

TWidthArray = array [1..4] of Integer;
PWidthArray = ^TWidthArray;
Run Code Online (Sandbox Code Playgroud)

然后像这样做你的常数:

const 
  arrWidth: TWidthArray = (100,100,100,70);
Run Code Online (Sandbox Code Playgroud)

当您需要从组合框中提取数组时,请执行以下操作:

Widths: TWidthArray;
...
Widths := PWidthArray(ComboBox.Tag)^;
Run Code Online (Sandbox Code Playgroud)

如果需要支持使用动态数组长度,则需要更改常用类型以反映这一点.但是,要注意转换为Integer放入Tag将绕过动态数组的引用计数.因此,如果沿着这条路走下去,你需要真正了解自己在做什么.

最后一点.如果您希望将此代码编译为64位,则会因此行而失败:

ComboBox.Tag := integer(@arrWidth);
Run Code Online (Sandbox Code Playgroud)

因为integer是32位数据类型.相反,您应该使用NativeInt哪个是与指针相同宽度的整数.

ComboBox.Tag := NativeInt(@arrWidth);
Run Code Online (Sandbox Code Playgroud)