How to pass a pointer-to-pointer parameter from VB.NET to a C++ DLL function

Posted on 2009-04-19
Last Modified: 2013-12-14
I am trying to call a C++ DLL function from VB.NET. My problem is the C++ function has a pointer-to-pointer parameter and I do not know how to declare the function in VB.NET and how to make the call. Any assistance will be appreciated.

C++ Declarations:

typedef sx_int32 sdvr_chan_handle_t;

typedef struct _sdvr_yuv_buffer_t {
    sx_uint32           signature;
    sx_uint8            hdr_version;        
    sx_uint8            reserved1;
    sx_uint16           hdr_size;          
    sx_uint8            board_id;
    sdvr_chan_type_e    channel_type;
    sx_uint8            channel_id;
    sdvr_frame_type_e   frame_type;
    sx_uint8            motion_detected;
    sx_uint8            blind_detected;
    sx_uint8            night_detected;
    sx_uint8            reserved2;
    sx_uint8            motion_value[4];
    sx_uint8            blind_value[4];
    sx_uint8            night_value[4];
    sx_uint32           timestamp;
    sx_uint64           timestamp_64;
    sx_uint16           active_width;
    sx_uint16           active_height;
    sx_uint32           seq_number;
    sx_uint32           frame_number;
    sx_uint32           frame_drop_count;
    sx_uint32           reserved[44];
    sx_uint32           y_data_size;
    sx_uint32           u_data_size;
    sx_uint32           v_data_size;
    sx_uint8            *y_data;
    sx_uint8            *u_data;
    sx_uint8            *v_data;
} sdvr_yuv_buffer_t;

EXTERN sdvr_err_e sdvr_get_yuv_buffer(sdvr_chan_handle_t handle, sdvr_yuv_buffer_t **frame_buffer);

Here's my declaration in VB.NET:

Public Structure sdvr_yuv_buffer_t
    Public signature As UInt32          '// Must be set to SDVR_DATA_HDR_SIG
    Public hdr_version As Byte
    Public reserved1 As Byte
    Public hdr_size As UInt16
    Public board_id As Byte
    Public channel_type As Byte
    Public channel_id As Byte
    Public frame_type As Byte
    Public motion_detected As Byte
    Public blind_detected As Byte
    Public night_detected As Byte
    Public reserved2 As Byte
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> Public motion_value() As Byte
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> Public blind_value() As Byte
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> Public night_value() As Byte
    Public timestamp As UInt32
    Public timestamp_64 As UInt64
    Public active_width As UInt16
    Public active_height As UInt16
    Public seq_number As UInt32
    Public frame_number As UInt32
    Public frame_drop_count As UInt32
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=44)> Public reserved() As UInt32
    Public y_data_size As UInt32
    Public u_data_size As UInt32
    Public v_data_size As UInt32
    Public y_data() As Byte
    Public u_data() As Byte
    Public v_data() As Byte
End Structure

Declare Auto Function sdvr_get_yuv_buffer Lib "sdvr_sdk_dll" (ByVal handle As Int32, ByRef frame_buffer As IntPtr) As sdvr_err_e

I tried the following code to pass an IntPtr into the ByRef parameter to effect passing a pointer-to-pointer parameter but I got the error "Object contains non-primitive or non-blittable data":

Dim yuvStruct As sdvr_yuv_buffer_t
Dim pinStructure As GCHandle = GCHandle.Alloc(yuvStruct, GCHandleType.Pinned);  <-- error occurs here
Dim Ptr As IntPtr = pinStructure.Target
sdvr_get_yuv_buffer(handle, Ptr)

Where did I go wrong? Can you please suggest a way to do this?

Question by:AndyC72
    1 Comment
    LVL 39

    Accepted Solution

    >>>> My problem is the C++ function has a pointer-to-pointer parameter and I do not know how to declare the function in VB.NET

    pointer-to-pointer is a special C interface (actually the pointers were pointing to arrays and not to single elements) which is not suitable for being called from other languages. You better would change the interface so that the argument

        sdvr_yuv_buffer_t **frame_buffer

    turns to a simple byte array of either fixed length or where the length (size) was passed as an additional argument.

    If you can't change the interface or have no code for the dll function you may consider building a C/C++ wrapper dll which does the job from 'translating' the dynamic arguments to fixed sized byte-arrays or strings.


    Featured Post

    IT, Stop Being Called Into Every Meeting

    Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

    Join & Write a Comment

    Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
    Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
    The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
    The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

    754 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    19 Experts available now in Live!

    Get 1:1 Help Now