es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo obtener un arreglo de C++/C en C# utilizando una DLL.

Soy un traductor de español que traduce documentos de IT. Traduzca lo siguiente al español. No traduzca el código y la salida en markdown.

Soy muy nuevo en C# y C/C++. Escribí un código en C que almacenaba 2 variables en un array y devolvía el array. Usando el método P/invoke, creé una biblioteca DLL de esta función en C y la importé a C#. Al llamar al array, no puedo obtener el array desde C#.
Necesito su amable ayuda. Aquí está el código en C:

#include <stdio.h>

extern __declspec(dllexport) int* sum();
int* sum()
{
    int a = 50, b = 80, sum, neg;
    sum = a + b;
    neg = b - a;
    int arr[2] = { sum, neg };
    return arr;
}

Ahora el código en C# es…

using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication
{
    class Program
    {
        [DllImport("Project2.dll")]
        unsafe public static extern int* sum();
        static void Main(string[] args)
        {
            unsafe
            {
                int* array2 = sum();

                Console.WriteLine("Valor: " + array2[0]);
            }

        }
    }
}

Por favor, avíseme cómo puedo obtener el array.</stdio.h>

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El problema con el código es que la función C está devolviendo un puntero a una variable local (un array). Cuando la función termina, la memoria asignada a la variable local se libera y el puntero se vuelve inválido.

    Para solucionar este problema, debes asignar memoria dinámicamente utilizando la función malloc y devolver el puntero a la memoria asignada dinámicamente. Aquí está el código C modificado:

    #include <stdio.h>
    #include <stdlib.h>
    
    extern __declspec(dllexport) int* sum();
    int* sum()
    {
        int a = 50, b = 80, sum, neg;
        sum = a + b;
        neg = b - a;
        int* arr = (int*)malloc(2 * sizeof(int)); // asignar memoria dinámicamente
        arr[0] = sum;
        arr[1] = neg;
        return arr;
    }
    

    En el código C#, debes declarar el tipo de retorno de la función sum como IntPtr en lugar de int*. Luego, puedes utilizar el método Marshal.Copy para copiar la memoria apuntada por el puntero devuelto a un array administrado. Aquí está el código C# modificado:

    using System;
    using System.Runtime.InteropServices;
    
    namespace ConsoleApplication
    {
        class Program
        {
            [DllImport("Project2.dll")]
            public static extern IntPtr sum(); // el tipo de retorno cambió a IntPtr
            static void Main(string[] args)
            {
                IntPtr arrayPtr = sum();
                int[] array = new int[2];
                Marshal.Copy(arrayPtr, array, 0, 2); // copiar memoria al array administrado
                Console.WriteLine("Valores: " + array[0] + ", " + array[1]);
                Marshal.FreeHGlobal(arrayPtr); // liberar la memoria asignada por la función C
            }
        }
    }
    

    Ten en cuenta que debes llamar a Marshal.FreeHGlobal para liberar la memoria asignada por la función C cuando hayas terminado con ella.</stdlib.h></stdio.h>

Comments are closed.