奇数一:如果数组大小大于4136,@ myRecordArray [0]返回无效指针

tha*_*alm 1 c# arrays delphi com pointers

这真的很奇怪,我在delphi中有一个数组并用directX矩阵填充它.然后我得到指向第一个元素的指针,并通过com将其传递给c#托管代码:

function TMPlugTransformInPin.GetMatrixPointer(out SliceCount: Integer; out
    ValueP: Int64): HResult;
var
  matrices: array of TD3DMatrix;
  i: Integer;
begin
  SliceCount := UserSliceCount;

  //make a temp array of all matrices
  SetLength(matrices, SliceCount);
  for i := 0 to SliceCount - 1 do
    matrices[i] := FTransformManager.ModelMatrix[i];

  //return a pointer to the first matrices cell [0,0]
  if SliceCount = 0 then
    ValueP := 0
  else
    ValueP := Int64(@matrices[0]);

  Result := S_OK;
end;
Run Code Online (Sandbox Code Playgroud)

在托管方面,代码如下所示:

if (IsChanged)
            {
                int sliceCount;
                long source;

                FTransformIn.GetMatrixPointer(out sliceCount, out source);
                SliceCount = sliceCount;

                System.Diagnostics.Debug.WriteLine(source);

                if (FSliceCount > 0)
                    Marshal.Copy(new IntPtr(source), FData, 0, FData.Length);
            }
Run Code Online (Sandbox Code Playgroud)

这一切都适用于最大4136(66176浮点数)的数组大小,但是对于更高的计数,指向数组的指针无效.

有任何想法吗?

非常感谢!thalm

Rob*_*edy 6

您的matrices变量是本地动态数组.在函数结束时,数组的引用计数减少到零并且数组被销毁.ValueP无论数组有多大,您存储的指针都是无效的.事实上,它似乎适用于较小的价值只是意味着你不走运.(如果你很幸运,代码每次都会崩溃,这是一个更大的线索,你的代码错误,而不是有时崩溃.)

您需要找到一些其他方法来管理该数组的生命周期.它将需要属于比该函数更大的东西.也许你可以从该函数返回数组本身,或者你可以使matrices变量成为类的一个字段而不是局部变量.或者你可以回来@FTransformManager.ModelMatrix[0].