I have the next C# method:
internal static class FillArrayApi
{
[DllImport("NativeLibrary.dll", EntryPoint = "fill_array")]
internal static extern void FillArray(byte[] array, int length);
}
It is implemented in the native code like this:
extern "C" __declspec(dllexport) void fill_array(uint8_t* array, int length);
void fill_array(uint8_t* array, const int length)
{
for (int i = 0; i < length; i++)
{
array[i] = 1;
}
}
I use the native code to fill a managed array like this:
internal static class Program
{
public static void Main()
{
var array = new byte[] { 0, 0, 0, 0, 0 };
Console.WriteLine("Array before filling: " + string.Join(", ", array));
FillArrayApi.FillArray(array, array.Length);
Console.WriteLine("Array after filling: " + string.Join(", ", array));
}
}
The full implementation is here.
FillArray indeed fills my array with 1s. Is this a proper way to fill the array in the native code or I am just lucky that it works?
From the docs I can see that sometimes MarshalAs attribute is needed, also I have to use Out attribute in some cases. Do I have to use them in my case as well or it is fine to rely on the default behavior?
Edit: posted the whole code and unhardcoded the array length as suggested in the comments.
Edit #2: the return type of FillArray should be void of course, because the native function is void.
Your
DllImportdefinition is wrong.It should have
CDeclcalling conventionvoidreturn type[Out]on the array, as well asMarshalAswith aSizeParamIndex.While
[Out]is not necessary in some circumstances (when the array is pinned), it is advisable to add it anyway. The docs say:[MarshalAs]is necessary here for the same reason. While the default type will beLPArrayanyway,SizeParamindexis needed for marshalling the array back.Again, if pinning is used then it wouldn't be necessary, but that doesn't always happen. So if you are sure you will never do a cross-process (or cross-COM-apartment) call, only then you can leave off
[Out]and[MarshalAs].