Is the Marshal of a pointer done automatically?

Answered Is the Marshal of a pointer done automatically?

  • Friday, July 06, 2012 4:27 PM
     
      Has Code

    Hi All,

    I am new on C#,  I am tryng to use it to interface with a camera using the provided DLL, What I don't understand is the following:

    I have a function that I would like to use to obtain the data dimensions: ( The declaration comes out from the documentation )

    BOOL dcam_getdatasize( HDCAM h, SIZE* pSize);


    I inserted it in my C# program as:

       

      [DllImport("dcamapi.dll", EntryPoint = "dcam_getdatasize")]       

          public static extern bool dcam_getdatasize(IntPtr CAMERA, out IntPtr pSize);

    Then I call it as:

    IntPtr CAMERA = IntPtr.Zero; 

     IntPtr dimensione = IntPtr.Zero;

    sego = dcam_getdatasize(CAMERA, out dimensione);

    What I expect is to have as output an array with the dimensions of the image ( 320 x 246 )

    If I do :

    Console.WriteLine("Dimensioni  {0}", dimensione);

    I obtain the first term of the vector I am expecting ( 320 ) , but I need the entire vector

    I tryed to Marshal the pointer as:

        int[] vettore_dimensione = new int[2];       

      Marshal.Copy(dimensione, vettore_dimensione, 0, 2);

    But I receive an AccessViolationException 

    I arrived at this point reading around this forum but now I am stopped and Ask for suggestions,  What I don't understand why the dimensione that is a pointer has the right value ( only the first however) There have been done already a marshal from the pointer to a value at the  moment of calling the function?

    Thank you so much

    Giampiero


All Replies

  • Friday, July 06, 2012 5:00 PM
     
      Has Code

    Try something more like:


    [StructLayout(LayoutKind.Sequential)] public struct SIZE { public int cx; public int cy; public SIZE(int cx, int cy) { this.cx = cx; this.cy = cy; } }

    [DllImport("dcamapi.dll", EntryPoint = "dcam_getdatasize")]       

          public static extern bool dcam_getdatasize(IntPtr CAMERA, out IntPtr pSize);

    // to call it do something like

    IntPtr CAMERA = IntPtr.Zero; SIZE dimensione = new SIZE(0,0);sego = dcam_getdatasize(CAMERA, out dimensione);

    Note that you have to be sure that passing 0 for an HDCAM is correct.  It is very possible that you have to call some sort of open function to get a valid HDCAM value.
  • Friday, July 06, 2012 5:15 PM
     
      Has Code

    The problem is probably in the under-layer...it is hard to tell, but how are you allocating/deallocating the array that you are putting into pSize? How is that memory persisting after it is passed out? It is usually pretty werid to set a pointer to a persistent array...

    It would seem to me that the function call is filling in the size structure as SimonRev is showing, rather than passing out a pointer. This can be shown by

    Console.WriteLine("Dimensioni  {0}", dimensione);

    Shows the value of "cx". If it was as you are using it, it would show a pointer (some large hex value).


    SimonRev is pretty close: if you change your footprint to:

    [DllImport("dcamapi.dll", EntryPoint = "dcam_getdatasize")]       

          public static extern bool dcam_getdatasize(IntPtr CAMERA, ref SIZE s);

    It will automatically pin and send the pointer of s, so you call it like

    IntPtr CAMERA = IntPtr.Zero; SIZE dimensione = new SIZE(0,0);sego = dcam_getdatasize(CAMERA, ref dimensione);

  • Friday, July 06, 2012 5:15 PM
     
      Has Code

    Thank you so much for your suggestion, even if I don't understand why you suggested to use a structure: I have so much things to learn!! 

    But when I call 

    sego = dcam_getdatasize(CAMERA, out dimensione);

    I have an error because ( I think ) I declare a pointer in the DLLimport and I am using a structure in the function  call,

    This is more or less the message error: 

    Errore 1  method  'ConsoleApplication1.Program.dcam_getdatasize(System.IntPtr, out System.IntPtr)' has invalid arguments 

    About the HDCAM passing, I initialize the camera, the camera seems to be open at that moment :)
  • Friday, July 06, 2012 5:44 PM
     
     
    What is SIZE? Is it a structure? Basic Type? Is dimensione supposed to be an array?
  • Friday, July 06, 2012 5:51 PM
     
      Has Code

    The problem is probably in the under-layer...it is hard to tell, but how are you allocating/deallocating the array that you are putting into pSize? How is that memory persisting after it is passed out? It is usually pretty werid to set a pointer to a persistent array...

    It would seem to me that the function call is filling in the size structure as SimonRev is showing, rather than passing out a pointer. This can be shown by

    Console.WriteLine("Dimensioni  {0}", dimensione);

    Shows the value of "cx". If it was as you are using it, it would show a pointer (some large hex value).


    SimonRev is pretty close: if you change your footprint to:

    [DllImport("dcamapi.dll", EntryPoint = "dcam_getdatasize")]       

          public static extern bool dcam_getdatasize(IntPtr CAMERA, ref SIZE s);

    It will automatically pin and send the pointer of s, so you call it like

    IntPtr CAMERA = IntPtr.Zero; SIZE dimensione = new SIZE(0,0);sego = dcam_getdatasize(CAMERA, ref dimensione);

     Thank you so much, it works fine,  

    I tried with both "ref" and "out"  and  the result is the same ( the correct one )

    [DllImport("dcamapi.dll", EntryPoint = "dcam_getdatasize")]       

          public static extern bool dcam_getdatasize(IntPtr CAMERA, ref SIZE s);

    public static extern bool dcam_getdatasize(IntPtr CAMERA, OUT SIZE s); <------------ OUT

    IntPtr CAMERA = IntPtr.Zero; SIZE dimensione = new SIZE(0,0);sego = dcam_getdatasize(CAMERA, ref dimensione);

    sego = dcam_getdatasize(CAMERA, OUT dimensione); <---- OUT

     I tried also using an array  instead of the Structure but it doesn't work, either with the ref, out, inizializing it or not, why an array is not usable?

    I am worried about the continue , in the end I will extract an image that should be something like an array!

    Thank you so much :)

     


  • Friday, July 06, 2012 6:50 PM
     
     Answered

    Because in .NET an array is a structure which contains more than just data.  It also contains a length field.

    In C and C++, an "array" doesn't actually exist.  Arrays are just pointers to a location in memory which contains sequence of memory blocks that are all the same size, e.g., an array of integers of size 5 is just a pointer to a location in memory which contains 5 sequential blocks of 4 bytes each for a total memory size of 20 bytes.

  • Friday, July 06, 2012 10:11 PM
     
     

    Thank you so much,

    My background is composed almost of arrays :) 

    I will study the implications that this kind of approach gives.

    Ciao,

    p.s. How can I flag the question as answered?
  • Monday, July 09, 2012 6:45 AM
    Moderator
     
     

    Hi Giampiero.at.Home,

      You can click the button at the bottom of reply box which you feel it is useful and helpful for you.Thank all for your time and efforts in this thread.

      Sincerely,

      Jason Wang


    Jason Wang [MSFT]
    MSDN Community Support | Feedback to us