As I understand it, you will need to call the function twice. Once you will pass an empty array and ask the function to calculate the required length. And then again you call with an allocated array which the function will populate.
The unmanaged code might look like this:
void __stdcall fn(double p[], int* pLength)
{
int i = 0;
double p_ = 0;
do
{
if (p) p[i] = p_;
p_ = ...;
i++;
}
while (...);
*pLength = i;
}
Note that the code checks whether or not p
is assigned, and only writes to the array if it is.
On the managed side the code looks like this:
[DllImport(...)]
public static extern void fn(double[] p, out int pLength);
....
int pLength;
fn(null, out pLength);
double[] p = new double[pLength];
fn(p, out pLength);
A safer version of this would be to pass the length of the array to the function. That would allow the function to make sure that it does not write off the end.
void __stdcall fn(double p[], int* pLength)
{
int i = 0;
double p_ = 0;
do
{
if (p)
{
if (i >= *pLength) return -1; // or some other error code
p[i] = p_;
}
p_ = ...;
i++;
}
while (...);
*pLength = i;
}
And the managed side:
[DllImport(...)]
public static extern void fn(double[] p, ref int pLength);
....
int pLength = 0;
fn(null, ref pLength);
double[] p = new double[pLength];
fn(p, ref pLength);
If you only want to call the function once then you need to do the following:
- Allocate memory dynamically in the unmanaged code. Use
GlobalAlloc
so that the managed code can deallocate it. - Be prepared to re-allocate in the unmanaged code if your initial allocation proved to be of insufficient length.
- Use an
out
parameter of typeIntPtr
in the managed code to get the pointer to unmanaged memory. - Use
Marshal.Copy
to copy the array contents into your manageddouble[]
object. - Call
Marshal.FreeHGlobal
to free the unmanaged memory.
This technique is much more complex and involves a lot more boiler-plate. You only take this approach when there is a significant performance overhead in the first approach that I outlined.
An aside. Please don't put your files in the system directory. It belongs to the system and you are expected not to modify it. Place the DLL in the same directory as the host executable.