无法将 ref double[] 转换为 ref 对象

发布于 2024-09-08 09:04:55 字数 1749 浏览 6 评论 0原文

看来我现在每天都在这里问一个问题。我不确定这是好事还是坏事……

今天的“WTF 风格”涉及我在使用 NIMeasurement Studio 对象中的函数时完全无知的情况。与我之前的大多数问题一样,这是一个实习项目,我的任务是将 VB6 项目翻译成 .Net Framework 2.0 中的 C#。

原始的 VB 代码看起来像这样:

Public Sub FFT(ZData() As Single, FFTData() As Single)
    Dim realdata As Variant
    Dim imgdata As Variant

    // (... Some unrelated other code in here ...)

    // Here we pass three variables to a NI CWDSP object's ReFFT function
    CWDSP1.ReFFT ZData, realdata, imgdata

    // (... More unrelated code ...)
End Sub

我一度陷入 MsgBox 中,看看 realdata 和 imgdata 是如何被解释的。它们都是Double()。它在原始程序中的作用很好。诚然,我对原始程序的了解只是平庸,因为我最近接手了这个项目,并且只进行了几年的编程(并且没有多年的机械工程经验。程序员是一名机械工程师,应用程序本身机器输出的测量工具)。

将代码转移到 C# 中,我尝试将其重写如下:

private void FFT(float[] ZData, float[] FFTData){
    double[] realData = new double[1000];
    double[] imgData = new double[1000];

    // (... Unrelated intermediate code ...)

    DSP.ReFFT(ZData, realData, imgData);

    // (... Unrelated intermediate code ...)
}

正如您所看到的,我首先以与原始 VB 基本相同的方式进行编写。出现以下错误:无法将 double[] 转换为 ref 对象

嗯,这不好。所以我尝试了: DSP.ReFFT(ZData, ref realData, ref imgData);

只是为了返回: Cannot Convert ref double[] to ref object

所以我做了我想做的想法是显而易见的。我将 realData 和 imgData 装箱到 object 中,并将它们传递给函数。然而,它不太喜欢这样。如果我在没有 ref 的情况下传递新对象,它会坚持认为我需要使用 ref 传递它们。如果我使用 ref 传递它们,则会出现错误:

无法将 ref double[] 转换为 ref 对象。

呃……看起来很熟悉。当我在两个变量的实例化中将 double[] 更改为 Object 时,我终于让编译器停止产生错误。但是......当我运行该函数时,我收到类型不匹配错误。

我真的不知道我该去哪里。互联网上几乎没有关于使用Measurement Studio 进行C# 编程的信息。即使有,我也确信解决方案比我预期的要简单得多。历史告诉我,当出现我无法弄清楚的错误时,它几乎总是愚蠢的。

It seems like I'm on here asking a question just about every day now. I'm not sure if that's a good thing or a bad thing...

Today's "Flavor-Of-The-WTF" involves my complete and utter cluelessness when using a function from a NI Measurement Studio object. As with most of my previous questions, this is in regards to an internship project where I've been tasked with translating a VB6 project into C# in the .Net Framework 2.0.

The original VB code looks something like this:

Public Sub FFT(ZData() As Single, FFTData() As Single)
    Dim realdata As Variant
    Dim imgdata As Variant

    // (... Some unrelated other code in here ...)

    // Here we pass three variables to a NI CWDSP object's ReFFT function
    CWDSP1.ReFFT ZData, realdata, imgdata

    // (... More unrelated code ...)
End Sub

I stuck in a MsgBox at one point to see how realdata and imgdata were being interpreted. They're both Double()s. It works just fine for what it does, in the original program. Admittedly, my intimate knowledge of the original program is only mediocre, as I picked up the project recently, and only have a few years of programming under my belt (and no years of mechanical engineering. The programmer was a mechanical engineer, the application itself a measuring tool for machine output).

Taking the code over to C#, I tried rewriting it as such:

private void FFT(float[] ZData, float[] FFTData){
    double[] realData = new double[1000];
    double[] imgData = new double[1000];

    // (... Unrelated intermediate code ...)

    DSP.ReFFT(ZData, realData, imgData);

    // (... Unrelated intermediate code ...)
}

As you can see, I started by doing it basically the same way as the original VB. The following error came up: Cannot Convert double[] to ref object

