Marshalling a structure of TCHARs

J

Jared Miniman

One would think this is pretty simple, but apparently it's not. After
seeing some of the OpenNETCF guru postings, I've deemed this one too much to
tackle alone. Here is my structure in C++ land:

typedef struct _WLAN_CREDENTIALS_INFO

{

TCHAR _szUserName[UNLEN+1]; ///< User name.

TCHAR _szPassword[PWLEN+1]; ///< Password.

TCHAR _szDomain[DNLEN+1]; ///< Domain
name



} WLAN_CREDENTIALS_INFO, WLAN_CREDENTIALS_INFO,
*PWLAN_CREDENTIALS_INFO, *PWLAN_CREDENTIALS_INFO;



All I need to do is pass this structure into a native DLL call as an input
argument. What is the easiest way to push three C# strings into this
structure and then package this off to my function call?
--
_________________________________
Jared Miniman
Accenture Mobile Solutions Group

ActiveSync problems?
http://www.microsoft.com/mobile/pocketpc/support/help/activesync.asp
Connection Mngr Q's?
http://www.microsoft.com/mobile/pocketpc/tutorials/connectionmanager
 
C

Chris Tacke, eMVP

marshal a byte array of the entire length of the LAN credentials. Basically
create a wrapper class that has string properties that set/get the text at
the right byte location, then add a byte[] operator that exports the data as
a byte array, pass that to the native call and add a byte[] operator and
ctor that will create a class from a passed-in byte array.
 
J

Jared Miniman

Okay, sounds good. I'll give that a try. However, if I am sending the
native DLL a byte array when it is expecting three distinct TCHARs, how will
it know how to break the byte array into three TCHARs? Are the getters some
used auto-magically by the marshalling mechanism?

--
_________________________________
Jared Miniman
MS-MVP Mobile Devices
Accenture Mobile Solutions Group

ActiveSync problems?
http://www.microsoft.com/mobile/pocketpc/support/help/activesync.asp
Connection Mngr Q's?
http://www.microsoft.com/mobile/pocketpc/tutorials/connectionmanager

Chris Tacke said:
marshal a byte array of the entire length of the LAN credentials. Basically
create a wrapper class that has string properties that set/get the text at
the right byte location, then add a byte[] operator that exports the data as
a byte array, pass that to the native call and add a byte[] operator and
ctor that will create a class from a passed-in byte array.

--
<ctacke/>
www.OpenNETCF.org
Your CF searches start and end here


Jared Miniman said:
One would think this is pretty simple, but apparently it's not. After
seeing some of the OpenNETCF guru postings, I've deemed this one too much
to
tackle alone. Here is my structure in C++ land:

typedef struct _WLAN_CREDENTIALS_INFO

{

TCHAR _szUserName[UNLEN+1]; ///< User name.

TCHAR _szPassword[PWLEN+1]; ///< Password.

TCHAR _szDomain[DNLEN+1]; ///< Domain
name



} WLAN_CREDENTIALS_INFO, WLAN_CREDENTIALS_INFO,
*PWLAN_CREDENTIALS_INFO, *PWLAN_CREDENTIALS_INFO;



All I need to do is pass this structure into a native DLL call as an input
argument. What is the easiest way to push three C# strings into this
structure and then package this off to my function call?
--
_________________________________
Jared Miniman
Accenture Mobile Solutions Group

ActiveSync problems?
http://www.microsoft.com/mobile/pocketpc/support/help/activesync.asp
Connection Mngr Q's?
http://www.microsoft.com/mobile/pocketpc/tutorials/connectionmanager
 
P

Paul G. Tobey [eMVP]

What you'd do something like this:

class WLAN_CREDENTIALS_INFO
{
public const int szUserNameOffset = 0;
public const int szPasswordOffset = szUserNameOffset + (ULEN+1)*2;
public const int szDomainOffset = szPasswordOffset + (PWLEN+1)*2;

protected byte[] data;

public WLAN_CREDENTIALS_INFO()
{
data = new byte[ (ULEN+1)*2 + (PWLEN+1)*2 + (DNLEN+1)*2 ];
}

public String szUserName
{
get { }
set { System.Text.Encoding.Unicode.GetBytes(value, 0, value.Length,
data, szUserNameOffset ); }
}

public String szPassword
{
get { }
set { System.Text.Encoding.Unicode.GetBytes(value, 0, value.Length,
data, szPasswordOffset ); }
}

public String szDomain
{
get { }
set { System.Text.Encoding.Unicode.GetBytes(value, 0, value.Length,
data, szDomainOffset ); }
}

public static implicit operator byte[](WLAN_CREDENTIALS_INFO wl)
{
return wl.data;
}
}

I haven't shown the get() implementations, but there are *lots* of examples
of that, particularly in OpenNETCF.Net. So, what you're up to is making the
data field be the in-memory layout of the structure exactly as the C code is
going to expect it. When you call the C code, declare the parameter as
byte[] and the implicit operator will give you the data field, or declare a
public version of the call taking a WLAN_CREDENTIALS_INFO and convert it to
byte[] and call the real external function from there, if you like.

Paul T.


