1

I'm trying to copy an array of floats from my C# application to an array in a C-coded DLL.

Im used to programming in C#, not so much with C. However I have no problem doing the reverse procedure ie. reading an array of floats from a C coded DLL into my C# application. I've read several threads on this site but cant work out where Im going wrong.

C# CODE

[DllImport(@"MyDll")]
static extern int CopyArray(double[] MyArray);

double[] myValues = new double[100]
int a = 0;
while(a < 100)
{
    myValues[a] = a;
    a++;
}

CopyArray(myValues);

C++ DLL

This is the function header;

__declspec(dllexport) int CopyArray(float* Wavelengths);

This is the function code;

float theValues[100];
int CopyArray(float* theArray)
{
    status = 0;
    int count = 0;
    while (count < 100)
    {
        theValues[count] = theArray[count];
        ++count;
    }
    return(status);
}

I'm expecting my C# array to end up in the C array "theValues" but that's not happening. There is nothing getting into "theValues" array.

Doug
  • 113
  • 1
  • 5
  • You need to specify the CallingConvention in the [DllImport] declaration. Should be Cdecl for this one. That it didn't crash with an AVE is unlucky. While you're at it, add an extra parameter so the C code doesn't have to guess at the array size. – Hans Passant May 31 '19 at 11:26

1 Answers1

1

A couple of things.

  1. You are mixing data types and they are different lengths (float is 32bit and double is 64bit). Both types exist in both languages, but your caller and callee need to agree on the data type. Here is a list of data types and their managed/unmanaged equivalents.
  2. The parameter you are sending is not a pointer. It might be translated to that automatically by the compiler, but there are several options. It is entirely possible that the compiler will pick one you don't want (more info here). The one you are probably looking for is [In]. If you want to get data back from C to C#, you will also want [Out]:
[DllImport(@"MyDll")]
static extern int CopyArray([In, Out]double[] MyArray);
Thoryn Hawley
  • 335
  • 1
  • 7
  • Thanks Thoryn. Yes I will try [In] and for some reason I assumed a double in C# equates to a float in C. – Doug May 30 '19 at 21:27
  • Don't add [Out] needlessly, having to copy the array content back can be quite expensive. The C code doesn't alter the elements so no need to copy back. In this specific case the attributes don't matter at all, a double[] is a "blittable" type and the pinvoke marshaller can pass the managed array directly. The [DllImport] should also specify CallingConvention.Cdecl. – Hans Passant May 31 '19 at 11:38
  • Hans is correct. I only added the Out to show how to add both at the same time. – Thoryn Hawley Jun 01 '19 at 01:45