Well, that's no good. So I tried: DSP.ReFFT(ZData, ref realData, ref imgData);

Only to get back: Cannot Convert ref double[] to ref object

So I did what I thought was obvious. I boxed realData and imgData into objects, and passed them to the function. It's not too fond of that, however. If I pass the new objects without ref, it insists that I need to pass them with ref. If I pass them with ref, it gives me the error:

Cannot Convert ref double[] to ref object.

Huh... that looks familiar. I finally get the compiler to stop producing errors when I change double[] to Object in the instantiation of the two variables. But... when I run the function, I get a Type Mismatch error.

I've really got no idea where I go from here. There's little to no information about programming for C# with Measurement Studio out there on the internet. Even if there was, I'm sure the solution is much more simple than I expect it to be. History has taught me that when there's a bug I can't figure out, it's almost always something stupid.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

静待花开 2024-09-15 09:04:55

在您的 FFT 函数中尝试一下:

object realData = new double[1000];
object imgData = new double[1000];
ReFFT(new object(), ref realData, ref imgData);

double[] realDataArray = (double[])realData;

通过将对象实例化为新的 double[1000],您可以确定虽然您将 realData 视为对象,但其基础类型是 double[]。稍后,在方法调用之后,您将通过创建一个新数组并将前一个数组转换为原始类型来关闭 realData 数组。装箱/拆箱可能比严格需要的要多,但希望它能够理解

尝试 2 的要点:

double[] somerealData = new double[1000];
double[] someimgData = new double[1000];
object realData, imgData;
realData = somerealData;
imgData = someimgData;

ReFFT(new object(), ref realData, ref imgData);

double[] realDataArray = (double[])realData;
Console.WriteLine(realDataArray.Length);
realDataArray[0] = 1.0d;
Console.WriteLine(realDataArray[0]);

我已经在 .NET 2.0 控制台应用程序中尝试了第二种方法,所以我非常确定它是有效的。如果没有,那么我们就需要退后一步,重新评估情况。

尝试 3:刚刚注意到 ReFFT 方法的第一个参数是 float[]。让我们试试这个:

double[] somerealData = new double[1000];
double[] someimgData = new double[1000];
//float[] zData placeholder since array comes from input param

object realData, imgData, zObj;
realData = somerealData;
imgData = someimgData;
zObj = zData;

ReFFT(zObj, ref realData, ref imgData);

double[] realDataArray = (double[])realData;
Console.WriteLine(realDataArray.Length);
realDataArray[0] = 1.0d;
Console.WriteLine(realDataArray[0]);

Give this a go in your FFT function:

object realData = new double[1000];
object imgData = new double[1000];
ReFFT(new object(), ref realData, ref imgData);

double[] realDataArray = (double[])realData;

by instantiating the object as a new double[1000], you are establishing that although you are treating realData as an object, its' underlying type is double[]. Later, after the method call, you're closing the realData array by creating a new one and casting the previous one to the original type. It may be more boxing/unboxing than is strictly needed, but hopefully it gets the point across

Try 2:

double[] somerealData = new double[1000];
double[] someimgData = new double[1000];
object realData, imgData;
realData = somerealData;
imgData = someimgData;

ReFFT(new object(), ref realData, ref imgData);

double[] realDataArray = (double[])realData;
Console.WriteLine(realDataArray.Length);
realDataArray[0] = 1.0d;
Console.WriteLine(realDataArray[0]);

I've tried the second approach in a .NET 2.0 console app, so I'm pretty sure that it works. If it doesn't, then we'll need to take a step back and re-assess the situation.

Try 3: Just noticed that the first parameter of the ReFFT method is a float[]. Let's try this:

double[] somerealData = new double[1000];
double[] someimgData = new double[1000];
//float[] zData placeholder since array comes from input param

object realData, imgData, zObj;
realData = somerealData;
imgData = someimgData;
zObj = zData;

ReFFT(zObj, ref realData, ref imgData);

double[] realDataArray = (double[])realData;
Console.WriteLine(realDataArray.Length);
realDataArray[0] = 1.0d;
Console.WriteLine(realDataArray[0]);
独夜无伴 2024-09-15 09:04:55

