How to pass memory blocks (pointers) from C ++ to C #?

2

I have a small problem that I hope you can help me.

I have this code in c++ :

__declspec(dllexport)
unsigned char* ProcessFrame() {

    VideoCapture cam;
    cam.open(0);

    Mat imagen;
    unsigned char* result;
    cam >> imagen;
    flip(imagen, imagen, 0);
    result = new unsigned char[imagen.cols*imagen.rows*4];
    memcpy(result, imagen.data, imagen.cols*imagen.rows*4);
    return result;
}

I want to use it in Unity, with the following code:

        byte[] imgData = ProcessFrame();

        Debug.Log(imgData.Length);
        Texture2D tex = new Texture2D(320, 240, TextureFormat.RGB24, false);
        tex.LoadRawTextureData(imgData);
        tex.Apply();
        GetComponent<Renderer>().material.mainTexture = tex;

The problem is that he always answers me:

  

No texture data provided to LoadRawTextureData.

It seems that from C ++ you can not pass pointers as is to C #.

    
asked by Urko Sanchez Ortiz 28.08.2017 в 10:50
source

1 answer

2
  

It seems that from C ++ you can not pass pointers as is to C #.

That's not the case. Passing pointers in fact is very simple. The problem is to obtain the data pointed to by that pointer, since they are not delimited. For that, it is necessary to know its size. There are several options:

1.- If the size of the data to be passed is always fixed (in your case imagen.cols*imagen.rows*4 ) you can simply copy that data in the C # part

Example:

- Header (.h file)

extern "C" { __declspec(dllexport)unsigned char *ProcessFrame(); }

- C ++ code (.cpp file)

unsigned char* ProcessFrame() {

    VideoCapture cam;
    cam.open(0);

    Mat imagen;
    unsigned char* result;
    cam >> imagen;
    flip(imagen, imagen, 0);
    result = new unsigned char[imagen.cols*imagen.rows*4];
    memcpy(result, imagen.data, imagen.cols*imagen.rows*4);
    return result;
}

- C #

var imgPointer = ProcessFrame();
int tamaño=t; //t es el valor de imagen.cols*imagen.rows*4
byte[] imgData=new byte[tamaño];     
Marshal.Copy(imgPointer , imagen, 0, tamaño);

2.- In case the size of the data is not fixed, a possible solution is to store this value in a static variable and create a C ++ method that returns this value. The rest of the code would be the same as the one I put in the previous point.

It is good to mention that the code in c ++ has a memory leak, since you assign memory to result and do not release it at any time. The problem is that you can not do it before the image is obtained on the C # side, because if it would not be available. A possible solution would be to create another method in C ++ that releases that memory, and call it from C # once the data is obtained.

    
answered by 29.08.2017 в 10:55