Click here to Skip to main content
14,429,439 members
Rate this:
Please Sign up or sign in to vote.
See more:
Greetings!

As tittle says, I need to marshal an struct within a pointer to another struct (actually,. a vector to another struct). That one is got after certain message (related question here), with it address as LParam.

It definition is in a .dll file made by a thirdparty (dont have source code), made in C++. Here's an example:

typedef struct _cImage
{
  BYTE *Buffer;
  int Lenght;
} cImage;

typedef struct _Images
{
  DWORD DocID;
  cImage *Imgs;
  BOOL Enabled;
} Images;


According to manual...
Quote:
It's the pointer to a vector of cImage structure: 5 elements for images and 10 for snippets.


What I have tried:

First I tried to define the struct within an inner array:

[StructLayout(LayoutKind.Sequential, Pack = 0)]
public struct cImage
{
    public IntPtr Buffer;
    public int Lenght;
};

[StructLayout(LayoutKind.Sequential, Pack = 0)]
public struct Images
{
    public int DocID;
    [MarshalAs(UnmanagedType.ByValArray)]
    public cImage[] Imgs;
    [MarshalAs(UnmanagedType.Bool)]
    public bool Enabled;
};


Here is how I try to extract the information (it's in a class "ScanMgr")

public bool getImage(IntPtr imgPtr, out Images img)
{
    try
    {
        img = (Images)Marshal.PtrToStructure(imgPtr, typeof(Images));
        return true;
    }
    catch { img = new Images(); }
    return false;
}


And here is where I call the function (scanner is an object of ScanMgr):

switch ((int)msg.WParam)
{
    /* Other cases */
    case (int)WMPAR.ImagesReady:
    Images img;
    if (scanner.getImage(m.LParam, out img))
        /* Here I should get access and use the struct members */
    break;
}


I then tried replacing the array with an IntPtr to the inner struct, to marshal it later:

[StructLayout(LayoutKind.Sequential, Pack = 0)]
public struct Images
{
    public int DocID;
    public IntPtr Imgs;
    [MarshalAs(UnmanagedType.Bool)]
    public bool Enabled;
};

////////////

switch ((int)msg.WParam)
{
    /* Other cases */
    case (int)WMPAR.ImagesReady:
    Images img;
    if (scanner.getImage(m.LParam, out img))
    {
        cImage cImg = (cImage)Marshal.PtrToStructure(img.Imgs, typeof(cImage));
        /* Access/Use the struct members */
    }
    break;
}


My question is: What is the right way to marshal that inner vector of structs? If is the IntPtr, then how can I extract those members? (since just gonna work with images, I'll stick with a vector of 5)

Thanks in advance
Posted
Updated 10-Apr-19 12:53pm
v2

1 solution

Rate this:
Please Sign up or sign in to vote.

Solution 1

Solving stuff by myself (yup, I'm a library mice!)


I defined the pointer to vector as an IntPtr (see 2nd C# struct implementation in previous post). Then:

switch ((int)msg.WParam)
{
    /* Other cases */
    case (int)WMPAR.ImagesReady:
    Images img;
    if (scanner.getImage(m.LParam, out img))
    {
        var size = Marshal.SizeOf(typeof(cImage));
        cImage[] ar = new cImage[5];

        for (int i = 0; i < 5; i++)
        {
            IntPtr p = new IntPtr(img.Imgs.ToInt32() + i * size);
            ar[i] = (cImage)Marshal.PtrToStructure(p, typeof(cImage));
            logInfo.Items.Add(ar[i].Buffer + "-" + ar[i].Lenght);
        }
    }
    break;
}
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100