本文介绍了在.NET中使用C库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在C#项目中使用C库。我该怎么办?

I need to use the C library in a C# project. How can I do?

更具体地说:出于效率考虑,我需要使用函数从字符串中提取双精度值(例如 9.63074,9.63074 -5.55708e-006 0,0 1477.78)。如果您对如何优化此操作有任何建议,请不要害羞,但主要问题仍然是标题指定的问题。

To be more specific: for reasons of efficiency I need to use the strtod function to extract double values from a string (like this "9.63074,9.63074 -5.55708e-006 0 ,0 1477.78"). If you have suggestions about how to optimize this operation do not be shy, but the main question remains that specified by title.

推荐答案

我认为p /调用 strtod 不可能比纯C#解决方案更有效。在托管/非托管转换中会产生开销,我认为这对于 strtod 这样琐碎的事情来说意义重大。我自己会使用C#令牌生成器,并结合 double.Parse

I think it very unlikely that p/invoking to strtod would be more efficient than a pure C# solution. There is an overhead in managed/unmanaged transitions and I would think that would be significant for something as trivial as strtod. Myself I would use a C# tokenizer, combined with double.Parse.

最简单的C#令牌生成器是 String.Split()产生以下例程:

The simplest C# tokenizer is String.Split() which yields this routine:

static List<double> getValues(string str)
{
    List<double> list = new List<double>();
    foreach (string item in str.Split(default(Char[]), StringSplitOptions.RemoveEmptyEntries))
        list.Add(double.Parse(item));
    return list;
}






但是,因为我喜欢p / invoke,这是从C#调用 strtod 的方式,请记住,我建议您不要在实际代码中使用此方法。


However, since I enjoy p/invoke, here's how you would call strtod from C#, bearing in mind that I recommend you don't use this approach in real code.

[DllImport(@"msvcrt.dll", CallingConvention=CallingConvention.Cdecl)]
static extern double strtod(IntPtr str, ref IntPtr endptr);

您可以这样称呼它:

IntPtr str = Marshal.StringToHGlobalAnsi(inputStr);
IntPtr endptr = IntPtr.Zero;
double val = strtod(str, ref endptr);
Marshal.FreeHGlobal(str);

我将字符串作为 IntPtr ,因为您将反复调用 strtod 以遍历整个缓冲区。我没有在这里显示出来,但是如果您要使用 endptr 的话,就需要按照我的说明进行操作。

I'm passing the string as an IntPtr because you would be calling strtod repeatedly to walk across the entire buffer. I didn't show that here, but if you are going to make any use of endptr then you need to do it as I illustrate.

当然,要有效地远程使用 strtod ,您需要访问全局 errno 变量。您需要处理全局变量的事实应该足以警告您这是龙。而且,通过 errno 提供的错误报告非常有限。但是,如果需要,它在这里:

Of course, to use strtod remotely effectively you need to gain access to the errno global variable. The very fact that you need to deal with a global variable should be warning enough that here be dragons. What's more, the error reporting offered through errno is exceedingly limited. However, if you want it, here it is:

[DllImport(@"msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int _get_errno();

最后一点。您建议的输入字符串为

One final point. Your suggested input string is

"9.63074,9.63074 -5.55708e-006 0 ,0 1477.78"

,但由于虚假逗号, strtod 不会对此进行标记。

but strtod won't tokenize that because of the spurious commas.

这篇关于在.NET中使用C库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-23 20:50