SOS: verilog array data got padded when calling into C!

this is the URL of the my code at EDA playground

In case you don’t have access, below code demonstrate the problem and output
// Example of using SystemVerilog DPI-C with C++ code.
//
// In EDA Playground, when using ModelSim,
// any *.cc file will be compiled as C++ and linked into the simulation.


module automatic test;
 
  import "DPI-C" function int tb_sm_io(inout logic[31:0] data_buf[],input int device_addr,input int size,input int direction);
  initial run();
 
  task run();
    
    logic a = 1'bx;
    logic [31:0] pay_load_data[];
    int result;
    pay_load_data = new[3];
    pay_load_data[0]=32'h12345678;
    pay_load_data[1]=32'h87654321;
    pay_load_data[2]=32'hDEADBEEF;
    $display("Before 1st call to tb_sm_io \n\tSV: pay_load_data[0]=%x",pay_load_data[0]);
    $display("\tSV: pay_load_data[1]=%x",pay_load_data[1]);
    $display("\tSV: pay_load_data[2]=%x",pay_load_data[2]);

    result=tb_sm_io(pay_load_data,pay_load_data[0],pay_load_data[1],pay_load_data[2]);
    $display("After return from 1st call to tb_sm_io\n\tSV: pay_load_data[0]=%x",pay_load_data[0]);
    $display("\tSV: pay_load_data[1]=%x",pay_load_data[1]);
    $display("\tSV: pay_load_data[2]=%x",pay_load_data[2]);

  endtask
 
endmodule

//C
// This file is compiled as C++ and linked with stdlib
// into the simulation executable.

#include <iostream>
#include <svdpi.h>
#include <stdio.h>
#include <assert.h>
using namespace std;
#define cdump(x) printf("\tC: %s=%x\n",#x,x)
extern "C" int tb_sm_io(svOpenArrayHandle data_buf_ref,int device_addr,int size,int direction) 
{
  unsigned int *pay_load_data=(unsigned int *)svGetArrayPtr(data_buf_ref);
  printf("Data Dump in C/%s pay_load_data=%p\n",__FUNCTION__,pay_load_data);
  cdump(pay_load_data[0]);
  //expect 0x87654321 == pay_load_data[1]
  cdump(pay_load_data[1]);
  assert(0x87654321 == pay_load_data[1]);
  cdump(pay_load_data[2]);
  pay_load_data[0]=pay_load_data[2];
  pay_load_data[1]=0x01234567;
  pay_load_data[2]=0x84219751;
  cdump(device_addr);
  cdump(size);
  cdump(direction);
  return 0;
}

//Result:
Before 1st call to tb_sm_io
SV: pay_load_data[0]=12345678
SV: pay_load_data[1]=87654321
SV: pay_load_data[2]=deadbeef
Data Dump in C/tb_sm_io pay_load_data=0xefd6efe0
C: pay_load_data[0]=12345678
C: pay_load_data[1]=0
simv: …/my_dpi.cc:17: int tb_sm_io(svOpenArrayHandle, int, int, int): Assertion `0x87654321 == pay_load_data[1]’ failed.

An unexpected termination has occurred in ./simv due to a signal: Aborted

In reply to MichaelSong:

You can’t dereference a svOpenArrayHandle as an array. You need to use ‘svGetArrayElemPtr()’ to get the data pointers for each array element. Refer to section H.12.4 of the LRM.

int tb_sm_io(const svOpenArrayHandle data_buf_ref,int device_addr,int size,int direction) 
{
  unsigned int *pay_load_data[3];
  pay_load_data[0] = (unsigned int *)svGetArrElemPtr(data_buf_ref, 0);
  pay_load_data[1] = (unsigned int *)svGetArrElemPtr(data_buf_ref, 1);
  pay_load_data[2] = (unsigned int *)svGetArrElemPtr(data_buf_ref, 2);

  cdump(*pay_load_data[0]);
  cdump(*pay_load_data[1]);
  cdump(*pay_load_data[2]);

  return 0;
}