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
.
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;
}
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);
You can call it like this:
IntPtr str = Marshal.StringToHGlobalAnsi(inputStr);
IntPtr endptr = IntPtr.Zero;
double val = strtod(str, ref endptr);
Marshal.FreeHGlobal(str);
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.
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"
but strtod
won't tokenize that because of the spurious commas.