简体   繁体   中英

How to get a struct array to an IntPtr?

C++ function prototype is;

/************************************************************************
parameters[in]: 
    void *handle,
    char *jpeg_buf,
    jpeg_buf jpeg_buf
parameters[out]:
    listSize:   result list size, max <= 1000;
    list:       result
************************************************************************/

int getInfo(void *handle,unsigned char* jpeg_buf, unsigned int jpeg_len, int& list_size, Info *info_list);

C++ types;

typedef struct
{
    int dot_x;
    int dot_y;
} Attr;


typedef struct
{
    int left;
    int top;
    int right;
    int bottom;
} Rect_S;


typedef struct
{
    Rect_S rect;
    Attr attr;
} Info;

C# DLL import;

[DllImport("sample.dll", CallingConvention = CallingConvention.Cdecl)]
    internal static extern int getInfo(IntPtr handle, byte[] jpeg_buf, uint jpeg_len, out int listSize, out IntPtr List);

Structures are in C#;

internal struct Attr
    {
        public int dot_x;
        public int dot_y;
    };

    internal struct Rect_S
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    };

    internal struct Info
    {
        public Rect_S rect;
        public Attr attr;
    };

C# GetInfo Function;

public Info[] getInfo(byte[] scan0)
    {
        Info[] retVal = null;
        IntPtr structPtr = IntPtr.Zero;
        int size;

        int ret = EFEngine.getInfo(this.Engine, scan0, (uint)scan0.Length, out size, out structPtr);

        if (ret >= 0)
        {
            retVal = new Info[size];
            int sizePointerInfo = Marshal.SizeOf(new EFaceInfo());
            for (int i = 0; i < size; i++)
            {
                retVal[i] = (Info)Marshal.PtrToStructure(new IntPtr(structPtr.ToInt64() + (i * sizePointerInfo)), typeof(Info));
            }
        }

        return retVal;
    }

I get an error as "Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt." when call the "Marshal.PtrToStructure".

What is it in wrong?

C++ test code;

int getInfoTest(void *handle, unsigned char* jpeg_buf, unsigned int jpeg_len, int& list_size, FaceInfo *face_rect_list)
{
    int nSizeNum = 0;
    Info* List = new Info[32];
    int nRet = getInfo(handle, jpeg_buf, jpeg_len, nSizeNum, List);
    if (nRet != 0)
    {
        fprintf(stderr, "error: getInfo failed\n");
    }
    delete[] List;
    delete[] jpeg_buf;

    return nRet;
}

As happened at your previous question, the information provided in the question is incomplete. As I tried to explain to you there, a C++ prototype does not fully specify the semantics of a C++ function. As I explained to you before, you should include those semantics, or at least some example C++ code to call the function.

However, it seems very likely that the problem is the final parameter. The caller is expected to allocate the memory and pass its address to the function. It looks very much like this final parameter is in fact an array. Working on that assumption, the p/invoke declaration should be:

[DllImport("sample.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern int getInfo(IntPtr handle, byte[] jpeg_buf, 
    uint jpeg_len, ref int listSize, [Out] Info[] List);

You would call the function like this:

int listSize = ...; // you have to somehow work out what to put here
Info[] List = new Info[listSize];
int retval = getInfo(handle, jpeg_buf, jpeg_len, ref listSize, List);
// check retval

Of course, since the list size parameter is passed by reference that would suggest that the function can tell you how large an array is needed. So perhaps the call sequence should be:

int listSize = 0;
int retval = getInfo(handle, jpeg_buf, jpeg_len, ref listSize, null);
// check retval
Info[] List = new Info[listSize];
int retval = getInfo(handle, jpeg_buf, jpeg_len, ref listSize, List);
// check retval

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM