gpt4 book ai didi

C# 指针上的指针

转载 作者:行者123 更新时间:2023-11-30 22:02:30 25 4
gpt4 key购买 nike

我以前从未使用过指针,现在我需要使用,尽管我已经阅读了它们,但我仍然不知道如何使用它们!我使用的是第三方产品 (Mitov Signal Lab),我使用的控件具有允许我拦截数据的事件。当我进入事件时,我可以访问“args”并且其中一个语句将返回一个指针。现在这指向一个包含 4096 个 double 值的缓冲区(一个是实数,下一个是虚数等)。所以这是代码:

 private void genericComplex1_ProcessData(object Sender, Mitov.SignalLab.ProcessComplexNotifyArgs Args)
{
unsafe
{
IntPtr pointer = Args.InBuffer.Read();

// now what???? I want to get each double value, do some calculations on them
// and return them to the buffer.
}
args.sendOutPutData = true;
}

我假设我需要将指针分配给 Args.InBuffer.Read()但是我已经尝试了一些我见过的例子,但我只是遇到了错误。我正在使用 visual studio 2010 并且我正在使用/unsafe 进行编译。这是一个更新。还有其他方法,例如 Args.Inbuffer.Write() 和 Args.Inbuffer.Modify(),但我仍然无法弄清楚如何访问缓冲区的各个组件。

好的,这里有更多详细信息。我使用了 Marshall.copy。这是代码:

   private void genericComplex1_ProcessData(object Sender, Mitov.SignalLab.ProcessComplexNotifyArgs Args)
{
//used to generate a phase corrected Q signal
//equations:
// real = real
// imaginary = (1 + amplitudeimbalance)(real*cos(phaseImbalance) + imaginary*sin(phaseImbalance)
//but amplitude imbalance is already corrected therefore

//imaginary = real * cos(phaseCorrection) + imaginary*sin(phaseCorrection)

double real;
double imaginary;
double newImaginary;

var bufferSize = Convert.ToInt32(Args.InBuffer.GetSize());

Mitov.SignalLab.ComplexBuffer ComplexDataBuffer = new Mitov.SignalLab.ComplexBuffer(bufferSize);
ComplexDataBuffer.Zero();

IntPtr pointer = Args.InBuffer.Read();
IntPtr pointer2 = ComplexDataBuffer.Write();

var data = new double[8192];

Marshal.Copy(pointer, data, 0, 8192);

for (int i = 0; i < 8192; i+=2)
{
data[i] = data[i];
data[i + 1] = data[i] * Math.Cos(phaseCorrection) + data[i+1] * Math.Sin(phaseCorrection);
}

Marshal.Copy(data, 0, pointer2, 8192);

Args.SendOutputData = false;
genericComplex1.SendData(ComplexDataBuffer);

}

现在,这行不通了。原因是时间太长了。我正在以每秒 192,000 个样本的速度从声卡中采样音频。每次有可用的 4096 缓冲区时,都会触发上述事件。因此,每 20 毫秒就会有一个新缓冲区到达。然后将该缓冲区发送到快速傅立叶变换例程,生成信号强度与频率的关系图。虚部数据实际上与实部数据相同,但相移了 90 度。这就是它在完美世界中的样子。然而,由于信号的不平衡、不同的电子路径、不同的代码等,相位永远不会是 90 度。因此需要一个校正因子,这就是方程式所做的。现在,如果我更换

data[i] = data[i];
data[i + 1] = data[i] * Math.Cos(phaseCorrection) + data[i+1] * Math.Sin(phaseCorrection);

data[i] = data[i];
data[i+1] = data[i+1];

它工作正常。
所以我需要指点。但这会快得多还是正弦和余弦函数会花费太长时间? Cn 我将数据直接发送到处理器(现在这真的很不安全!)。

最佳答案

您无法在安全上下文中直接访问非托管数据,因此您需要将数据复制到托管容器:

using System.Runtime.InteropServices;
// ...

var data = new double[4096];
Marshal.Copy(pointer, data, 0, 4096);
// process data here

据我所知,这部分代码不需要 unsafe 上下文。

至于回写数据,其实大同小异,但注意参数顺序:

// finished processing, copying data back
Marshal.Copy(data, 0, pointer, 4096);

至于你最后关于表现的笔记。正如我已经提到的,将 var data = new double[8192]; 移动到 data 类成员并在类构造函数中对其进行初始化,因此它不会每次都分配(和分配很慢)。您可以在循环之外执行 Math.Cos(phaseCorrection),因为 phaseCorrection 未更改,Math.Sin(phaseCorrection) 当然也是如此。像这样:

Marshal.Copy(pointer, this.data, 0, 8192);

var cosCache = Math.Cos(phaseCorrection);
var sinCache = Math.Sin(phaseCorrection);
for (int i = 0; i < 8192; i+=2)
{
data[i] = data[i];
data[i + 1] = data[i] * cosCache + data[i+1] * sinCache;
}

Marshal.Copy(this.data, 0, pointer2, 8192);

所有这些都会极大地加快速度。

关于C# 指针上的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26857060/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com