I'm trying to PInvoke the following function from GitHub's fork of CMark
char *cmark_markdown_to_html(const char *text, size_t len, int options)
and here's my PInvoke signature:
[DllImport("cmark.dll")]
public static extern IntPtr cmark_markdown_to_html(
[In()] [MarshalAs(UnmanagedType.LPStr)] string text,
[MarshalAs(UnmanagedType.SysUInt)] uint len,
[MarshalAs(UnmanagedType.SysInt)] int options);
I call it as follows:
var retValue = cmark_markdown_to_html(markdown, 0, 0);
However, it throws a Marshaling exception the with the message:
Cannot marshal 'parameter #2':
Invalid managed/unmanaged type combination
(Int32/UInt32 must be paired with I4, U4, or Error).
OK, so I change the signature to:
[DllImport("cmark.dll")]
public static extern IntPtr cmark_markdown_to_html(
[In, MarshalAs(UnmanagedType.LPStr)] string text,
[MarshalAs(UnmanagedType.U4)] uint len,
[MarshalAs(UnmanagedType.I4)] int options);
Now it throws a PInvokeStackImbalance
error
The name '$exception' does not exist in the current context
Native stuff is a mystery to me. Can someone help?
PInvokeStackImbalance
Presumably CMark is using the default calling convention. The default calling convention for C code is "Cdecl", while the default used for P/invoke calls is "StdCall". The calling convention specifies how the arguments and return value are placed on the call stack. A mismatch between the used calling convention causes the stack to become imbalanced.
You can specify the calling convention to use from C# code in the
DllImport
attribute.Marshalling
In case you want your code to be compatible with architectures other than 32-bit, you would want to marshall
size_t
withUIntPtr
. (Read @Eugene Podskal answer)Then you can call the method like so