Hi,
This is probably an easy one but it iy first bit of p/invoke. I am trying to
use the following C struct in a call:
typedef struct
{
BYTE SRB_Cmd;
BYTE SRB_Status,
BYTE SRB_HaId;
BYTE SRB_Flags;
DWORD SRB_Hdr_Rsvd;
BYTE HA_Count;
BYTE HA_SCSI_ID;
BYTE HA_ManagerId[16];
BYTE HA_Identifiyer[16];
BYTE HA_Unique[16];
BYTE HA_SRsvd1;
}
SRB_HAInquiry, *PSRB_HAInquiry ;
The function prototype is as follows:
SendASPI32Comma nd((LPSRB)&srbH AInquiry)
According to the docs LPSRB is 4 bit generic pointer to a command strucure.
Fort this I have:
[StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Ansi)]
public class SRB_HAInquiry
{
public const int STRING_LEN = 16;
public byte SRB_Cmd;
public byte SRB_Status;
public byte SRB_HaId;
public byte SRB_Flags;
public UInt32 SRB_Hdr_Rsvd;
public byte HA_Count;
public byte HA_SCSI_ID;
[MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)]
public string HA_ManagerId = new string(' ', STRING_LEN);
[MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)]
public string HA_Identifier = new string(' ', STRING_LEN);
[MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)]
public string HA_Unique = new string(' ', STRING_LEN);
public UInt16 HA_Rsvd1 = 0;
}
my invokke is :
[DllImport("wnas pi32.dll", EntryPoint="Sen dASPI32Command" ,
ExactSpelling=t rue, CharSet=CharSet .Ansi, SetLastError=tr ue)]
private static extern UInt32 SendASPI32Comma nd(
ref SRB_HAInquiry str);
and my call is:
public SRB_HAInquiry ScHaInquiry(int haId)
{
SRB_HAInquiry enq = new SRB_HAInquiry() ;
enq.SRB_Cmd = (byte)Commands. SC_HA_INQUIRY;
enq.SRB_HaId = (byte)haId;
UInt32 result = SendASPI32Comma nd(ref enq);
return enq;
}
Any help would be much appreciated.
Nov 16 '05
16 2504
Hi BMermuys,
Sorry Duncan to really interrupt.
I am not sure since in C, you do this:
BYTE HA_ManagerId[16];
Why in C#, you need to code this for:
[MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)]
public string HA_ManagerId;
Why just cannot be:
public string HA_ManagerId;
or public byte[] HA_ManagerID;
Why must there be a MarshalAs?
Just curious. Thanks again.
--
Regards,
Chua Wen Ching :)
"BMermuys" wrote: Hi,
"Duncan Mole" <du**********@n tlworld.com> wrote in message news:8f******** *******@newsfe1-gui.ntli.net... Hi BMermuys,
Well, unfortuantley the changes did not help. None of the fields are being set, this I can confirm becase SRB_Status is supposed to be set to the return value of SendASPI32Comma nd and it isn't. With regards to HA_SRsvd1 , this was a mistake in the post, it is acually a WORD.
I always use a struct not a class. A quick test using a class as a struct failed when an inline array is used, I gonna look into that later.
In the meantime if you didn't already tried it, try using a struct. This should work, if it doesn't check if the function doesn't return an error and check if you can call it succesfully from c.
[StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Ansi)] public struct SRB_HAInquiry { public const int STRING_LEN = 16; public byte SRB_Cmd; public byte SRB_Status; public byte SRB_HaId; public byte SRB_Flags; public uint SRB_Hdr_Rsvd; public byte HA_Count; public byte HA_SCSI_ID;
[MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] public string HA_ManagerId;
[MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] public string HA_Identifier;
[MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] public string HA_Unique;
public ushort HA_Rsvd1; }
[DllImport("wnas pi32.dll", EntryPoint="Sen dASPI32Command" , ExactSpelling=t rue, CharSet=CharSet .Ansi, SetLastError=tr ue)] private static extern UInt32 SendASPI32Comma nd(ref SRB_HAInquiry str);
HTH, greetings Any other ideas?
"Duncan Mole" <___@____.com > wrote in message news:Ox******** ******@TK2MSFTN GP11.phx.gbl... Hi BMermuys,
Thanks for the response. I wrote it last last night, trying new tricks that late is never a good idea! I look forward to making the fixes you have flagged when I get home tonight, interestingly HA_SRsvd1 was the only member whose value changed - hopefully this is a good sign! I'll post my
results to this thread.
Duncan
"BMermuys" <so*****@someon e.com> wrote in message news:Mw******** **************@ phobos.telenet-ops.be... > Hi, > > 3 problems: > > - You don't have to initialize the strings > > - If you use a class as struct, then you don't have to pass it by reference, > objects are already passed by reference. > If you use a struct then you have to pass it by reference. > > - HA_SRsvd1 is a BYTE inside the c structure and a Uint16 inside the managed > class, they don't match. > > > HTH, > greetings > > > "Duncan Mole" <du**********@n tlworld.com> wrote in message > news:L8******** *******@newsfe1-gui.ntli.net... > > Hi, > > > > This is probably an easy one but it iy first bit of p/invoke. I am trying > to > > use the following C struct in a call: > > > > typedef struct > > { > > BYTE SRB_Cmd; > > BYTE SRB_Status, > > BYTE SRB_HaId; > > BYTE SRB_Flags; > > DWORD SRB_Hdr_Rsvd; > > BYTE HA_Count; > > BYTE HA_SCSI_ID; > > BYTE HA_ManagerId[16]; > > BYTE HA_Identifiyer[16]; > > BYTE HA_Unique[16]; > > BYTE HA_SRsvd1; > > } > > SRB_HAInquiry, *PSRB_HAInquiry ; > > > > The function prototype is as follows: > > > > SendASPI32Comma nd((LPSRB)&srbH AInquiry) > > > > According to the docs LPSRB is 4 bit generic pointer to a command > strucure. > > > > Fort this I have: > > > > [StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Ansi)] > > > > public class SRB_HAInquiry > > > > { > > > > public const int STRING_LEN = 16; > > > > public byte SRB_Cmd; > > > > public byte SRB_Status; > > > > public byte SRB_HaId; > > > > public byte SRB_Flags; > > > > public UInt32 SRB_Hdr_Rsvd; > > > > public byte HA_Count; > > > > public byte HA_SCSI_ID; > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > public string HA_ManagerId = new string(' ', STRING_LEN); > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > public string HA_Identifier = new string(' ', STRING_LEN); > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > public string HA_Unique = new string(' ', STRING_LEN); > > > > public UInt16 HA_Rsvd1 = 0; > > > > } > > > > my invokke is : > > > > [DllImport("wnas pi32.dll", EntryPoint="Sen dASPI32Command" , > > > > ExactSpelling=t rue, CharSet=CharSet .Ansi, SetLastError=tr ue)] > > > > private static extern UInt32 SendASPI32Comma nd( > > > > ref SRB_HAInquiry str); > > > > > > > > and my call is: > > > > > > > > public SRB_HAInquiry ScHaInquiry(int haId) > > > > { > > > > SRB_HAInquiry enq = new SRB_HAInquiry() ; > > > > enq.SRB_Cmd = (byte)Commands. SC_HA_INQUIRY; > > > > enq.SRB_HaId = (byte)haId; > > > > UInt32 result = SendASPI32Comma nd(ref enq); > > > > > > return enq; > > > > } > > > > Any help would be much appreciated. > > > > > > > > > >
Hi,
[inline]
"Chua Wen Ching" <ch************ @nospam.hotmail .com> wrote in message
news:E7******** *************** ***********@mic rosoft.com... Hi BMermuys,
Wow. Thanks a lot. I always thought IntPtr is for integer. Not sure can be done with ushort. Had been thinking of using other ways. I had few doubts. Maybe you can help me to clarify it. Thanks.
From your code: -------------------- // eg write to it ushort x = 100; Marshal.WriteIn t16( myStruct.pData, (short) x );
--> Is this to write 100 value to myStruct.pData?
Storing the value 100 at the location where myStruct.pData points to. // suppose here you call an unmanaged function that alters (*pData), it shouldn't change the pointer, // then you can get the new value: x = (ushort)Marshal .ReadInt16( myStruct.pData );
--> I assume if we use *pData, normally we expect the out value there. So
it also means you are transfering the *pData out value to x.
This is basicly reading the value where pData points at and storing it in x. Marshal.FreeHGl obal( myStruct.pData ); //de-allocation
--> Is it always a must to do the de-allocation?
Well, if you allocate it using Marshal.AllocHG lobal then you need to free it
using FreeHGlobal. But the example was allocation and de-allocation from
C#. It's also possible that the allocation happens inside the dll, in this
case you should not de-allocate it in c#. Wow, if i had this:
struct StructTest { int Var1; int Var2; float Var3; IntPtr pData; IntPtr pHeader; IntPtr pBits; }
--> So i declare IntPtr for 3 times, had to marshal for 3 times and
deallocated for 3 times. Is that right?
You should only de-allocate if you allocated the memory. Again, it's
possible that the dll allocates memory, but then the dll should also
de-allocate it.
You can use Marshal.Copy, Marshal.ReadXXX , Marshal.WriteXX X,
Marshal.PtrToSt ruct, Marshal.StructT oPtr, depending on what the pointer
points at. Eg. for pData you probely want Marshal.Copy, so you can copy the
data into a managed byte array. --> I am also curious about UIntPtr. I saw this before. What is the
difference between UIntPtr and IntPtr. Why can't i use UIntPtr, as i am
using unsigned short pointer.
You can, but it won't make a difference, since marshalling happens with
Marshal.WriteIn t16/ReadInt16.
Realize that a pointer is an address. An address can point to anything.
It's also possible to *see* this address as a number which will have the
same wide as the pointer (32 or 64 bits).
UIntPtr and IntPtr both can represent any pointer (ushort*, int*, short*,
void*,etc). The difference is that IntPtr has methods to convert the
pointer to an signed integer, while UIntPtr has methods to convert the
pointer to an unsigned integer. Unsigned or signed they are still
addresses, and mostly used for pointer arithmetic, not for reading or
writing a value. --> Is there any good resources to pick up marshalling for this kind of
scenario. I am always looking forward on this, but I am not sure what is the
right keywords to search in the Internet.
IMHO you must really know C, and more important the concept of pointers.
I don't think you should try to learn it all at once. When you have a
concrete marshalling problem and you can't figure it out, post it here with
sufficient information, and we'll help you. And after a while you will see
a pattern. Offcourse .Net framework sdk documentation (which is also
online at microsoft) is a good starting place (it has a lot of examples
too), look for platform invoke.
HTH,
greetings Thanks again for the wonderful tips.
-- Regards, Chua Wen Ching :)
"BMermuys" wrote:
Hi, [inline]
"Chua Wen Ching" <ch************ @nospam.hotmail .com> wrote in message news:36******** *************** ***********@mic rosoft.com... Hi BMermuys,
What if i have a structure like this?
typedef unsigned short uint16;
typedef uint16 *puint16;
typedef struct StructA { puint16 Data; } StructTest;
[StructLayout(La youtKind.Sequen tial)] public struct StructTest { IntPtr pData; // PUSHORT }
Here you end up with the "pointer-problem". If you work with pointers,
you should think about allocating and de-allocating memory.
Think about: 1. The side (managed or unmanaged) that allocates the memory for the ushort should also de-allocate it. 2. This also means that the side that initial set the pointer can
only change it (re-allocation). 3. After allocation happened, any side can change the value the
pointer points to, that's no problem.
Example allocating memory from c# and de-allocating from c#: ---- StructTest myStruct = new StructTest(); myStruct.pData = Marshal.AllocHG lobal(sizeof(ty peof(ushort)); //allocation
// eg write to it ushort x = 100; Marshal.WriteIn t16( myStruct.pData, (short) x );
// suppose here you call an unmanaged function that alters (*pData), it shouldn't change the pointer, // then you can get the new value: x = (ushort)Marshal .ReadInt16( myStruct.pData );
Marshal.FreeHGl obal( myStruct.pData ); //de-allocation
HTH, greetings Any idea how to do this in C#?
Thanks. -- Regards, Chua Wen Ching :)
"BMermuys" wrote:
> Hi, > > 3 problems: > > - You don't have to initialize the strings > > - If you use a class as struct, then you don't have to pass it by
reference, > objects are already passed by reference. > If you use a struct then you have to pass it by reference. > > - HA_SRsvd1 is a BYTE inside the c structure and a Uint16 inside the managed > class, they don't match. > > > HTH, > greetings > > > "Duncan Mole" <du**********@n tlworld.com> wrote in message > news:L8******** *******@newsfe1-gui.ntli.net... > > Hi, > > > > This is probably an easy one but it iy first bit of p/invoke. I am trying > to > > use the following C struct in a call: > > > > typedef struct > > { > > BYTE SRB_Cmd; > > BYTE SRB_Status, > > BYTE SRB_HaId; > > BYTE SRB_Flags; > > DWORD SRB_Hdr_Rsvd; > > BYTE HA_Count; > > BYTE HA_SCSI_ID; > > BYTE HA_ManagerId[16]; > > BYTE HA_Identifiyer[16]; > > BYTE HA_Unique[16]; > > BYTE HA_SRsvd1; > > } > > SRB_HAInquiry, *PSRB_HAInquiry ; > > > > The function prototype is as follows: > > > > SendASPI32Comma nd((LPSRB)&srbH AInquiry) > > > > According to the docs LPSRB is 4 bit generic pointer to a command > strucure. > > > > Fort this I have: > > > > [StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Ansi)] > > > > public class SRB_HAInquiry > > > > { > > > > public const int STRING_LEN = 16; > > > > public byte SRB_Cmd; > > > > public byte SRB_Status; > > > > public byte SRB_HaId; > > > > public byte SRB_Flags; > > > > public UInt32 SRB_Hdr_Rsvd; > > > > public byte HA_Count; > > > > public byte HA_SCSI_ID; > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > public string HA_ManagerId = new string(' ', STRING_LEN); > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > public string HA_Identifier = new string(' ', STRING_LEN); > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > public string HA_Unique = new string(' ', STRING_LEN); > > > > public UInt16 HA_Rsvd1 = 0; > > > > } > > > > my invokke is : > > > > [DllImport("wnas pi32.dll", EntryPoint="Sen dASPI32Command" , > > > > ExactSpelling=t rue, CharSet=CharSet .Ansi, SetLastError=tr ue)] > > > > private static extern UInt32 SendASPI32Comma nd( > > > > ref SRB_HAInquiry str); > > > > > > > > and my call is: > > > > > > > > public SRB_HAInquiry ScHaInquiry(int haId) > > > > { > > > > SRB_HAInquiry enq = new SRB_HAInquiry() ; > > > > enq.SRB_Cmd = (byte)Commands. SC_HA_INQUIRY; > > > > enq.SRB_HaId = (byte)haId; > > > > UInt32 result = SendASPI32Comma nd(ref enq); > > > > > > return enq; > > > > } > > > > Any help would be much appreciated. > > > > > > > > > > >
Hi,
"Chua Wen Ching" <ch************ @nospam.hotmail .com> wrote in message
news:41******** *************** ***********@mic rosoft.com... Hi BMermuys,
Sorry Duncan to really interrupt.
I am not sure since in C, you do this:
BYTE HA_ManagerId[16];
This is inside a structure, so the bytes are actually part of the struct. Why in C#, you need to code this for:
[MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] public string HA_ManagerId;
Because if you want, you can see an array of bytes as a (ansi)string with a
fixed length. Why just cannot be: public string HA_ManagerId;
As far as I know, this would translate to a char* or byte* if you want. Not
to an inlined array. or public byte[] HA_ManagerID;
This is possible, but you still need the MarshalAs :
[MarshalAs(Unman agedType.ByValA rray,SizeConst= STRING_LEN)]
public byte[] HA_ManagerID; Why must there be a MarshalAs?
You need it mostly because of the const size.
EG.
struct // in C
{
byte b[10];
}
Now what's the size of this struct ? Always 10 bytes.
struct // in c#
{
byte[] b;
}
Now what's the size of this struct ? You can't tell, it depends on b. But
since you're using platform invoke. The struct's must match in size.
That's why you must specify the const size.
HTH,
greetings Just curious. Thanks again. -- Regards, Chua Wen Ching :)
"BMermuys" wrote:
Hi,
"Duncan Mole" <du**********@n tlworld.com> wrote in message news:8f******** *******@newsfe1-gui.ntli.net... Hi BMermuys,
Well, unfortuantley the changes did not help. None of the fields are
being set, this I can confirm becase SRB_Status is supposed to be set to the return value of SendASPI32Comma nd and it isn't. With regards to
HA_SRsvd1 , this was a mistake in the post, it is acually a WORD.
I always use a struct not a class. A quick test using a class as a
struct failed when an inline array is used, I gonna look into that later.
In the meantime if you didn't already tried it, try using a struct.
This should work, if it doesn't check if the function doesn't return an error
and check if you can call it succesfully from c.
[StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Ansi)] public struct SRB_HAInquiry { public const int STRING_LEN = 16; public byte SRB_Cmd; public byte SRB_Status; public byte SRB_HaId; public byte SRB_Flags; public uint SRB_Hdr_Rsvd; public byte HA_Count; public byte HA_SCSI_ID;
[MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] public string HA_ManagerId;
[MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] public string HA_Identifier;
[MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] public string HA_Unique;
public ushort HA_Rsvd1; }
[DllImport("wnas pi32.dll", EntryPoint="Sen dASPI32Command" , ExactSpelling=t rue, CharSet=CharSet .Ansi, SetLastError=tr ue)] private static extern UInt32 SendASPI32Comma nd(ref SRB_HAInquiry str);
HTH, greetings Any other ideas?
"Duncan Mole" <___@____.com > wrote in message news:Ox******** ******@TK2MSFTN GP11.phx.gbl... > Hi BMermuys, > > Thanks for the response. I wrote it last last night, trying new
tricks that > late is never a good idea! I look forward to making the fixes you
have > flagged when I get home tonight, interestingly HA_SRsvd1 was the
only member > whose value changed - hopefully this is a good sign! I'll post my results to > this thread. > > Duncan > > > "BMermuys" <so*****@someon e.com> wrote in message > news:Mw******** **************@ phobos.telenet-ops.be... > > Hi, > > > > 3 problems: > > > > - You don't have to initialize the strings > > > > - If you use a class as struct, then you don't have to pass it by > reference, > > objects are already passed by reference. > > If you use a struct then you have to pass it by reference. > > > > - HA_SRsvd1 is a BYTE inside the c structure and a Uint16 inside
the > managed > > class, they don't match. > > > > > > HTH, > > greetings > > > > > > "Duncan Mole" <du**********@n tlworld.com> wrote in message > > news:L8******** *******@newsfe1-gui.ntli.net... > > > Hi, > > > > > > This is probably an easy one but it iy first bit of p/invoke. I
am > trying > > to > > > use the following C struct in a call: > > > > > > typedef struct > > > { > > > BYTE SRB_Cmd; > > > BYTE SRB_Status, > > > BYTE SRB_HaId; > > > BYTE SRB_Flags; > > > DWORD SRB_Hdr_Rsvd; > > > BYTE HA_Count; > > > BYTE HA_SCSI_ID; > > > BYTE HA_ManagerId[16]; > > > BYTE HA_Identifiyer[16]; > > > BYTE HA_Unique[16]; > > > BYTE HA_SRsvd1; > > > } > > > SRB_HAInquiry, *PSRB_HAInquiry ; > > > > > > The function prototype is as follows: > > > > > > SendASPI32Comma nd((LPSRB)&srbH AInquiry) > > > > > > According to the docs LPSRB is 4 bit generic pointer to a
command > > strucure. > > > > > > Fort this I have: > > > > > > [StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Ansi)] > > > > > > public class SRB_HAInquiry > > > > > > { > > > > > > public const int STRING_LEN = 16; > > > > > > public byte SRB_Cmd; > > > > > > public byte SRB_Status; > > > > > > public byte SRB_HaId; > > > > > > public byte SRB_Flags; > > > > > > public UInt32 SRB_Hdr_Rsvd; > > > > > > public byte HA_Count; > > > > > > public byte HA_SCSI_ID; > > > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > > > public string HA_ManagerId = new string(' ', STRING_LEN); > > > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > > > public string HA_Identifier = new string(' ', STRING_LEN); > > > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > > > public string HA_Unique = new string(' ', STRING_LEN); > > > > > > public UInt16 HA_Rsvd1 = 0; > > > > > > } > > > > > > my invokke is : > > > > > > [DllImport("wnas pi32.dll", EntryPoint="Sen dASPI32Command" , > > > > > > ExactSpelling=t rue, CharSet=CharSet .Ansi, SetLastError=tr ue)] > > > > > > private static extern UInt32 SendASPI32Comma nd( > > > > > > ref SRB_HAInquiry str); > > > > > > > > > > > > and my call is: > > > > > > > > > > > > public SRB_HAInquiry ScHaInquiry(int haId) > > > > > > { > > > > > > SRB_HAInquiry enq = new SRB_HAInquiry() ; > > > > > > enq.SRB_Cmd = (byte)Commands. SC_HA_INQUIRY; > > > > > > enq.SRB_HaId = (byte)haId; > > > > > > UInt32 result = SendASPI32Comma nd(ref enq); > > > > > > > > > return enq; > > > > > > } > > > > > > Any help would be much appreciated. > > > > > > > > > > > > > > > > > >
Hi BMermuys,
Thanks a lot.
You think is necessary for me to buy Adam Nathan's .NET and COM book?
Yeah, soon i need to code C. Sad story. Haha!
Thanks again.
--
Regards,
Chua Wen Ching :)
"BMermuys" wrote: Hi, [inline]
"Chua Wen Ching" <ch************ @nospam.hotmail .com> wrote in message news:E7******** *************** ***********@mic rosoft.com... Hi BMermuys,
Wow. Thanks a lot. I always thought IntPtr is for integer. Not sure can be done with ushort. Had been thinking of using other ways. I had few doubts. Maybe you can help me to clarify it. Thanks.
From your code: -------------------- // eg write to it ushort x = 100; Marshal.WriteIn t16( myStruct.pData, (short) x );
--> Is this to write 100 value to myStruct.pData?
Storing the value 100 at the location where myStruct.pData points to.
// suppose here you call an unmanaged function that alters (*pData), it shouldn't change the pointer, // then you can get the new value: x = (ushort)Marshal .ReadInt16( myStruct.pData );
--> I assume if we use *pData, normally we expect the out value there. So
it also means you are transfering the *pData out value to x.
This is basicly reading the value where pData points at and storing it in x.
Marshal.FreeHGl obal( myStruct.pData ); //de-allocation
--> Is it always a must to do the de-allocation?
Well, if you allocate it using Marshal.AllocHG lobal then you need to free it using FreeHGlobal. But the example was allocation and de-allocation from C#. It's also possible that the allocation happens inside the dll, in this case you should not de-allocate it in c#.
Wow, if i had this:
struct StructTest { int Var1; int Var2; float Var3; IntPtr pData; IntPtr pHeader; IntPtr pBits; }
--> So i declare IntPtr for 3 times, had to marshal for 3 times and
deallocated for 3 times. Is that right?
You should only de-allocate if you allocated the memory. Again, it's possible that the dll allocates memory, but then the dll should also de-allocate it.
You can use Marshal.Copy, Marshal.ReadXXX , Marshal.WriteXX X, Marshal.PtrToSt ruct, Marshal.StructT oPtr, depending on what the pointer points at. Eg. for pData you probely want Marshal.Copy, so you can copy the data into a managed byte array.
--> I am also curious about UIntPtr. I saw this before. What is the
difference between UIntPtr and IntPtr. Why can't i use UIntPtr, as i am using unsigned short pointer.
You can, but it won't make a difference, since marshalling happens with Marshal.WriteIn t16/ReadInt16.
Realize that a pointer is an address. An address can point to anything. It's also possible to *see* this address as a number which will have the same wide as the pointer (32 or 64 bits).
UIntPtr and IntPtr both can represent any pointer (ushort*, int*, short*, void*,etc). The difference is that IntPtr has methods to convert the pointer to an signed integer, while UIntPtr has methods to convert the pointer to an unsigned integer. Unsigned or signed they are still addresses, and mostly used for pointer arithmetic, not for reading or writing a value.
--> Is there any good resources to pick up marshalling for this kind of
scenario. I am always looking forward on this, but I am not sure what is the right keywords to search in the Internet.
IMHO you must really know C, and more important the concept of pointers.
I don't think you should try to learn it all at once. When you have a concrete marshalling problem and you can't figure it out, post it here with sufficient information, and we'll help you. And after a while you will see a pattern. Offcourse .Net framework sdk documentation (which is also online at microsoft) is a good starting place (it has a lot of examples too), look for platform invoke.
HTH, greetings
Thanks again for the wonderful tips.
-- Regards, Chua Wen Ching :)
"BMermuys" wrote:
Hi, [inline]
"Chua Wen Ching" <ch************ @nospam.hotmail .com> wrote in message news:36******** *************** ***********@mic rosoft.com... > Hi BMermuys, > > What if i have a structure like this? > > typedef unsigned short uint16; > > typedef uint16 *puint16; > > typedef struct StructA > { > puint16 Data; > } StructTest;
[StructLayout(La youtKind.Sequen tial)] public struct StructTest { IntPtr pData; // PUSHORT }
Here you end up with the "pointer-problem". If you work with pointers, you should think about allocating and de-allocating memory.
Think about: 1. The side (managed or unmanaged) that allocates the memory for the ushort should also de-allocate it. 2. This also means that the side that initial set the pointer can only change it (re-allocation). 3. After allocation happened, any side can change the value the pointer points to, that's no problem.
Example allocating memory from c# and de-allocating from c#: ---- StructTest myStruct = new StructTest(); myStruct.pData = Marshal.AllocHG lobal(sizeof(ty peof(ushort)); //allocation
// eg write to it ushort x = 100; Marshal.WriteIn t16( myStruct.pData, (short) x );
// suppose here you call an unmanaged function that alters (*pData), it shouldn't change the pointer, // then you can get the new value: x = (ushort)Marshal .ReadInt16( myStruct.pData );
Marshal.FreeHGl obal( myStruct.pData ); //de-allocation
HTH, greetings > > Any idea how to do this in C#? > > Thanks. > -- > Regards, > Chua Wen Ching :) > > > "BMermuys" wrote: > > > Hi, > > > > 3 problems: > > > > - You don't have to initialize the strings > > > > - If you use a class as struct, then you don't have to pass it by reference, > > objects are already passed by reference. > > If you use a struct then you have to pass it by reference. > > > > - HA_SRsvd1 is a BYTE inside the c structure and a Uint16 inside the managed > > class, they don't match. > > > > > > HTH, > > greetings > > > > > > "Duncan Mole" <du**********@n tlworld.com> wrote in message > > news:L8******** *******@newsfe1-gui.ntli.net... > > > Hi, > > > > > > This is probably an easy one but it iy first bit of p/invoke. I am trying > > to > > > use the following C struct in a call: > > > > > > typedef struct > > > { > > > BYTE SRB_Cmd; > > > BYTE SRB_Status, > > > BYTE SRB_HaId; > > > BYTE SRB_Flags; > > > DWORD SRB_Hdr_Rsvd; > > > BYTE HA_Count; > > > BYTE HA_SCSI_ID; > > > BYTE HA_ManagerId[16]; > > > BYTE HA_Identifiyer[16]; > > > BYTE HA_Unique[16]; > > > BYTE HA_SRsvd1; > > > } > > > SRB_HAInquiry, *PSRB_HAInquiry ; > > > > > > The function prototype is as follows: > > > > > > SendASPI32Comma nd((LPSRB)&srbH AInquiry) > > > > > > According to the docs LPSRB is 4 bit generic pointer to a command > > strucure. > > > > > > Fort this I have: > > > > > > [StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Ansi)] > > > > > > public class SRB_HAInquiry > > > > > > { > > > > > > public const int STRING_LEN = 16; > > > > > > public byte SRB_Cmd; > > > > > > public byte SRB_Status; > > > > > > public byte SRB_HaId; > > > > > > public byte SRB_Flags; > > > > > > public UInt32 SRB_Hdr_Rsvd; > > > > > > public byte HA_Count; > > > > > > public byte HA_SCSI_ID; > > > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > > > public string HA_ManagerId = new string(' ', STRING_LEN); > > > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > > > public string HA_Identifier = new string(' ', STRING_LEN); > > > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > > > public string HA_Unique = new string(' ', STRING_LEN); > > > > > > public UInt16 HA_Rsvd1 = 0; > > > > > > } > > > > > > my invokke is : > > > > > > [DllImport("wnas pi32.dll", EntryPoint="Sen dASPI32Command" , > > > > > > ExactSpelling=t rue, CharSet=CharSet .Ansi, SetLastError=tr ue)] > > > > > > private static extern UInt32 SendASPI32Comma nd( > > > > > > ref SRB_HAInquiry str); > > > > > > > > > > > > and my call is: > > > > > > > > > > > > public SRB_HAInquiry ScHaInquiry(int haId) > > > > > > { > > > > > > SRB_HAInquiry enq = new SRB_HAInquiry() ; > > > > > > enq.SRB_Cmd = (byte)Commands. SC_HA_INQUIRY; > > > > > > enq.SRB_HaId = (byte)haId; > > > > > > UInt32 result = SendASPI32Comma nd(ref enq); > > > > > > > > > return enq; > > > > > > } > > > > > > Any help would be much appreciated. > > > > > > > > > > > > > > > > > >
Hi BMermuys,
I understand now. I had one more question.
struct // in C
{
byte b[10];
}
Now what's the size of this struct ? Always 10 bytes.
struct // in c#
{
byte[] b;
}
Now what's the size of this struct ? You can't tell, it depends on b. But
since you're using platform invoke. The struct's must match in size.
That's why you must specify the const size.
--> Quite true. But then how do you allocate size 10 to byte[] b in c#?
By this:
Struct aStruct = new Struct();
aStruct.b = new byte[10]; // ???? not sure what i am doing!
Thanks again.
--
Regards,
Chua Wen Ching :)
"BMermuys" wrote: Hi,
"Chua Wen Ching" <ch************ @nospam.hotmail .com> wrote in message news:41******** *************** ***********@mic rosoft.com... Hi BMermuys,
Sorry Duncan to really interrupt.
I am not sure since in C, you do this:
BYTE HA_ManagerId[16];
This is inside a structure, so the bytes are actually part of the struct.
Why in C#, you need to code this for:
[MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] public string HA_ManagerId;
Because if you want, you can see an array of bytes as a (ansi)string with a fixed length.
Why just cannot be: public string HA_ManagerId;
As far as I know, this would translate to a char* or byte* if you want. Not to an inlined array.
or public byte[] HA_ManagerID;
This is possible, but you still need the MarshalAs :
[MarshalAs(Unman agedType.ByValA rray,SizeConst= STRING_LEN)] public byte[] HA_ManagerID;
Why must there be a MarshalAs?
You need it mostly because of the const size.
EG. struct // in C { byte b[10]; }
Now what's the size of this struct ? Always 10 bytes.
struct // in c# { byte[] b; }
Now what's the size of this struct ? You can't tell, it depends on b. But since you're using platform invoke. The struct's must match in size. That's why you must specify the const size.
HTH, greetings Just curious. Thanks again. -- Regards, Chua Wen Ching :)
"BMermuys" wrote:
Hi,
"Duncan Mole" <du**********@n tlworld.com> wrote in message news:8f******** *******@newsfe1-gui.ntli.net... > Hi BMermuys, > > Well, unfortuantley the changes did not help. None of the fields are being > set, this I can confirm becase SRB_Status is supposed to be set to the > return value of SendASPI32Comma nd and it isn't. With regards to HA_SRsvd1 , > this was a mistake in the post, it is acually a WORD.
I always use a struct not a class. A quick test using a class as a struct failed when an inline array is used, I gonna look into that later.
In the meantime if you didn't already tried it, try using a struct. This should work, if it doesn't check if the function doesn't return an error and check if you can call it succesfully from c.
[StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Ansi)] public struct SRB_HAInquiry { public const int STRING_LEN = 16; public byte SRB_Cmd; public byte SRB_Status; public byte SRB_HaId; public byte SRB_Flags; public uint SRB_Hdr_Rsvd; public byte HA_Count; public byte HA_SCSI_ID;
[MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] public string HA_ManagerId;
[MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] public string HA_Identifier;
[MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] public string HA_Unique;
public ushort HA_Rsvd1; }
[DllImport("wnas pi32.dll", EntryPoint="Sen dASPI32Command" , ExactSpelling=t rue, CharSet=CharSet .Ansi, SetLastError=tr ue)] private static extern UInt32 SendASPI32Comma nd(ref SRB_HAInquiry str);
HTH, greetings > > Any other ideas? > > "Duncan Mole" <___@____.com > wrote in message > news:Ox******** ******@TK2MSFTN GP11.phx.gbl... > > Hi BMermuys, > > > > Thanks for the response. I wrote it last last night, trying new tricks > that > > late is never a good idea! I look forward to making the fixes you have > > flagged when I get home tonight, interestingly HA_SRsvd1 was the only > member > > whose value changed - hopefully this is a good sign! I'll post my results > to > > this thread. > > > > Duncan > > > > > > "BMermuys" <so*****@someon e.com> wrote in message > > news:Mw******** **************@ phobos.telenet-ops.be... > > > Hi, > > > > > > 3 problems: > > > > > > - You don't have to initialize the strings > > > > > > - If you use a class as struct, then you don't have to pass it by > > reference, > > > objects are already passed by reference. > > > If you use a struct then you have to pass it by reference. > > > > > > - HA_SRsvd1 is a BYTE inside the c structure and a Uint16 inside the > > managed > > > class, they don't match. > > > > > > > > > HTH, > > > greetings > > > > > > > > > "Duncan Mole" <du**********@n tlworld.com> wrote in message > > > news:L8******** *******@newsfe1-gui.ntli.net... > > > > Hi, > > > > > > > > This is probably an easy one but it iy first bit of p/invoke. I am > > trying > > > to > > > > use the following C struct in a call: > > > > > > > > typedef struct > > > > { > > > > BYTE SRB_Cmd; > > > > BYTE SRB_Status, > > > > BYTE SRB_HaId; > > > > BYTE SRB_Flags; > > > > DWORD SRB_Hdr_Rsvd; > > > > BYTE HA_Count; > > > > BYTE HA_SCSI_ID; > > > > BYTE HA_ManagerId[16]; > > > > BYTE HA_Identifiyer[16]; > > > > BYTE HA_Unique[16]; > > > > BYTE HA_SRsvd1; > > > > } > > > > SRB_HAInquiry, *PSRB_HAInquiry ; > > > > > > > > The function prototype is as follows: > > > > > > > > SendASPI32Comma nd((LPSRB)&srbH AInquiry) > > > > > > > > According to the docs LPSRB is 4 bit generic pointer to a command > > > strucure. > > > > > > > > Fort this I have: > > > > > > > > [StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Ansi)] > > > > > > > > public class SRB_HAInquiry > > > > > > > > { > > > > > > > > public const int STRING_LEN = 16; > > > > > > > > public byte SRB_Cmd; > > > > > > > > public byte SRB_Status; > > > > > > > > public byte SRB_HaId; > > > > > > > > public byte SRB_Flags; > > > > > > > > public UInt32 SRB_Hdr_Rsvd; > > > > > > > > public byte HA_Count; > > > > > > > > public byte HA_SCSI_ID; > > > > > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > > > > > public string HA_ManagerId = new string(' ', STRING_LEN); > > > > > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > > > > > public string HA_Identifier = new string(' ', STRING_LEN); > > > > > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > > > > > public string HA_Unique = new string(' ', STRING_LEN); > > > > > > > > public UInt16 HA_Rsvd1 = 0; > > > > > > > > } > > > > > > > > my invokke is : > > > > > > > > [DllImport("wnas pi32.dll", EntryPoint="Sen dASPI32Command" , > > > > > > > > ExactSpelling=t rue, CharSet=CharSet .Ansi, SetLastError=tr ue)] > > > > > > > > private static extern UInt32 SendASPI32Comma nd( > > > > > > > > ref SRB_HAInquiry str); > > > > > > > > > > > > > > > > and my call is: > > > > > > > > > > > > > > > > public SRB_HAInquiry ScHaInquiry(int haId) > > > > > > > > { > > > > > > > > SRB_HAInquiry enq = new SRB_HAInquiry() ; > > > > > > > > enq.SRB_Cmd = (byte)Commands. SC_HA_INQUIRY; > > > > > > > > enq.SRB_HaId = (byte)haId; > > > > > > > > UInt32 result = SendASPI32Comma nd(ref enq); > > > > > > > > > > > > return enq; > > > > > > > > } > > > > > > > > Any help would be much appreciated. > > > > > > > > > > > > > > > > > > > > > > > > > > > >
Hi,
<snip>
--> Quite true. But then how do you allocate size 10 to byte[] b in c#? By this:
Struct aStruct = new Struct(); aStruct.b = new byte[10]; // ???? not sure what i am doing!
Yes, that's right, you *must* do that before passing the struct to some
unmanaged function.
HTH,
greetings Thanks again. -- Regards, Chua Wen Ching :)
"BMermuys" wrote:
Hi,
"Chua Wen Ching" <ch************ @nospam.hotmail .com> wrote in message news:41******** *************** ***********@mic rosoft.com... Hi BMermuys,
Sorry Duncan to really interrupt.
I am not sure since in C, you do this:
BYTE HA_ManagerId[16];
This is inside a structure, so the bytes are actually part of the
struct. Why in C#, you need to code this for:
[MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] public string HA_ManagerId;
Because if you want, you can see an array of bytes as a (ansi)string
with a fixed length.
Why just cannot be: public string HA_ManagerId;
As far as I know, this would translate to a char* or byte* if you want.
Not to an inlined array.
or public byte[] HA_ManagerID;
This is possible, but you still need the MarshalAs :
[MarshalAs(Unman agedType.ByValA rray,SizeConst= STRING_LEN)] public byte[] HA_ManagerID;
Why must there be a MarshalAs?
You need it mostly because of the const size.
EG. struct // in C { byte b[10]; }
Now what's the size of this struct ? Always 10 bytes.
struct // in c# { byte[] b; }
Now what's the size of this struct ? You can't tell, it depends on b.
But since you're using platform invoke. The struct's must match in size. That's why you must specify the const size.
HTH, greetings Just curious. Thanks again. -- Regards, Chua Wen Ching :)
"BMermuys" wrote:
> Hi, > > "Duncan Mole" <du**********@n tlworld.com> wrote in message > news:8f******** *******@newsfe1-gui.ntli.net... > > Hi BMermuys, > > > > Well, unfortuantley the changes did not help. None of the fields
are being > > set, this I can confirm becase SRB_Status is supposed to be set to
the > > return value of SendASPI32Comma nd and it isn't. With regards to HA_SRsvd1 > , > > this was a mistake in the post, it is acually a WORD. > > I always use a struct not a class. A quick test using a class as a struct > failed when an inline array is used, I gonna look into that later. > > In the meantime if you didn't already tried it, try using a struct. This > should work, if it doesn't check if the function doesn't return an
error and > check if you can call it succesfully from c. > > [StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Ansi)] > public struct SRB_HAInquiry > { > public const int STRING_LEN = 16; > public byte SRB_Cmd; > public byte SRB_Status; > public byte SRB_HaId; > public byte SRB_Flags; > public uint SRB_Hdr_Rsvd; > public byte HA_Count; > public byte HA_SCSI_ID; > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > public string HA_ManagerId; > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > public string HA_Identifier; > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > public string HA_Unique; > > public ushort HA_Rsvd1; > } > > [DllImport("wnas pi32.dll", EntryPoint="Sen dASPI32Command" , > ExactSpelling=t rue, CharSet=CharSet .Ansi, SetLastError=tr ue)] > private static extern UInt32 SendASPI32Comma nd(ref SRB_HAInquiry
str); > > HTH, > greetings > > > > > > > Any other ideas? > > > > "Duncan Mole" <___@____.com > wrote in message > > news:Ox******** ******@TK2MSFTN GP11.phx.gbl... > > > Hi BMermuys, > > > > > > Thanks for the response. I wrote it last last night, trying new tricks > > that > > > late is never a good idea! I look forward to making the fixes
you have > > > flagged when I get home tonight, interestingly HA_SRsvd1 was the only > > member > > > whose value changed - hopefully this is a good sign! I'll post
my > results > > to > > > this thread. > > > > > > Duncan > > > > > > > > > "BMermuys" <so*****@someon e.com> wrote in message > > > news:Mw******** **************@ phobos.telenet-ops.be... > > > > Hi, > > > > > > > > 3 problems: > > > > > > > > - You don't have to initialize the strings > > > > > > > > - If you use a class as struct, then you don't have to pass it
by > > > reference, > > > > objects are already passed by reference. > > > > If you use a struct then you have to pass it by reference. > > > > > > > > - HA_SRsvd1 is a BYTE inside the c structure and a Uint16
inside the > > > managed > > > > class, they don't match. > > > > > > > > > > > > HTH, > > > > greetings > > > > > > > > > > > > "Duncan Mole" <du**********@n tlworld.com> wrote in message > > > > news:L8******** *******@newsfe1-gui.ntli.net... > > > > > Hi, > > > > > > > > > > This is probably an easy one but it iy first bit of
p/invoke. I am > > > trying > > > > to > > > > > use the following C struct in a call: > > > > > > > > > > typedef struct > > > > > { > > > > > BYTE SRB_Cmd; > > > > > BYTE SRB_Status, > > > > > BYTE SRB_HaId; > > > > > BYTE SRB_Flags; > > > > > DWORD SRB_Hdr_Rsvd; > > > > > BYTE HA_Count; > > > > > BYTE HA_SCSI_ID; > > > > > BYTE HA_ManagerId[16]; > > > > > BYTE HA_Identifiyer[16]; > > > > > BYTE HA_Unique[16]; > > > > > BYTE HA_SRsvd1; > > > > > } > > > > > SRB_HAInquiry, *PSRB_HAInquiry ; > > > > > > > > > > The function prototype is as follows: > > > > > > > > > > SendASPI32Comma nd((LPSRB)&srbH AInquiry) > > > > > > > > > > According to the docs LPSRB is 4 bit generic pointer to a command > > > > strucure. > > > > > > > > > > Fort this I have: > > > > > > > > > > [StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Ansi)] > > > > > > > > > > public class SRB_HAInquiry > > > > > > > > > > { > > > > > > > > > > public const int STRING_LEN = 16; > > > > > > > > > > public byte SRB_Cmd; > > > > > > > > > > public byte SRB_Status; > > > > > > > > > > public byte SRB_HaId; > > > > > > > > > > public byte SRB_Flags; > > > > > > > > > > public UInt32 SRB_Hdr_Rsvd; > > > > > > > > > > public byte HA_Count; > > > > > > > > > > public byte HA_SCSI_ID; > > > > > > > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > > > > > > > public string HA_ManagerId = new string(' ', STRING_LEN); > > > > > > > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > > > > > > > public string HA_Identifier = new string(' ', STRING_LEN); > > > > > > > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > > > > > > > public string HA_Unique = new string(' ', STRING_LEN); > > > > > > > > > > public UInt16 HA_Rsvd1 = 0; > > > > > > > > > > } > > > > > > > > > > my invokke is : > > > > > > > > > > [DllImport("wnas pi32.dll", EntryPoint="Sen dASPI32Command" , > > > > > > > > > > ExactSpelling=t rue, CharSet=CharSet .Ansi,
SetLastError=tr ue)] > > > > > > > > > > private static extern UInt32 SendASPI32Comma nd( > > > > > > > > > > ref SRB_HAInquiry str); > > > > > > > > > > > > > > > > > > > > and my call is: > > > > > > > > > > > > > > > > > > > > public SRB_HAInquiry ScHaInquiry(int haId) > > > > > > > > > > { > > > > > > > > > > SRB_HAInquiry enq = new SRB_HAInquiry() ; > > > > > > > > > > enq.SRB_Cmd = (byte)Commands. SC_HA_INQUIRY; > > > > > > > > > > enq.SRB_HaId = (byte)haId; > > > > > > > > > > UInt32 result = SendASPI32Comma nd(ref enq); > > > > > > > > > > > > > > > return enq; > > > > > > > > > > } > > > > > > > > > > Any help would be much appreciated. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >
Thanks BMermuys for the confirmation. :)
--
Regards,
Chua Wen Ching :)
"BMermuys" wrote: Hi,
<snip>
--> Quite true. But then how do you allocate size 10 to byte[] b in c#? By this:
Struct aStruct = new Struct(); aStruct.b = new byte[10]; // ???? not sure what i am doing!
Yes, that's right, you *must* do that before passing the struct to some unmanaged function. HTH, greetings
Thanks again. -- Regards, Chua Wen Ching :)
"BMermuys" wrote:
Hi,
"Chua Wen Ching" <ch************ @nospam.hotmail .com> wrote in message news:41******** *************** ***********@mic rosoft.com... > Hi BMermuys, > > Sorry Duncan to really interrupt. > > I am not sure since in C, you do this: > > BYTE HA_ManagerId[16];
This is inside a structure, so the bytes are actually part of the struct. > > Why in C#, you need to code this for: > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > public string HA_ManagerId;
Because if you want, you can see an array of bytes as a (ansi)string with a fixed length.
> > Why just cannot be: > public string HA_ManagerId;
As far as I know, this would translate to a char* or byte* if you want. Not to an inlined array.
> > or public byte[] HA_ManagerID;
This is possible, but you still need the MarshalAs :
[MarshalAs(Unman agedType.ByValA rray,SizeConst= STRING_LEN)] public byte[] HA_ManagerID;
> > Why must there be a MarshalAs?
You need it mostly because of the const size.
EG. struct // in C { byte b[10]; }
Now what's the size of this struct ? Always 10 bytes.
struct // in c# { byte[] b; }
Now what's the size of this struct ? You can't tell, it depends on b. But since you're using platform invoke. The struct's must match in size. That's why you must specify the const size.
HTH, greetings > > Just curious. Thanks again. > -- > Regards, > Chua Wen Ching :) > > > "BMermuys" wrote: > > > Hi, > > > > "Duncan Mole" <du**********@n tlworld.com> wrote in message > > news:8f******** *******@newsfe1-gui.ntli.net... > > > Hi BMermuys, > > > > > > Well, unfortuantley the changes did not help. None of the fields are being > > > set, this I can confirm becase SRB_Status is supposed to be set to the > > > return value of SendASPI32Comma nd and it isn't. With regards to HA_SRsvd1 > > , > > > this was a mistake in the post, it is acually a WORD. > > > > I always use a struct not a class. A quick test using a class as a struct > > failed when an inline array is used, I gonna look into that later. > > > > In the meantime if you didn't already tried it, try using a struct. This > > should work, if it doesn't check if the function doesn't return an error and > > check if you can call it succesfully from c. > > > > [StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Ansi)] > > public struct SRB_HAInquiry > > { > > public const int STRING_LEN = 16; > > public byte SRB_Cmd; > > public byte SRB_Status; > > public byte SRB_HaId; > > public byte SRB_Flags; > > public uint SRB_Hdr_Rsvd; > > public byte HA_Count; > > public byte HA_SCSI_ID; > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > public string HA_ManagerId; > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > public string HA_Identifier; > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > public string HA_Unique; > > > > public ushort HA_Rsvd1; > > } > > > > [DllImport("wnas pi32.dll", EntryPoint="Sen dASPI32Command" , > > ExactSpelling=t rue, CharSet=CharSet .Ansi, SetLastError=tr ue)] > > private static extern UInt32 SendASPI32Comma nd(ref SRB_HAInquiry str); > > > > HTH, > > greetings > > > > > > > > > > > > Any other ideas? > > > > > > "Duncan Mole" <___@____.com > wrote in message > > > news:Ox******** ******@TK2MSFTN GP11.phx.gbl... > > > > Hi BMermuys, > > > > > > > > Thanks for the response. I wrote it last last night, trying new tricks > > > that > > > > late is never a good idea! I look forward to making the fixes you have > > > > flagged when I get home tonight, interestingly HA_SRsvd1 was the only > > > member > > > > whose value changed - hopefully this is a good sign! I'll post my > > results > > > to > > > > this thread. > > > > > > > > Duncan > > > > > > > > > > > > "BMermuys" <so*****@someon e.com> wrote in message > > > > news:Mw******** **************@ phobos.telenet-ops.be... > > > > > Hi, > > > > > > > > > > 3 problems: > > > > > > > > > > - You don't have to initialize the strings > > > > > > > > > > - If you use a class as struct, then you don't have to pass it by > > > > reference, > > > > > objects are already passed by reference. > > > > > If you use a struct then you have to pass it by reference. > > > > > > > > > > - HA_SRsvd1 is a BYTE inside the c structure and a Uint16 inside the > > > > managed > > > > > class, they don't match. > > > > > > > > > > > > > > > HTH, > > > > > greetings > > > > > > > > > > > > > > > "Duncan Mole" <du**********@n tlworld.com> wrote in message > > > > > news:L8******** *******@newsfe1-gui.ntli.net... > > > > > > Hi, > > > > > > > > > > > > This is probably an easy one but it iy first bit of p/invoke. I am > > > > trying > > > > > to > > > > > > use the following C struct in a call: > > > > > > > > > > > > typedef struct > > > > > > { > > > > > > BYTE SRB_Cmd; > > > > > > BYTE SRB_Status, > > > > > > BYTE SRB_HaId; > > > > > > BYTE SRB_Flags; > > > > > > DWORD SRB_Hdr_Rsvd; > > > > > > BYTE HA_Count; > > > > > > BYTE HA_SCSI_ID; > > > > > > BYTE HA_ManagerId[16]; > > > > > > BYTE HA_Identifiyer[16]; > > > > > > BYTE HA_Unique[16]; > > > > > > BYTE HA_SRsvd1; > > > > > > } > > > > > > SRB_HAInquiry, *PSRB_HAInquiry ; > > > > > > > > > > > > The function prototype is as follows: > > > > > > > > > > > > SendASPI32Comma nd((LPSRB)&srbH AInquiry) > > > > > > > > > > > > According to the docs LPSRB is 4 bit generic pointer to a command > > > > > strucure. > > > > > > > > > > > > Fort this I have: > > > > > > > > > > > > [StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Ansi)] > > > > > > > > > > > > public class SRB_HAInquiry > > > > > > > > > > > > { > > > > > > > > > > > > public const int STRING_LEN = 16; > > > > > > > > > > > > public byte SRB_Cmd; > > > > > > > > > > > > public byte SRB_Status; > > > > > > > > > > > > public byte SRB_HaId; > > > > > > > > > > > > public byte SRB_Flags; > > > > > > > > > > > > public UInt32 SRB_Hdr_Rsvd; > > > > > > > > > > > > public byte HA_Count; > > > > > > > > > > > > public byte HA_SCSI_ID; > > > > > > > > > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > > > > > > > > > public string HA_ManagerId = new string(' ', STRING_LEN); > > > > > > > > > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > > > > > > > > > public string HA_Identifier = new string(' ', STRING_LEN); > > > > > > > > > > > > [MarshalAs(Unman agedType.ByValT Str, SizeConst=STRIN G_LEN)] > > > > > > > > > > > > public string HA_Unique = new string(' ', STRING_LEN); > > > > > > > > > > > > public UInt16 HA_Rsvd1 = 0; > > > > > > > > > > > > } > > > > > > > > > > > > my invokke is : > > > > > > > > > > > > [DllImport("wnas pi32.dll", EntryPoint="Sen dASPI32Command" , > > > > > > > > > > > > ExactSpelling=t rue, CharSet=CharSet .Ansi, SetLastError=tr ue)] > > > > > > > > > > > > private static extern UInt32 SendASPI32Comma nd( > > > > > > > > > > > > ref SRB_HAInquiry str); > > > > > > > > > > > > > > > > > > > > > > > > and my call is: > > > > > > > > > > > > > > > > > > > > > > > > public SRB_HAInquiry ScHaInquiry(int haId) > > > > > > > > > > > > { > > > > > > > > > > > > SRB_HAInquiry enq = new SRB_HAInquiry() ; > > > > > > > > > > > > enq.SRB_Cmd = (byte)Commands. SC_HA_INQUIRY; > > > > > > > > > > > > enq.SRB_HaId = (byte)haId; > > > > > > > > > > > > UInt32 result = SendASPI32Comma nd(ref enq); > > > > > > > > > > > > > > > > > > return enq; > > > > > > > > > > > > } > > > > > > > > > > > > Any help would be much appreciated. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >
This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: brckcc |
last post by:
I have a function in C which takes a pointer to a pointer to a structure. It
then returns a linked list.
How do I call, via P/Invoke, from C# to C.
struct LinkedList
{
char *value;
struct LinkedList *next;
}
|
by: Zürcher See |
last post by:
I'm using the following structure for my programm, and I never had problems.
Now by the invoke of the MyObject_End eventhandler I get the following
error:
System.Windows.FormsSpecified cast is not valid.
at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate
method, Object args, Boolean synchronous)
at System.Windows.Forms.Control.Invoke(Delegate method, Object args)
....
|
by: Daniel Jin |
last post by:
I'm trying to P/Invoke a method in shell32.dll. here's the method signature.
LPITEMIDLIST SHBrowseForFolder( LPBROWSEINFO lpbi );
and this is the parameter structure
typedef struct _browseinfo {
HWND hwndOwner;
LPCITEMIDLIST pidlRoot;
LPTSTR pszDisplayName;
|
by: Xia Wei |
last post by:
Hi group,
I'v got something wrong with P/Invoke. If I have two structs defined like
this:
typedef struct{
DWORD F1;
}A, *PA;
typedef struct{
A Data;
|
by: Charles Denny |
last post by:
I'm trying to invoke CertFindCertificateInStore to find all certificates that
have the Code Signing enhanced key attribute. I'd just like to find 1 cert
(not even all at this point), however, I keep coming up with the error - "
Can not marshal parameter #5: Invalid managed/unmanaged type combination
(this value type must be paired with Struct)."
The structs are defined as:
public struct CRYPT_OID_INFO
{
| |
by: Charles Law |
last post by:
Hi guys.
I have two threads: a main thread and a background thread. Lots of stuff
happens in the background thread that means I have to update several (lots)
of controls on a form.
It is quite tiresome to have to write code to call MyControl.Invoke for each
control on the form, along with the delegates that are required for each.
Is there a better way to do this? What I mean is, if I could marshal the
|
by: stephan querengaesser |
last post by:
hi ng,
i try to invoke a webservice-method with an filter-object, that
contains value types. if i don´t want to filter the return value of
the method, i have to pass a new instance of the filter-object without
setting any properties. but the value type-properties can´t be null
and the filter is set to 0 (int) or false (bool).
therefore i did implement the propertySpecified-pattern like this:
|
by: Richard |
last post by:
Hello,
I'm working on an application to allow our network team to use a small
application to make DHCP reservations on our Microsoft DHCP Server.
The problem is you have to use P/Invoke to do it, and from what I've
found on the web and in this newsgroup is that it's not easy, however I
believe it can/has been done.
At the moment I'm just trying to find out information about an existing
|
by: balabaster |
last post by:
Does anyone know how to get a file's short pathname in 3.5? (Without p/invoke)
I've got a file compare routine that runs a diff on two directories returning the differences of every file (attributes, times, permissions, crc etc) in the tree below the two roots.
Now, if the file structure is too deep, my app can't get at the files. Obviously I can't just take the first 6 chars and append ~1 because of potential duplication of short...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
| |
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |