• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 762
  • Last Modified:

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

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?

1 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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now