C++ 到 C# 移植问题:我将如何处理具有 double* 作为参数的方法?
Posted
技术标签:
【中文标题】C++ 到 C# 移植问题:我将如何处理具有 double* 作为参数的方法?【英文标题】:C++ to C# port question: How would I deal with a method that has a double* as a parameter? 【发布时间】:2011-08-15 17:47:13 【问题描述】:我正在将 C++ 库移植到 C#,并且遇到了一些将双 * 指针作为参数的方法。处理这个问题的最佳方法是什么?也许修改调用代码使其不传递指针?我只想将代码包装在“不安全”块中并设置编译器的 /unsafe 标志,但我不能在方法签名中这样做。
【问题讨论】:
代码用 double* 做什么?它们被用作数组吗?它们是否被用于返回值? 你的意思是指向 double 类型的指针还是作为指向类型数组的指针的 'type ** name'? 您应该发布一些 C++,因为这取决于 double* 的使用方式。很可能 double 是通过引用传递的,以允许更改其值,在这种情况下,您可以使用 ref/out - 但还有其他可能性。 不,它不是通过引用传递的。参数上没有与号。 【参考方案1】:也许在参数上使用ref
(或out
)可能就足够了,或者如果您需要处理这些参数的数组,请使用double[]
。
也许发布方法定义,以便更清楚您真正需要什么。
【讨论】:
【参考方案2】:我假设您希望使用托管安全代码
取决于指针的使用方式。如果它在您的方法中用作数组,那么您需要将数组传递给方法,因此需要更改签名。
如果它被用作双精度并再次(重新)分配它取决于。该方法是否有返回类型?如果是这样使用 ref double 可能是要走的路。如果方法没有返回类型,则返回被分配的值,并让调用者传递给本地而不是通过 ref 传递。
如果 double* 用作双精度且从不赋值,则简单地传递为双精度。
【讨论】:
【参考方案3】:可能它转换为 ref double 或 out double 或 double[]。应该是哪个取决于代码的语义。 C++ double* 实际上有很多含义。
不太可能需要不安全的代码。
【讨论】:
【参考方案4】:您可以将函数标记为 unsafe
并使用 /unsafe 标志进行编译:
private static unsafe void MyFunction(double *d)
见http://msdn.microsoft.com/en-us/library/chfa2zb8.aspx
【讨论】:
我没有投反对票,但我感觉这是因为提倡使用unsafe
而没有明确的理由需要它;很可能 OP 的代码可以很容易地用托管习语编写。
这是非常正确的,我完全同意它可以通过其他方式完成。但是,OP 说他会将它包装在一个不安全的块中,但不能包含方法签名。这个答案说您可以使用 unsafe 关键字将参数包含在 unsafe 声明中。
确实如此,但鉴于 OP 询问“处理此问题的最佳方法是什么”,我认为这就是大多数人的来源;不仅可以以其他方式完成,而且几乎可以肯定应该以其他方式完成。
虽然从内存安全的角度来看,Evan 的回答可能不是最好的解决方案,但我确实学到了一些新东西:能够将方法标记为不安全。一旦我有机会尝试几种解决方案,我将接受答案。感谢各位大佬的大力投入!!!【参考方案5】:
在你传递指针的地方,你只是将默认的pass-by-value机制更改为pass-by-reference,在这种情况下,使用@987654321 @关键字:
public void SomeMethod(ref double val)
你需要确保在调用它时指定ref
:
SomeMethod(ref 12.0);
【讨论】:
这是假设他没有传递一个数组。 不必要的反对票?如果这个答案有问题,请写评论。【参考方案6】:您所做的将取决于指针的使用方式。如果指针存在以便调用代码可以传递double
s 的数组,则让方法接受double[]
。如果指针存在以便被调用代码可以从调用者修改double
变量的值,那么您有两种选择:
double
成为返回值(我建议这样做)
将参数声明为ref
或out
(取决于您是否要保证被调用的函数会赋值。
不要只是在代码周围抛出unsafe
块,以便您可以继续使用指针; unsafe
应该非常谨慎使用(最好不要使用)。
【讨论】:
【参考方案7】:这取决于函数如何使用指针。您确实没有提供足够的信息来给出可靠的答案,但无论如何我都会试一试。
普通 C# 代码
如果方法中的代码取消引用指针并赋值,而不进行任何指针运算,则只需将参数设为out
参数。
如果上一段为真,并且您还没有返回值,只需修改方法的签名以返回double
。
如果代码不是在做指针运算,而是使用在指向的位置已经存在的值,以及分配它,那么将参数设为ref
参数。
如果代码不进行指针运算,使用该值,但不分配它,那么您应该将其从指针更改为普通的double
,而不是使其成为ref
或out
。
如果函数的实现是指针运算,那么您需要构建并传递某种可索引集合,例如实现IList
或数组的集合。
普通 C# 代码的替代方案
您也可以随时选择将您的代码标记为unsafe
,并使用指针。与简单的逻辑翻译相比,这可能需要更多的工作,但更有可能保持类似的性能配置文件。
您也可以选择使用 C++/CLI 而不是 C#。它也是一种 .Net 语言,直接与现有 C++ 代码集成可能更简单(取决于您的应用)。
【讨论】:
谢谢梅林。很好的深入回答。回到我正在移植的 C++ 库后,我发现包含相关方法的静态类甚至没有在任何地方使用,除非在一些示例代码中使用。该方法用于天文计算中的拉格朗日点计算。以上是关于C++ 到 C# 移植问题:我将如何处理具有 double* 作为参数的方法?的主要内容,如果未能解决你的问题,请参考以下文章
当循环中调用了异步函数时,Node.JS 将如何处理循环控制?