How do I pass a const char* to a C function from C

2019-01-17 20:48发布

问题:

I try to call a plain C-function from an external DLL out of my C#-application. This functions is defined as

void set_param(const char *data)

Now I have some problems using this function:

  1. How do I specify this "const" in C#-code? public static extern void set_param(sbyte *data) seems to miss the "const" part.

  2. How do I hand over a plain, 8 bit C-string when calling this function? A call to set_param("127.0.0.1") results in an error message, "cannot convert from 'string' to 'sbyte'"*.

回答1:

It looks like you will be using the ANSI char set, so you could declare the P/Invoke like so:

[DllImport("yourdll.dll", CharSet = CharSet.Ansi)]
public static extern void set_param([MarshalAs(UnmanagedType.LPStr)] string lpString);

The .NET marshaller handles making copies of strings and converting the data to the right type for you.

If you have an error with an unbalanced stack, you will need to set the calling convention to match your C DLL, for example:

[DllImport("yourdll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]

See pinvoke.net for lots of examples using Windows API functions.

Also see Microsoft's documentation on pinvoking strings.



回答2:

A const char* is simply a string in .NET - the managed side does not (yet) understand the notion of read-only parameters.

If you are using this in a P/Invoke context, you should declare a MarshalAs attribute and marshal it as a LPStr. The resulting signature would look something along the lines of

[DllImport("SomeModule.dll")]
public static extern void set_param([MarshalAs(UnmanagedType.LPStr)]string lpString);

There's also this article on MSDN with more information on how to marshal native strings to a managed environment.