convert WCHAR in byte[] to string

G

Guest

hi,

I import a funtion fromm dll file:

dll function header :

DWORD WINAPI
Enumerate(
HANDLE hWDMHandle,
PNDIS_STATUS pNStatus,
PWCHAR pBuffer,
PUINT pBufferSize
)

in C# should be:


[DllImport("MyAPIdll", SetLastError=true)]
private static extern unsafe ulong Enumerate (
IntPtr g_hPCASIMHandle,
ulong* pNStatus,
void* pBuffer,
uint* pBufferSize);


und aufgerufen:

[CSHARP]
byte[] buf = new byte[2024];
uint iBytesRead = 0;
ulong ioResult;
ulong ndis_status;
uint buffsize;

unsafe
{
// create a void pointer to buf
fixed (void* pBuffer = buf)
{
ioResult=Enumerate(this.m_iHandle,
&ndis_status,pBuffer,&buffsize);
}


So how can i read buf or convert it to string ?
 
W

Willy Denoyette [MVP]

centrino said:
hi,

I import a funtion fromm dll file:

dll function header :

DWORD WINAPI
Enumerate(
HANDLE hWDMHandle,
PNDIS_STATUS pNStatus,
PWCHAR pBuffer,
PUINT pBufferSize
)

in C# should be:


[DllImport("MyAPIdll", SetLastError=true)]
private static extern unsafe ulong Enumerate (
IntPtr g_hPCASIMHandle,
ulong* pNStatus,
void* pBuffer,
uint* pBufferSize);


und aufgerufen:

[CSHARP]
byte[] buf = new byte[2024];
uint iBytesRead = 0;
ulong ioResult;
ulong ndis_status;
uint buffsize;

unsafe
{
// create a void pointer to buf
fixed (void* pBuffer = buf)
{
ioResult=Enumerate(this.m_iHandle,
&ndis_status,pBuffer,&buffsize);
}


So how can i read buf or convert it to string ?

There is no need for this, but first some remarks.
1. A long in C# is a 64 bit entity in C it's 32 bit.
2. There is no need for unsafe in your declarations and your code.
3. strings in C# are w_char strings, PInvoke marshaling considers ANSI by
default, so you need to change this behavior.

Change your function declaration into:

[DllImport("MyAPIdll", SetLastError=true)]
private static extern uint Enumerate (
IntPtr g_hPCASIMHandle,
ref uint pNStatus,
[MarshalAs(UnmanagedType.LPWStr)]
StringBuilder pBuffer,
ref uint pBufferSize);

And use it as:

StringBuilder buf new StringBuilder( 2048);
uint iBytesRead = 0;
uintioResult;
uint ndis_status;
uint buffsize;

....
ioResult = Enumerate(this.m_iHandle, ref ndis_status, buf, ref buffsize);
string s = buf.ToString();

Willy.
 
G

Guest

Thanks Willy !
It works.
But i think i get only first vallue of pBuffer.
Maybe i need an array of;

StringBuilder[] buf;

How can i initializise it:
StringBuilder[] buf = new StringBuilder ....????

and:

[DllImport("MyAPIdll", SetLastError=true)]
private static extern uint Enumerate (
IntPtr g_hPCASIMHandle,
ref uint pNStatus,
[MarshalAs(UnmanagedType.LPWStr)]
StringBuilder pBuffer, // ???????
ref uint pBufferSize)


Willy Denoyette said:
centrino said:
hi,

I import a funtion fromm dll file:

dll function header :

DWORD WINAPI
Enumerate(
HANDLE hWDMHandle,
PNDIS_STATUS pNStatus,
PWCHAR pBuffer,
PUINT pBufferSize
)

in C# should be:


[DllImport("MyAPIdll", SetLastError=true)]
private static extern unsafe ulong Enumerate (
IntPtr g_hPCASIMHandle,
ulong* pNStatus,
void* pBuffer,
uint* pBufferSize);


und aufgerufen:

[CSHARP]
byte[] buf = new byte[2024];
uint iBytesRead = 0;
ulong ioResult;
ulong ndis_status;
uint buffsize;

unsafe
{
// create a void pointer to buf
fixed (void* pBuffer = buf)
{
ioResult=Enumerate(this.m_iHandle,
&ndis_status,pBuffer,&buffsize);
}


So how can i read buf or convert it to string ?

There is no need for this, but first some remarks.
1. A long in C# is a 64 bit entity in C it's 32 bit.
2. There is no need for unsafe in your declarations and your code.
3. strings in C# are w_char strings, PInvoke marshaling considers ANSI by
default, so you need to change this behavior.

Change your function declaration into:

[DllImport("MyAPIdll", SetLastError=true)]
private static extern uint Enumerate (
IntPtr g_hPCASIMHandle,
ref uint pNStatus,
[MarshalAs(UnmanagedType.LPWStr)]
StringBuilder pBuffer,
ref uint pBufferSize);

And use it as:

StringBuilder buf new StringBuilder( 2048);
uint iBytesRead = 0;
uintioResult;
uint ndis_status;
uint buffsize;

....
ioResult = Enumerate(this.m_iHandle, ref ndis_status, buf, ref buffsize);
string s = buf.ToString();

Willy.
 
W

Willy Denoyette [MVP]

centrino said:
Thanks Willy !
It works.
But i think i get only first vallue of pBuffer.
Maybe i need an array of;

StringBuilder[] buf;

How can i initializise it:
StringBuilder[] buf = new StringBuilder ....????

and:

[DllImport("MyAPIdll", SetLastError=true)]
private static extern uint Enumerate (
IntPtr g_hPCASIMHandle,
ref uint pNStatus,
[MarshalAs(UnmanagedType.LPWStr)]
StringBuilder pBuffer, // ???????
ref uint pBufferSize)

No, you don't need a StringBuilder[].
What do you mean with the first value, do you mean the first character? How
are you looking at it, don't say in the debugger.

What is the length of the string in the StringBuilder?
int len = buf.ToString().Length;

Did you check the value in pBufferSize on return?

Willy.
 
G

Guest

i get:


pBufferSize: 772
pBuffer: \Device\{91E405CA-9D5E-4366-BB44-3B27E09C6C35}

i think i would get more, i don't know !?

regards


Willy Denoyette said:
centrino said:
Thanks Willy !
It works.
But i think i get only first vallue of pBuffer.
Maybe i need an array of;

StringBuilder[] buf;

How can i initializise it:
StringBuilder[] buf = new StringBuilder ....????

and:

[DllImport("MyAPIdll", SetLastError=true)]
private static extern uint Enumerate (
IntPtr g_hPCASIMHandle,
ref uint pNStatus,
[MarshalAs(UnmanagedType.LPWStr)]
StringBuilder pBuffer, // ???????
ref uint pBufferSize)

No, you don't need a StringBuilder[].
What do you mean with the first value, do you mean the first character? How
are you looking at it, don't say in the debugger.

What is the length of the string in the StringBuilder?
int len = buf.ToString().Length;

Did you check the value in pBufferSize on return?

Willy.
 
W

Willy Denoyette [MVP]

centrino said:
i get:


pBufferSize: 772
pBuffer: \Device\{91E405CA-9D5E-4366-BB44-3B27E09C6C35}

i think i would get more, i don't know !?

regards

I guess you do have more. Your pBufferSize is 772 ( don't know what exactly,
chars or bytes), the string is shorter anyway.
I guess the buffer returned contains strings delimitted with 'nulls', like
this...
\Device\{91E405CA-9D5E-4366-BB44-3B27E09C6C35}\0\0
\Device\{..........................................................}\0\0

You can check the stringbuilders Length after return.
If I'm right, you can use ToString(int startindex, int length) to retrieve
the individual strings from the StringBuilders buffer.


Willy.
 
Top