By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,418 Members | 1,430 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,418 IT Pros & Developers. It's quick & easy.

[C#] PtrToStructure problem

P: n/a
Hi

First of all please let me know if there is some other, more suitable
group for this news - TIA :-)
Now, my problem. I'm writing an C# application in which I'm using some
functions from DLL. This dll has been written in C.

One of these functions returns as a result a structure, in example:

[StructLayout(LayoutKind.Sequential, Pack=2)]
internal class myStruct
{
public short someNumber;
public IntPtr handle;
}
OK. Now in this handle there is a pointer to a structure with actuall
results.

[StructLayout(LayoutKind.Sequential, Pack=2)]
internal class myStruct2
{
public uint count; //number of values return from function
public uint current; //current value
[MarshalAs(UnmanagedType.ByValArray, SizeConst=1)]
public short[] items; //array of results
}

OK. Hope you're still with me :D

Now, as you can see there is another array in myStruct2. This array
contains result which I want to get :D

In this function description I have something like this:
<description>
The items value is simply a placeholder for the start of the actual
array, which must be allocated when the container is allocated.
</description>
In my application I have something like this:

<code>
[DllImport("some.dll", EntryPoint="#1")]
private static extern short getValues([In, Out] myStruct cap);

myStruct ms = new myStruct();
getValues(ms);

myStruct2 ms2 = new myStruct2();
ms2 = (myStruct2)Marshal.PtrToStructure(ms.handle, typeof(myStruct2));
</code>

In return I get some really strange values in ms2.count and ms2.current.
Not mentioning that I can't get the values from the items :-(

What am I doing wrong? Meybe there is something missing?

best regards
Mateusz [PEYN] Adamus
Nov 16 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
Hi,

You can try something like this (at least to see if the data in the array
makes more sense):

myStruct s1 = new myStruct();
getValues(s1);
int length = Marshal.ReadInt32(s1.handle);
short[] values = new short[length];
Marshal.Copy((IntPtr)(s1.handle.ToInt32() + 2 * sizeof(int)), values, 0,
length);

Don't forget to free the memory that s1.handle is pointing to.

Hope this helps,
Martin Dechev
ASP.NET MVP
"Mateusz [PEYN] Adamus" <pe************@tlen.pl> wrote in message
news:d0**********@atlantis.news.tpi.pl...
Hi

First of all please let me know if there is some other, more suitable
group for this news - TIA :-)
Now, my problem. I'm writing an C# application in which I'm using some
functions from DLL. This dll has been written in C.

One of these functions returns as a result a structure, in example:

[StructLayout(LayoutKind.Sequential, Pack=2)]
internal class myStruct
{
public short someNumber;
public IntPtr handle;
}
OK. Now in this handle there is a pointer to a structure with actuall
results.

[StructLayout(LayoutKind.Sequential, Pack=2)]
internal class myStruct2
{
public uint count; //number of values return from function
public uint current; //current value
[MarshalAs(UnmanagedType.ByValArray, SizeConst=1)]
public short[] items; //array of results
}

OK. Hope you're still with me :D

Now, as you can see there is another array in myStruct2. This array
contains result which I want to get :D

In this function description I have something like this:
<description>
The items value is simply a placeholder for the start of the actual
array, which must be allocated when the container is allocated.
</description>
In my application I have something like this:

<code>
[DllImport("some.dll", EntryPoint="#1")]
private static extern short getValues([In, Out] myStruct cap);

myStruct ms = new myStruct();
getValues(ms);

myStruct2 ms2 = new myStruct2();
ms2 = (myStruct2)Marshal.PtrToStructure(ms.handle, typeof(myStruct2));
</code>

In return I get some really strange values in ms2.count and ms2.current.
Not mentioning that I can't get the values from the items :-(

What am I doing wrong? Meybe there is something missing?

best regards
Mateusz [PEYN] Adamus


Nov 16 '05 #2

P: n/a
Martin Dechev napisał(a):
Hi,
[cut]
Don't forget to free the memory that s1.handle is pointing to.

Hi

Thank for the reply.

I don't know why but I can't make it work. Meybe I just simplified it
too much. So I'll give you full example with real data - meybe than
you'll figure out what is wrong.

OK. I'm doing a Twain library in C#. I want to get what type of units is
set on the scanner. In C I have these structures:

<c>
typedef struct {
TW_UINT16 Cap; /* ID of capability to get or set */
TW_UINT16 ConType; /* TWON_ONEVALUE, TWON_RANGE, */
/* TWON_ENUMERATION or TWON_ARRAY */
TW_HANDLE hContainer; /* Handle to container of type */
/* ConType */
} TW_CAPABILITY, FAR *pTW_CAPABILITY;
</c>

I've translated into:
<c#>
public short Cap;
public short ConType;
public IntPtr Handle;
</c#>
Handle can be of many types, one of them is TW_ENYMERATION

<c>
typedef struct {
TW_UINT16 ItemType;
TW_UINT32 NumItems;
TW_UINT32 CurrentIndex;
TW_UINT32 DefaultIndex;
TW_UINT8 ItemList[1];
} TW_ENUMERATION, FAR * pTW_ENUMERATION;

ItemList[1] = The enumerated list: one value resides within each array
element. Space for the list is not allocated inside this structure. The
ItemList value is simply a placeholder for the start of the actual
array, which must be allocated when the container is allocated. Remember
to typecast the allocation to ItemType, as well as references to the
elements of the array.
</c>

<c#>
public ushort ItemType;
public uint NumItems;
public uint CurrentIndex;
public uint DefaultIndex;
public short[] ItemList;
</c#>

OK. That's it. I also have an example in the Twain's documentation on
how to get values from the scanner but I just can't figure out way on
how to translateg to the C#. Its probably very easy but I'm noobie in C#
so its darn hard for me :-(

example:
<c>
pTW_ENUMERATION pvalEnum;
TW_UINT16 valueU16;
TW_UINT16 index;
pvalEnum = (pTW_ENUMERATION)GlobalLock(twCapability.hContaine r);
NumItems = pvalEnum->NumItems;
CurrentIndex = pvalEnum->CurrentIndex;
DefaultIndex = pvalEnum->DefaultIndex;
for (index = 0; index < pvalEnum->NumItems; index++)
{
if (pvalEnum->ItemType == TWTY_UINT16)
{
valueU16 = ((TW_UINT16)(pvalEnum->ItemList[index*2]));
//Store Item Value
}
}
GlobalUnlock(twCapability.hContainer);
</c>
TIA for all replies

best regards
Mateusz [PEYN] Adamus
Nov 16 '05 #3

P: n/a
Mateusz [PEYN] Adamus napisał(a):
Hi

Thank for the reply.

I don't know why but I can't make it work. Meybe I just simplified it
too much. So I'll give you full example with real data - meybe than
you'll figure out what is wrong.

OK. I'm doing a Twain library in C#. I want to get what type of units is
set on the scanner. In C I have these structures:
[cut]
TIA for all replies

best regards
Mateusz [PEYN] Adamus


Heh. It seems that it wasn't so hard after all. I don't know what was
happening with me on Firday - probably the weekend thing :D

Anyways I just figured out way to get all data. :-)
best regards
Mateusz [PEYN] Adamus
Nov 16 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.