C ++和C#数组和无效转换

时间:2022-09-01 09:51:36

I'm converting C++ code to C# code, it happens to be the Fast Fourier Transform on an image in the Frequency Domain. Just to give some context.

我正在将C ++代码转换为C#代码,它恰好是频域中图像的快速傅立叶变换。只是给出一些背景信息。

Here is a link to the C++ Code : fft.cc

这是C ++代码的链接:fft.cc

I have this function called Step, its signature is this in C++:

我有这个叫做Step的函数,它的签名是用C ++编写的:

void step ( int n, int mj, float a[], float b[], float c[], float d[], float w[], float sgn );

and is called like this:

并像这样调用:

step ( n, mj, &x[0*2+0], &x[(n/2)*2+0], &y[0*2+0], &y[mj*2+0], w, sgn );

I want to convert it to C#, now this function operates on either Y or X arrays depending on whether its a Forward Fast Fourier Transform or a Backward Fast Fourier Transform. (More context)

我想将它转换为C#,现在这个函数可以在Y或X数组上运行,具体取决于它是前向快速傅里叶变换还是后向快速傅里叶变换。 (更多背景)

What I don't understand, is that in C#, doing x[0*2+0] does nothing.... firstly putting an integer in the square brackets actually calls for a variable at a position in that array.

我不明白的是,在C#中,做x [0 * 2 + 0]什么都不做....首先在方括号中放一个整数实际上是在该数组中的某个位置调用一个变量。

But what is it doing in C++, I know that the & is equiv to the ref C# keyword, it is saying get the contents from the array that is being pointed too, but I feel that in this context it means more than just that.

但是它在C ++中做了什么,我知道&等同于ref C#关键字,它是说从数组中获取指向的内容,但我觉得在这种情况下它不仅仅意味着它。

So how would you call that function in C#, obviously this fails:

那么你如何在C#中调用该函数,显然这会失败:

step(n, mj, x[0 * 2 + 0], x[(n / 2) * 2 + 0], y[0 * 2 + 0], y[mj * 2 + 0], w, sgn);

3 个解决方案

#1


2  

In C++, this is passing the address of an entry of the array to the function. This doesn't work in C#, because you cannot take the address of an entry of an array. I suggest rewriting the declaration to pass the indices only and pass the array separately. Or make the x and y array a member of the containing class.

在C ++中,这是将数组条目的地址传递给函数。这在C#中不起作用,因为您无法获取数组条目的地址。我建议重写声明只传递索引并分别传递数组。或者使x和y数组成为包含类的成员。

Uh, or if you're only interested in the single element, you could pass the element instead. Remember that float b[] in C++ is the same as float* b, so if skip only accesses b[0] (and not [b+1]), then that would probably be the easier solution).

呃,或者如果你只对单个元素感兴趣,你可以改为传递元素。请记住,C ++中的float b []与float * b相同,所以如果skip只访问b [0](而不是[b + 1]),那么这可能是更简单的解决方案)。

When we have a C++ declaration like

当我们有像这样的C ++声明时

void step (float a[]) 

which is the same as

这是一样的

void step (float* a)

And we call it with

我们称之为

step(&x[2]);

The function step sees an array of float that starts at the second entry of x. So, inside step

函数步骤查看从x的第二个条目开始的float数组。所以,在步骤内

float f = a[0];

would refer to the element at x[2];

会引用x [2]处的元素;

Of course, one could also address a[27], but that's prone for errors, since we do not know the (remaining) length of x.

当然,人们也可以解决[27],但这很容易出错,因为我们不知道x的(剩余)长度。

To help finding the optimal solution in this case, one needs to know what step does with the arguments. Would it be possible to post the step function or parts of it?

为了帮助在这种情况下找到最佳解决方案,需要知道参数的步骤。是否可以发布阶梯函数或部分函数?

#2


0  

Remove addresses, no way of changing a value except making it a class with functions to change the values or returning them. instead of float a[] use float[] a

删除地址,除了使其成为具有更改值或返回值的函数的类之外,无法更改值。而不是浮动a []使用float [] a

Here's how your function looks like, no headers needed:

这是你的函数的样子,不需要头文件:

public class entity
{
    public void Step(int n, int mj, float a[], float[] b, float[] c, float[] d, float[] w, float sgn)
    {
       ...
    }

    Step(0, 0, new[] { 1f, 1f }, new[] { 1f, 1f }, new[] { 1f, 1f }, new[] { 1f, 1f }, new[] { 1f, 1f }, 1f);
}