Jared Miniman said:
Okay, sounds good. I'll give that a try. However, if I am sending the
native DLL a byte array when it is expecting three distinct TCHARs, how
will
it know how to break the byte array into three TCHARs? Are the getters
some
used auto-magically by the marshalling mechanism?

--
_________________________________
Jared Miniman
MS-MVP Mobile Devices
Accenture Mobile Solutions Group

ActiveSync problems?
http://www.microsoft.com/mobile/pocketpc/support/help/activesync.asp
Connection Mngr Q's?
http://www.microsoft.com/mobile/pocketpc/tutorials/connectionmanager

Chris Tacke said:
marshal a byte array of the entire length of the LAN credentials. Basically
create a wrapper class that has string properties that set/get the text
at
the right byte location, then add a byte[] operator that exports the data as
a byte array, pass that to the native call and add a byte[] operator and
ctor that will create a class from a passed-in byte array.

--
<ctacke/>
www.OpenNETCF.org
Your CF searches start and end here


Jared Miniman said:
One would think this is pretty simple, but apparently it's not. After
seeing some of the OpenNETCF guru postings, I've deemed this one too much
to
tackle alone. Here is my structure in C++ land:

typedef struct _WLAN_CREDENTIALS_INFO

{

TCHAR _szUserName[UNLEN+1]; ///< User name.

TCHAR _szPassword[PWLEN+1]; ///< Password.

TCHAR _szDomain[DNLEN+1]; ///< Domain
name



} WLAN_CREDENTIALS_INFO, WLAN_CREDENTIALS_INFO,
*PWLAN_CREDENTIALS_INFO, *PWLAN_CREDENTIALS_INFO;



All I need to do is pass this structure into a native DLL call as an input
argument. What is the easiest way to push three C# strings into this
structure and then package this off to my function call?
--
_________________________________
Jared Miniman
Accenture Mobile Solutions Group

ActiveSync problems?
http://www.microsoft.com/mobile/pocketpc/support/help/activesync.asp
Connection Mngr Q's?
http://www.microsoft.com/mobile/pocketpc/tutorials/connectionmanager
 
G

Guest

Take a look at these article:

http://msdn.microsoft.com/library/d.../dnnetcomp/html/ProcessManager.asp?frame=true

http://www.opennetcf.org/PermaLink.aspx?guid=abe6694a-ff15-4617-a21f-8163d427a89c

--
Alex Yakhnin, .NET CF MVP
www.intelliprog.com
www.opennetcf.org

Jared Miniman said:
Okay, sounds good. I'll give that a try. However, if I am sending the
native DLL a byte array when it is expecting three distinct TCHARs, how will
it know how to break the byte array into three TCHARs? Are the getters some
used auto-magically by the marshalling mechanism?

--
_________________________________
Jared Miniman
MS-MVP Mobile Devices
Accenture Mobile Solutions Group

ActiveSync problems?
http://www.microsoft.com/mobile/pocketpc/support/help/activesync.asp
Connection Mngr Q's?
http://www.microsoft.com/mobile/pocketpc/tutorials/connectionmanager

Chris Tacke said:
marshal a byte array of the entire length of the LAN credentials. Basically
create a wrapper class that has string properties that set/get the text at
the right byte location, then add a byte[] operator that exports the data as
a byte array, pass that to the native call and add a byte[] operator and
ctor that will create a class from a passed-in byte array.

--
<ctacke/>
www.OpenNETCF.org
Your CF searches start and end here


Jared Miniman said:
One would think this is pretty simple, but apparently it's not. After
seeing some of the OpenNETCF guru postings, I've deemed this one too much
to
tackle alone. Here is my structure in C++ land:

typedef struct _WLAN_CREDENTIALS_INFO

{

TCHAR _szUserName[UNLEN+1]; ///< User name.

TCHAR _szPassword[PWLEN+1]; ///< Password.

TCHAR _szDomain[DNLEN+1]; ///< Domain
name



} WLAN_CREDENTIALS_INFO, WLAN_CREDENTIALS_INFO,
*PWLAN_CREDENTIALS_INFO, *PWLAN_CREDENTIALS_INFO;



All I need to do is pass this structure into a native DLL call as an input
argument. What is the easiest way to push three C# strings into this
structure and then package this off to my function call?
--
_________________________________
Jared Miniman
Accenture Mobile Solutions Group

ActiveSync problems?
http://www.microsoft.com/mobile/pocketpc/support/help/activesync.asp
Connection Mngr Q's?
http://www.microsoft.com/mobile/pocketpc/tutorials/connectionmanager
 
S

Stelrad Doulton

The answer is in your original post; there's no need for automagic as the
native structure expects 3 fixed length char arrays, not 3 char pointers. As
far as the unmanaged function is concerned it just wants a contiguous
sequence of bytes of length ([UNLEN+1] + [PWLEN+1] + _szDomain[DNLEN+1]) *
2. You may deduce that the "+1" bytes of each should be \0.



There are a couple of strategies for converting your initialised structure
into this byte array format, off the top of my head the OpenNETCF
implementation of SYSTEM_POWER_STATUS_EX2 is a good example of the strategy
referred to by Chris. You might also consider implementing an implicit
operator with the following prototype:



