Click here to Skip to main content
15,886,258 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
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:

C++
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:

C#
[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")

C#
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):

C#
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:

C#
[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 11:53am
v2

1 solution

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:

C#
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;
}
 
Share this answer
 
Comments
Member 15998787 14-May-23 8:39am    
Hi,
How do you retrieve LPARAM and WPARAM, i have a panini vision x scanner and i need to build a c# app (wpf app) to use it?
Thanks

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900