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】:

您所做的将取决于指针的使用方式。如果指针存在以便调用代码可以传递doubles 的数组,则让方法接受double[]。如果指针存在以便被调用代码可以从调用者修改double 变量的值,那么您有两种选择:

修改调用的语义,使 double 成为返回值(我建议这样做) 将参数声明为refout(取决于您是否要保证被调用的函数会赋值。

不要只是在代码周围抛出unsafe 块,以便您可以继续使用指针; unsafe 应该非常谨慎使用(最好不要使用)。

【讨论】:

【参考方案7】:

这取决于函数如何使用指针。您确实没有提供足够的信息来给出可靠的答案,但无论如何我都会试一试。

普通 C# 代码

如果方法中的代码取消引用指针并赋值,而不进行任何指针运算,则只需将参数设为out 参数。

如果上一段为真,并且您还没有返回值,只需修改方法的签名以返回double

如果代码不是在做指针运算,而是使用在指向的位置已经存在的值,以及分配它,那么将参数设为ref参数。

如果代码不进行指针运算,使用该值,但不分配它,那么您应该将其从指针更改为普通的double,而不是使其成为refout

如果函数的实现是指针运算,那么您需要构建并传递某种可索引集合,例如实现IList 或数组的集合。

普通 C# 代码的替代方案

您也可以随时选择将您的代码标记为unsafe,并使用指针。与简单的逻辑翻译相比,这可能需要更多的工作,但更有可能保持类似的性能配置文件。

您也可以选择使用 C++/CLI 而不是 C#。它也是一种 .Net 语言,直接与现有 C++ 代码集成可能更简单(取决于您的应用)。

【讨论】:

谢谢梅林。很好的深入回答。回到我正在移植的 C++ 库后,我发现包含相关方法的静态类甚至没有在任何地方使用,除非在一些示例代码中使用。该方法用于天文计算中的拉格朗日点计算。

以上是关于C++ 到 C# 移植问题:我将如何处理具有 double* 作为参数的方法?的主要内容,如果未能解决你的问题,请参考以下文章

您将如何处理字符串通配符,而不仅仅是比较正确的值?

将 Visual C++ 项目移植到 C# [关闭]

当循环中调用了异步函数时,Node.JS 将如何处理循环控制?

c# FileSystemWatcher如何处理多个文件?

您将如何处理 PHP + MySQL 字谜求解器? [关闭]

C# 创建 MIME 消息?