I'm trying to call some C++ I've written from some C# (also my code) and having troubles with Interop/PInvoke getting a populated int[]
back. Is there a way I could just add a compile-time reference to the C++ project from the C# project and call the functions within it as though it were just another C# class library?
I have a basic sample to illustrate the problem with the array. This is the C# signature for the C++ function I'm calling.
[DllImport("CPlusPlusTargetLibrary.dll", CallingConvention = CallingConvention.StdCall)]
private static extern void Accumulate
(
int input,
int accumulationFactor,
int numberOfAccumulations,
[In, Out, MarshalAs(UnmanagedType.LPArray)]
int[] accumulationsPointer
);
This is how it's called from C#:
var numberOfAccumulations = 3;
var accumulations = new int[numberOfAccumulations];
Accumulate(-8, 1, numberOfAccumulations, accumulations);
This is its declaration in the C++ header file:
__declspec(dllexport) const void __stdcall Accumulate
(
const signed long input,
const signed long accumulationFactor,
const signed long numberOfAccumulations,
signed long* accumulationsPointer
);
And this is its implementation in C++:
__declspec(dllexport) const void __stdcall Accumulate
(
const signed long input,
const signed long accumulationFactor,
const signed long numberOfAccumulations,
signed long* accumulationsPointer
)
{
for (auto index = 0; index < numberOfAccumulations; index++, accumulationsPointer++)
{
auto accumulation = input * ((index + 1) * accumulationFactor);
accumulationsPointer = &accumulation;
}
}
The accumulations
array just comes back as a 3-element array of all 0
- just as it was passed-in. Instead it should have come back containing -8
, -16
and -24
.
I followed the documentation on MSDN for marshaling int[]
and according to it, I shouldn't have needed any manual Marshaling (but even taking out the MarshalAs
attribute didn't resolve the issue): https://docs.microsoft.com/en-us/dotnet/framework/interop/marshaling-different-types-of-arrays
I had hoped if I could reference the C++ project directly then I wouldn't have to deal with all the type-related runtime failures.