public static implicit operator byte[] ( _WLAN_CREDENTIALS_INFO value)



Whichever strategy you emply be sure that you byte array is of the correct
length (as indicated above) and that each piece of "member" data appears at
the correct position - Array.Copy or Buffer.BlockCopy should help you in
this.



HTHs






Jared Miniman said:
Okay, sounds good. I'll give that a try. However, if I am sending the
native DLL a byte array when it is expecting three distinct TCHARs, how
will
it know how to break the byte array into three TCHARs? Are the getters
some
used auto-magically by the marshalling mechanism?

--
_________________________________
Jared Miniman
MS-MVP Mobile Devices
Accenture Mobile Solutions Group

ActiveSync problems?
http://www.microsoft.com/mobile/pocketpc/support/help/activesync.asp
Connection Mngr Q's?
http://www.microsoft.com/mobile/pocketpc/tutorials/connectionmanager

Chris Tacke said:
marshal a byte array of the entire length of the LAN credentials. Basically
create a wrapper class that has string properties that set/get the text
at
the right byte location, then add a byte[] operator that exports the data as
a byte array, pass that to the native call and add a byte[] operator and
ctor that will create a class from a passed-in byte array.

--
<ctacke/>
www.OpenNETCF.org
Your CF searches start and end here


Jared Miniman said:
One would think this is pretty simple, but apparently it's not. After
seeing some of the OpenNETCF guru postings, I've deemed this one too much
to
tackle alone. Here is my structure in C++ land:

typedef struct _WLAN_CREDENTIALS_INFO

{

TCHAR _szUserName[UNLEN+1]; ///< User name.

TCHAR _szPassword[PWLEN+1]; ///< Password.

TCHAR _szDomain[DNLEN+1]; ///< Domain
name



} WLAN_CREDENTIALS_INFO, WLAN_CREDENTIALS_INFO,
*PWLAN_CREDENTIALS_INFO, *PWLAN_CREDENTIALS_INFO;



All I need to do is pass this structure into a native DLL call as an input
argument. What is the easiest way to push three C# strings into this
structure and then package this off to my function call?
--
_________________________________
Jared Miniman
Accenture Mobile Solutions Group

ActiveSync problems?
http://www.microsoft.com/mobile/pocketpc/support/help/activesync.asp
Connection Mngr Q's?
http://www.microsoft.com/mobile/pocketpc/tutorials/connectionmanager
 
C

Chris Tacke, eMVP

Not so much magic as simple memory layout of things. A struct is just
contiguous memory, which is simply bytes of data. The struct itself is just
a way to access it to make sense to humans. When you marshal it, it's
simply sending either an array of bytes or the address of an array of bytes
(val or ref). The nice thing about P/Invoking is that is doesn't type
check, it simply passes the byte data across and assumes that the sender and
recipient are in line with one another at the outset.

--
<ctacke/>
www.OpenNETCF.org
Your CF searches start and end here


Jared Miniman said:
Okay, sounds good. I'll give that a try. However, if I am sending the
native DLL a byte array when it is expecting three distinct TCHARs, how
will
it know how to break the byte array into three TCHARs? Are the getters
some
used auto-magically by the marshalling mechanism?

--
_________________________________
Jared Miniman
MS-MVP Mobile Devices
Accenture Mobile Solutions Group

ActiveSync problems?
http://www.microsoft.com/mobile/pocketpc/support/help/activesync.asp
Connection Mngr Q's?
http://www.microsoft.com/mobile/pocketpc/tutorials/connectionmanager

Chris Tacke said:
marshal a byte array of the entire length of the LAN credentials. Basically
create a wrapper class that has string properties that set/get the text
at
the right byte location, then add a byte[] operator that exports the data as
a byte array, pass that to the native call and add a byte[] operator and
ctor that will create a class from a passed-in byte array.

--
<ctacke/>
www.OpenNETCF.org
Your CF searches start and end here


Jared Miniman said:
One would think this is pretty simple, but apparently it's not. After
seeing some of the OpenNETCF guru postings, I've deemed this one too much
to
tackle alone. Here is my structure in C++ land:

typedef struct _WLAN_CREDENTIALS_INFO

{

TCHAR _szUserName[UNLEN+1]; ///< User name.

TCHAR _szPassword[PWLEN+1]; ///< Password.

TCHAR _szDomain[DNLEN+1]; ///< Domain
name



} WLAN_CREDENTIALS_INFO, WLAN_CREDENTIALS_INFO,
*PWLAN_CREDENTIALS_INFO, *PWLAN_CREDENTIALS_INFO;



All I need to do is pass this structure into a native DLL call as an input
argument. What is the easiest way to push three C# strings into this
structure and then package this off to my function call?
--
_________________________________
Jared Miniman
Accenture Mobile Solutions Group

ActiveSync problems?
http://www.microsoft.com/mobile/pocketpc/support/help/activesync.asp
Connection Mngr Q's?
http://www.microsoft.com/mobile/pocketpc/tutorials/connectionmanager
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top