尝试向其发送一个对象,然后检查返回的对象类型怎么样?所以像这样:

    private void FFT(float[] ZData, float[] FFTData)
    {
        object realData = new object();
        object imgData = new object();
    
        // (... Unrelated intermediate code ...)
    
        DSP.ReFFT(ZData, ref realData, ref imgData);
        
        // Find out what the type actual is (this will probably only work
        // if the values are assigned with the new data type)
        // but worth a shot:
        type t1 = typeof(realData);
        type t2 = typeof(imgData);
    
        // if t1 and t2 show the actual types, replace the
        // type above (new object() with the type here)
    
        // (... Unrelated intermediate code ...)
    }

更新:刚刚看到你上面的最后一条评论。您可能想要创建三个单独的对象。 Test1、Test2 和 Test3 都是 new object() 的。

来自帖子中,它说文档要执行以下操作:

开始>>所有程序>>美国国家仪器>> Measurement Studio 7.1 for VS .NET 2003>>测量工作室文档

然后选择“过滤器”下拉菜单下的“Measurement Studio”。

现在导航到帮助树
"NI Measurment Studio 帮助 >> NIMeasurement Studio .NET 类库 >> 参考 >> National Instruments.Analysis.SpectralMeasurements >> 测量类 >> 方法 >> ReFFT???方法。

What about just trying to send it an object, then check the type of what you get back. So something like this:

    private void FFT(float[] ZData, float[] FFTData)
    {
        object realData = new object();
        object imgData = new object();
    
        // (... Unrelated intermediate code ...)
    
        DSP.ReFFT(ZData, ref realData, ref imgData);
        
        // Find out what the type actual is (this will probably only work
        // if the values are assigned with the new data type)
        // but worth a shot:
        type t1 = typeof(realData);
        type t2 = typeof(imgData);
    
        // if t1 and t2 show the actual types, replace the
        // type above (new object() with the type here)
    
        // (... Unrelated intermediate code ...)
    }

Update: Just saw your last comment above. You'll probably want to create three seperate objects. Test1, Test2 and Test3 all as new object()'s.

From this post, it says for documentation to do the following:

Start >> All Programs >> National Instruments >> Measurement Studio 7.1 for VS .NET 2003 >> Measurement Studio Documentation

Then select "Measurement Studio" under the Filter pull down.

Now navigate the help tree to
"NI Measurment Studio Help >> NI Measurement Studio .NET Class Library >> Reference >> National Instruments.Analysis.SpectralMeasurements >> Measurements Class >> Methods >> ReFFT??? Method.

我家小可爱 2024-09-15 09:04:55

您说 DSP 是 COM,您遇到的奇怪错误向我表明根本问题是“编组”.NET 和 COM 之间的参数。我不是这方面的专家,所以这更像是一个建议,研究如何将 DSP 封装在 COM 互操作层中并通过该层调用它。

这是 MSDN 上的一个很好的起点:COM 互操作简介< /a>

You say that DSP is COM, and the odd errors you're getting suggests to me that the underlying problem is "marshalling" the parameters between .NET and COM. I am no expert on this, so this is more along the lines of a suggestion to investigate how one would encapsulate DSP in a COM-interop layer and calling it through that layer.

Here's a good starting point on MSDN: Introduction to COM Interop

纵山崖 2024-09-15 09:04:55

我从来没有弄清楚这个函数出了什么问题,所以这个答案可能对某些人没有帮助。不过,如果您像我一样在 C# 中使用Measurement Studio 并且需要执行 FFT,显然有一个 .NET 类包含它,并且似乎可以工作。

NationalInstruments.Analysis.Dsp.Transforms.FFT(以及 InverseFFT 和其他一些)。不过,我仍然很想知道与另一位的交易是什么……

感谢大家的建议。它们都是合乎逻辑的,可能应该起作用,但由于某种未知的原因而没有起作用(可能与函数的内部工作原理有关)。

I never did figure out what was wrong with the function, so this answer might not help some people. Nevertheless, if you're using Measurement Studio in C# like I am and need to do a FFT, there was apparently a .NET class that includes it, and appears to work.

NationalInstruments.Analysis.Dsp.Transforms.FFT (and InverseFFT and a bunch of others). I'd still love to know what the deal with the other one was, though...

Thanks everyone for your suggestions. They were all logical ones that probably should have worked, but didn't for some unknown reason (likely relating to the inner workings of the function).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文