#3


0  

The C++ version lets you pass in pointers (think references) to certain elements in the data.

C ++版本允许您将指针(思考引用)传递给数据中的某些元素。

For a C# version, I would suggest you pass in the two arrays directly, and then only pass in the indices, so

对于C#版本,我建议你直接传入两个数组,然后只传入索引,所以

 void step ( int n, int mj, float a[], float b[], float c[], float d[], 
      float w[], float sgn );

becomes

void Step(float[] x, float[] y, int n, int mj, int ai, int bi, int ci, int di,
     int w, float sign)
{ 
      float a = x[ai];
      float b = x[bi];
      float y = y[ci];

      // .... compute whatever


     x[ai] = a;
     x[bi] = b;
     //...
}

And if you encounter something like a[5] in the C++ function, you can simply use

如果你在C ++函数中遇到类似[5]的东西,你可以简单地使用

float aa = x[ai+5];

but of course you need to think about writing the new value back, if necessary.

但是,如果有必要,你当然需要考虑重新编写新值。

#1


2  

In C++, this is passing the address of an entry of the array to the function. This doesn't work in C#, because you cannot take the address of an entry of an array. I suggest rewriting the declaration to pass the indices only and pass the array separately. Or make the x and y array a member of the containing class.

在C ++中,这是将数组条目的地址传递给函数。这在C#中不起作用,因为您无法获取数组条目的地址。我建议重写声明只传递索引并分别传递数组。或者使x和y数组成为包含类的成员。

Uh, or if you're only interested in the single element, you could pass the element instead. Remember that float b[] in C++ is the same as float* b, so if skip only accesses b[0] (and not [b+1]), then that would probably be the easier solution).

呃,或者如果你只对单个元素感兴趣,你可以改为传递元素。请记住,C ++中的float b []与float * b相同,所以如果skip只访问b [0](而不是[b + 1]),那么这可能是更简单的解决方案)。

When we have a C++ declaration like

当我们有像这样的C ++声明时

void step (float a[]) 

which is the same as

这是一样的

void step (float* a)

And we call it with

我们称之为

step(&x[2]);

The function step sees an array of float that starts at the second entry of x. So, inside step

函数步骤查看从x的第二个条目开始的float数组。所以,在步骤内

float f = a[0];

would refer to the element at x[2];

会引用x [2]处的元素;

Of course, one could also address a[27], but that's prone for errors, since we do not know the (remaining) length of x.

当然,人们也可以解决[27],但这很容易出错,因为我们不知道x的(剩余)长度。

To help finding the optimal solution in this case, one needs to know what step does with the arguments. Would it be possible to post the step function or parts of it?

为了帮助在这种情况下找到最佳解决方案,需要知道参数的步骤。是否可以发布阶梯函数或部分函数?

#2


0  

Remove addresses, no way of changing a value except making it a class with functions to change the values or returning them. instead of float a[] use float[] a

删除地址,除了使其成为具有更改值或返回值的函数的类之外,无法更改值。而不是浮动a []使用float [] a

Here's how your function looks like, no headers needed:

这是你的函数的样子,不需要头文件:

public class entity
{
    public void Step(int n, int mj, float a[], float[] b, float[] c, float[] d, float[] w, float sgn)
    {
       ...
    }

    Step(0, 0, new[] { 1f, 1f }, new[] { 1f, 1f }, new[] { 1f, 1f }, new[] { 1f, 1f }, new[] { 1f, 1f }, 1f);
}

#3


0  

The C++ version lets you pass in pointers (think references) to certain elements in the data.

C ++版本允许您将指针(思考引用)传递给数据中的某些元素。

For a C# version, I would suggest you pass in the two arrays directly, and then only pass in the indices, so

对于C#版本,我建议你直接传入两个数组,然后只传入索引,所以

 void step ( int n, int mj, float a[], float b[], float c[], float d[], 
      float w[], float sgn );

becomes

void Step(float[] x, float[] y, int n, int mj, int ai, int bi, int ci, int di,
     int w, float sign)
{ 
      float a = x[ai];
      float b = x[bi];
      float y = y[ci];

      // .... compute whatever


     x[ai] = a;
     x[bi] = b;
     //...
}

And if you encounter something like a[5] in the C++ function, you can simply use

如果你在C ++函数中遇到类似[5]的东西,你可以简单地使用

float aa = x[ai+5];

but of course you need to think about writing the new value back, if necessary.

但是,如果有必要,你当然需要考虑重新编写新值。