Para devolver matrices en C se necesitan punteros. Para aclarar mi pregunta, creé una función .c simple y la compilé como DLL y accedí a ella mediante C#. La función C es:
#include <stdio.h> __declspec(dllexport) int* ReturnArray(int size) { int* arr = malloc(size * sizeof(int)); arr[0] = 19; arr[1] = 18; arr[2] = 17; arr[3] = 16; arr[4] = 15; return arr; }En el lado de C#:
namespace ConsoleC2CSExample { class Program { [DllImport("array.dll", EntryPoint = "ReturnArray", CallingConvention = CallingConvention.Cdecl)] public unsafe static extern short* ReturnArray(int size); static unsafe void Main(string[] args) { int arraySize = 5; short *ptr = ReturnArray(arraySize); for(int i = 0; i < arraySize; i++) Console.WriteLine(*(ptr + i * sizeof(short))); Console.Read(); } } }Y la salida es la esperada de la siguiente manera:
Tengo dos preguntas aquí.
C#/.NET se denomina código administrado porque se ejecuta de forma segura en Common Language Runtime (CLR). Mientras que el código C es el llamado código no administrado.
El CLR asegura que no sufrimos los problemas típicos conocidos del código C (como el desbordamiento del búfer, el desbordamiento del búfer, ...) que dan como resultado un código vulnerable, fallas en las aplicaciones, comportamiento desconocido, etc.
Por lo tanto, el peligro de usar código no seguro es que los errores en su biblioteca C probablemente terminarán inesperadamente con toda su aplicación C#/.NET, causándole muchos dolores de cabeza.
Para deshacerse al menos del contexto inseguro dentro de su código C#, puede probar lo siguiente:
using System.Runtime.InteropServices; namespace ConsoleC2CSExample { class Program { [DllImport("array.dll", EntryPoint = "ReturnArray", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr ReturnArray(int size); static void Main(string[] args) { int arraySize = 5; IntPtr ptr = ReturnArray(arraySize); for(int i = 0; i < arraySize; i++) Console.WriteLine(Marshal.ReadInt32(ptr + i * sizeof(int))); Console.Read(); } } }