1

I have a C++ .DLL and C# application. In DLL I have a function like:

namespace Sample { public ref class SampleClass { public: int f(int arr[], int length); }; }

How can I call it from C# application? Problem is that in C++ I can use only int* argument and cannot declare int[], and only int[] variable in c#.

I have tried to declare int*[] type in C# but it is impossible due to

Cannot take address of a managed type

error. I have no idea how can I put an array into this function.

Upd: trying to dllimport like

[DllImport("samplelib.fll", EntryPoint = "Sample.SampleClass.f")] 

but that seems to be wrong.

AndrewR
  • 592
  • 2
  • 6
  • 20
  • Why would you even have that signature in C++? How do you know how many elements are in `arr`? – crashmstr Aug 27 '14 at 12:14
  • DllImport to...import that and signature simply int[]. See examples on MSDN. – Adriano Repetti Aug 27 '14 at 12:14
  • 2
    @crashmstr `int f(int arr[])` is the same as `int f(int arr*)` in C++. The [] syntax is just there to confuse. – juanchopanza Aug 27 '14 at 12:16
  • 1
    @juanchopanza but then the OP's argument about only being able to use `int*` (and **not** `int[]`) in C++ doesn't make sense.. He should be able to use both – default Aug 27 '14 at 12:20
  • @Default No, you can't declare an `int[]` (without a brace-encluses initializer list), but you can declare an `int*`. The two are the same in function parameter lists only. – juanchopanza Aug 27 '14 at 12:23
  • @juanchopanza but in C# he wants to pass an integer array (i.e. `int[]`). I think the user is confusing C++ arrays and C# arrays a bit. – crashmstr Aug 27 '14 at 12:27
  • 1
    @crashmstr Right. And my first comment should be a hint to OP that there is no length information being passed with that signature in C++. – juanchopanza Aug 27 '14 at 12:43

2 Answers2

0

I'm not sure, if this is what you want. Your example seems at bit incomplete ...

Let's say you have something like this in C/C++:

void TakesAnArray(int size, int array[]) {
   printf_s("[unmanaged]\n");
   for (int i=0; i<size; i++)
      printf("%d = %d\n", i, array[i]);
}

Then you want to call ist from C#, so you create a wrapper class.

internal static class NativeMethods
{
   [DllImport("SomeLib.dll" )]
   public static extern void TakesAnArray(int size, [In, Out] int[] array);
}
Sam Harwell
  • 97,721
  • 20
  • 209
  • 280
Mithrandir
  • 24,869
  • 6
  • 50
  • 66
  • Thank you, that works. But i can't find the proper syntax for entry point. I`m trying Sample.SampleClass.f, but that doesn`t work. – AndrewR Aug 27 '14 at 13:33
  • @maniac98066 how to find entry point for C++ .DLL and use it: http://stackoverflow.com/a/12885084/3908097 – Rimas Aug 27 '14 at 14:51
0
int[] arr = new int[10];
int ptrsize = arr.Length * Marshal.SizeOf(typeof(int));
IntPtr arrptr = Marshal.AllocHGlobal(ptrsize);
Marshal.Copy(arr, 0, arrptr, ptrsize);
NativeFunction(arr.Length, arrptr);
//after
Marshal.FreeHGlobal(arrptr);

Use the array as a pointer

void NativeFunction(int length, int* array) { /*...*/ }

Import(.\\ is executable path)

[DllImport(".\\MyLib.dll")]
static extern void NativeFunction(int length, IntPtr array);
Sam
  • 2,950
  • 1
  • 18
  • 26
  • Are you sure you want the memory size of the array instead of the number of elements being passes into the C++ function? – crashmstr Aug 27 '14 at 12:40
  • @crashmstr yeah you are right fixed with length – Sam Aug 27 '14 at 12:42
  • -1: This code is already more complicated than using a proper P/Invoke signature, and doesn't handle releasing memory in all the exception cases where a proper signature would handle it for you. – Sam Harwell Aug 27 '14 at 12:54