Hi,
I'm trying to call a win32 function using pinvoke and C# .Net.
The function takes a struct reference as a parameter (lpInfo), but on return
the struct is not filled with data, and I'm suspecting that I have made a
mistake mapping up the struct.
DBSTAT DBenum ( XInt32 hDBase,
LPSTR lpszPath,
XDWORD nLevel,
DBENUMCB Callback,
DWORD UserData,
LPVOID lpInfo);
The C struct is like this (truncated):
typedef struct _seginfo {
CHAR Name [ strSHORT + 1 ];
CHAR Desc [ strLONG + 1 ];
DWORD Created;
WORD DClass;
WORD UType;
Int32 Top;
Int32 Bottom;
WORD wPoints;
FLOAT fHStart;
WORD uHUnit;
FLOAT fVScale;
WORD SmpSize; // for smpFILE = file size
// for smpREGULAR
WORD TixPerSmp;
// for smpRANGE
XDWORD *lpUpdateCount;
// any
Int32 lAliasOffset;
} SGMINFO;
strSHORT = 10;
strLONG = 256;
Can anyone help me with a correct C# mapping? 11 8092
Tor, Can anyone help me with a correct C# mapping?
I'm guessing it should look something like this
struct SGMINFO
{
[MmshalAs(UnmanagedType.ByValTStr, SizeConst=11)]
public string Name;
[MmshalAs(UnmanagedType.ByValTStr, SizeConst=257
public string Desc;
public uint Created;
public ushort DClass;
public ushort UType;
public int Top;
public int Bottom;
public ushort wPoints;
public float fHStart;
public ushort uHUnit;
public float fVScale;
public ushort SmpSize;
public ushort TixPerSmp;
public IntPtr lpUpdateCount;
public int lAliasOffset;
}
Mattias
--
Mattias Sjögren [C# MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Hi Mattias,
Thanks for your answer!
The struct is still not filled with data.
I see that a sizeof( SGMINFO) i C is 255 bytes, and Marshal.SizeOf(
typeof( SGMINFO )) in .Net is 344 bytes.
Maybe this is due to the fact that a char in ansi C is 1 byte wheras a char
in C# is 2 bytes?
Or do you think this is not the case?
Regards Tor
"Mattias Sjögren" <ma********************@mvps.org> wrote in message
news:uE**************@TK2MSFTNGP09.phx.gbl... Tor,
Can anyone help me with a correct C# mapping?
I'm guessing it should look something like this
struct SGMINFO { [MmshalAs(UnmanagedType.ByValTStr, SizeConst=11)] public string Name; [MmshalAs(UnmanagedType.ByValTStr, SizeConst=257 public string Desc; public uint Created; public ushort DClass; public ushort UType; public int Top; public int Bottom; public ushort wPoints; public float fHStart; public ushort uHUnit; public float fVScale; public ushort SmpSize; public ushort TixPerSmp; public IntPtr lpUpdateCount; public int lAliasOffset; }
Mattias
-- Mattias Sjögren [C# MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com Please reply only to the newsgroup.
"Mattias Sjögren" <ma********************@mvps.org> wrote in message
news:uE**************@TK2MSFTNGP09.phx.gbl... Tor,
Can anyone help me with a correct C# mapping?
I'm guessing it should look something like this
struct SGMINFO { [MmshalAs(UnmanagedType.ByValTStr, SizeConst=11)] public string Name; [MmshalAs(UnmanagedType.ByValTStr, SizeConst=257 public string Desc; public uint Created; public ushort DClass; public ushort UType; public int Top; public int Bottom; public ushort wPoints; public float fHStart; public ushort uHUnit; public float fVScale; public ushort SmpSize; public ushort TixPerSmp; public IntPtr lpUpdateCount; public int lAliasOffset; }
I think it needs a StructLayoutAttribute:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
>I think it needs a StructLayoutAttribute: [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
That's the default for C# structs so it's optional. You don't have to
add it but it doesn't change anything if you do.
Mattias
--
Mattias Sjögren [C# MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
>The struct is still not filled with data.
How are you using it? I see that a sizeof( SGMINFO) i C is 255 bytes,
I find that hard to believe since the Desc field alone is 257 bytes.
and Marshal.SizeOf(typeof( SGMINFO )) in .Net is 344 bytes.
I get 312 or 308 depending on the packing.
Maybe this is due to the fact that a char in ansi C is 1 byte wheras a char in C# is 2 bytes?
The size of a char to the marshaler is whatever you set with the
StructLayout attribute. If you keep the default (CharSet.Ansi) it's
one byte per character.
Mattias
--
Mattias Sjögren [C# MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
"Mattias Sjögren" <ma********************@mvps.org> wrote in message
news:Oj**************@tk2msftngp13.phx.gbl... The struct is still not filled with data. How are you using it?
public delegate bool EnumCallbackCB( string EnumName, uint UserData );
[ DllImport( "WDBase.dll", CharSet=CharSet.Auto, EntryPoint="DBenumA",
SetLastError=true, ExactSpelling=true )]
public static extern WarriorCommon.DBStat DBEnum( UInt32 DBHandler, string
Path, Int32 Level, EnumCallbackCB Callback, Int32 SizeOfUserData, ref
SGMINFO sgm );
I see that a sizeof( SGMINFO) i C is 255 bytes, I find that hard to believe since the Desc field alone is 257 bytes.
Dont understand it, I checked again and sizeof(SGMINFO) is only 244 in C,
and Marshal.SizeOf(typeof( SGMINFO )) in .Net is 344 bytes. I get 312 or 308 depending on the packing.
Sorry I did't mention that the struct was truncated. The complete listing
goes like this
[ StructLayout( LayoutKind.Sequential )]
public struct SGMINFO{
[[MarshalAs(UnmanagedType.ByValTStr, SizeConst=11)]
public string Name;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=257)]
public string Desc;
public uint Created;//DWORD
public uint Modified;//DWORD
public uint Code;//DWORD
public ushort bIsAliased;//WORD
public ushort SType;//WORD
public ushort DType;//WORD
public ushort DClass;//WORD
public ushort UType;//WORD
public int Top;//Int32
public int Bottom;//Int32
public ushort wPoints;//WORD
public float fHStart;//FLOAT
public float fHStep;//FLOAT
public ushort uHUnit;//WORD
public float fVScale;//FLOAT
public float fVMin;//FLOAT
public float fVMax;//FLOAT/
public ushort SmpSize;
public ushort TixPerSmp;//WORD
public ushort SmpPerBlk;//WORD
public ushort IxPerBlk;//WORD
public IntPtr lpUpdateCount;//XDWORD
public int lAliasOffset;//Int32}
Maybe this is due to the fact that a char in ansi C is 1 byte wheras a char in C# is 2 bytes?
The size of a char to the marshaler is whatever you set with the StructLayout attribute. If you keep the default (CharSet.Ansi) it's one byte per character.
Mattias
-- Mattias Sjögren [C# MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com Please reply only to the newsgroup.
Sorry for the changed user name, but I'm at home.
"Mattias Sjögren" <ma********************@mvps.org> wrote in message
news:Oj**************@tk2msftngp13.phx.gbl... The struct is still not filled with data.
How are you using it?
I see that a sizeof( SGMINFO) i C is 255 bytes,
I find that hard to believe since the Desc field alone is 257 bytes.
and Marshal.SizeOf(typeof( SGMINFO )) in .Net is 344 bytes.
I get 312 or 308 depending on the packing.
Maybe this is due to the fact that a char in ansi C is 1 byte wheras a char in C# is 2 bytes?
The size of a char to the marshaler is whatever you set with the StructLayout attribute. If you keep the default (CharSet.Ansi) it's one byte per character.
Mattias
-- Mattias Sjögren [C# MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com Please reply only to the newsgroup.
>[ DllImport( "WDBase.dll", CharSet=CharSet.Auto, EntryPoint="DBenumA", SetLastError=true, ExactSpelling=true )] public static extern WarriorCommon.DBStat DBEnum( UInt32 DBHandler, string Path, Int32 Level, EnumCallbackCB Callback, Int32 SizeOfUserData, ref SGMINFO sgm );
You may have to add the attributes [In, Out] to the last parameter to
get changes to marshal back. I find that hard to believe since the Desc field alone is 257 bytes. Dont understand it, I checked again and sizeof(SGMINFO) is only 244 in C,
Then your value for strLONG must be wrong.
Mattias
--
Mattias Sjögren [C# MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
"Mattias Sjögren" <ma********************@mvps.org> wrote in message
news:O1*************@TK2MSFTNGP12.phx.gbl... You may have to add the attributes [In, Out] to the last parameter to get changes to marshal back.
Would that be a MarshalAsAttribute declaration?
Regards
Tor
>> You may have to add the attributes [In, Out] to the last parameter to get changes to marshal back.
Would that be a MarshalAsAttribute declaration?
No, the InAttribute and OutAttribute classes.
Mattias
--
Mattias Sjögren [C# MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Mattias,
Tanks for very good help!
"Mattias Sjögren" <ma********************@mvps.org> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl... You may have to add the attributes [In, Out] to the last parameter to get changes to marshal back.
Would that be a MarshalAsAttribute declaration?
No, the InAttribute and OutAttribute classes.
Mattias
-- Mattias Sjögren [C# MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com Please reply only to the newsgroup. This discussion thread is closed Replies have been disabled for this discussion. Similar topics
18 posts
views
Thread by Steven Bethard |
last post: by
|
7 posts
views
Thread by pmatos |
last post: by
|
56 posts
views
Thread by ccwork |
last post: by
|
1 post
views
Thread by geri.gan |
last post: by
|
10 posts
views
Thread by Giovanni Bajo |
last post: by
|
9 posts
views
Thread by Lloyd Dupont |
last post: by
|
1 post
views
Thread by Vikas |
last post: by
|
14 posts
views
Thread by barcaroller |
last post: by
|
4 posts
views
Thread by Steven Woody |
last post: by
| | | | | | | | | | |