469,917 Members | 1,620 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,917 developers. It's quick & easy.

C# DLL marshal a struct with strings

Mo
I am having problem with marshaling struct in C#.

//the original C++ struct
typedef struct _tagHHP_DECODE_MSG
{
DWORD dwStructSize; // Size of decode
structure.
TCHAR pchMessage[ MAX_MESAGE_LENGTH ]; // decoded message data
TCHAR chCodeID; // AIM Id of symbology
TCHAR chSymLetter; // HHP Id of symbology
TCHAR chSymModifier; // Modifier characters.
DWORD nLength; // length of the decoded
message
};

//the same in C# is

public const int MAX_MESAGE_LENGTH =4096;
public const int MAX_LEN=100;

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct _tagHHP_DECODE_MSG
{
public UInt32 dwStructSize; // Size of decode structure.

//[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_MESAGE_LENGTH)]
[MarshalAs(UnmanagedType.LPStr, SizeConst=MAX_MESAGE_LENGTH)]
public string/*StringBuilder*/ pchMessage;
//MAX_MESAGE_LENGTH, decoded message data

[MarshalAs(UnmanagedType.LPStr, SizeConst=MAX_LEN)]
public string /*StringBuilder*/ chCodeID; // AIM Id of symbology

[MarshalAs(UnmanagedType.LPStr, SizeConst=MAX_LEN)]
public string /*StringBuilder*/ chSymLetter; // HHP Id of symbology

[MarshalAs(UnmanagedType.LPStr, SizeConst=MAX_LEN)]
public string /*StringBuilder*/ chSymModifier; // Modifier
characters.

public UInt32 nLength; // length of the decoded message

//this constructor is used with StringBuilder case
//public _tagHHP_DECODE_MSG(int x)
//{
//x is some unimportant value
// pchMessage=new StringBuilder(MAX_MESAGE_LENGTH);
// chCodeID=new StringBuilder(MAX_LEN);
// chSymLetter=new StringBuilder(MAX_LEN);
// chSymModifier=new StringBuilder(MAX_LEN);
// nLength=(UInt32)1;
// dwStructSize=(UInt32)1;
//}
};

the C++ DLL function is defined as

int hhpCaptureBarcode( _tagHHP_DECODE_MSG pDecodeMsg)
where
pDecodeMsg: Pointer to an _tagHHP_DECODE_MSG structure

the C# version of this function is
[DllImport("hhpImgrSdk.dll", CharSet=CharSet.Ansi)]
public static extern int hhpCaptureBarcode( ref _tagHHP_DECODE_MSG
pDecodeMsg)

> now to my problem: i know that the strings (such as pchMessage) will be written inside hhpCaptureBarcode, i.e they should ne defined
as StringBuilder, i.e i should provide a non default struct for my
struct (as u can tell, its all commented out)

the problem is, when i do that i get tow errors.

1) first error: in my app, i do
_tagHHP_DECODE_MSG decodeInfo=new _tagHHP_DECODE_MSG();

//this line gives me an error when i use StringBuilder instead of
string for
//my variables in the struct
decodeInfo.dwStructSize =
(UInt32)System.Runtime.InteropServices.Marshal.Siz eOf(decodeInfo);

The error message is
"An unhandled exception of type 'System.ArgumentException' occurred
in barcode.exe Additional information: Type _tagHHP_DECODE_MSG can not
be marshaled as an unmanaged structure; no meaningful size or offset
can be computed."

However, This doesnt happen if i use String
2) if i ignore the previous line (comment it out), and i use
StringBuilder, i get the following error message on this line

int nResult;
if ( (nResult = hhpCaptureBarcode( ref decodeInfo) == 1 ) //1 is
success

i get the following error msg

"An unhandled exception of type 'System.TypeLoadException' occurred
in barcode.exe Additional information: Marshaler restriction:
StringBuilders can not be used in structure fields.
The same effect can usually be achieved by using a String field and
preinitializing it to a string with length matching the length of the
appropriate buffer."

However, i dont get the same error when i use string, but the result
returned by hhpCaptureBarCode is 0 (nResult=0 -which indicated there
was a problem reading the barcode, i verified that the barcode works
with the demo program provided by the Vendor)
I hope i made a point


I Apprciate any help.
Thanks
Mo

ma******@hotmail.com
Nov 16 '05 #1
7 5621
"Mo" <ma******@hotmail.com> wrote in message
news:78**************************@posting.google.c om...
int hhpCaptureBarcode( _tagHHP_DECODE_MSG pDecodeMsg)
where
pDecodeMsg: Pointer to an _tagHHP_DECODE_MSG structure

the C# version of this function is
[DllImport("hhpImgrSdk.dll", CharSet=CharSet.Ansi)]
public static extern int hhpCaptureBarcode( ref _tagHHP_DECODE_MSG
pDecodeMsg)


Still working my way through your code, but this jumped out at me almost
immediately. Try declaring your DllImport like this:

[DllImport("hhpImgrSdk.dll", CharSet=CharSer.Ansi)]
public static extern int hhpCaptureBarCode(ref IntPtr pDecodeMsg);

In your code you would Marshal the data from the pointer and then cast it
back to your structure, like this:

_tagHHP_DECODE_MSG hhp_decode_msg = new _tagHHP_DECODE_MSG();
IntPtr ptr = new IntPtr();
....
hhp_decode_msg = (_tagHHP_DECODE_MSG)Marshal.PtrToStructure(ptr,
typeof(_tagHHP_DECODE_MSG));

Hope that helps.

Michael C.


Nov 16 '05 #2
Hi,
inline

"Mo" <ma******@hotmail.com> wrote in message
news:78**************************@posting.google.c om...
I am having problem with marshaling struct in C#.

//the original C++ struct
typedef struct _tagHHP_DECODE_MSG
{
DWORD dwStructSize; // Size of decode
structure.
TCHAR pchMessage[ MAX_MESAGE_LENGTH ]; // decoded message data
TCHAR chCodeID; // AIM Id of symbology
TCHAR chSymLetter; // HHP Id of symbology
TCHAR chSymModifier; // Modifier characters.
DWORD nLength; // length of the decoded
message
};
chCodeID, chSymLetter and chSymModifier are in c++ declared as TCHAR's
(*single chars*) while in c# you're making them *strings*, so what's up with
that ?
If they are infact characters use char in c#.
If they are pointers use a string with [MarshalAs(UnmanagedType.LPTStr)]
attribute.

For pchMessage you must use a string with
[MarshalAs(MarshalAs.ByValTStr,SizeConst=...)] attribute;
[DllImport("hhpImgrSdk.dll", CharSet=CharSet.Ansi)]
public static extern int hhpCaptureBarcode( ref _tagHHP_DECODE_MSG
pDecodeMsg) Drop the charset on the function signature, there are no strings in the
sign.
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] You need this and you might want to try CharSet.Unicode if it doesn't work
with Charset.Ansi.
HTH,
Greetings


//the same in C# is

public const int MAX_MESAGE_LENGTH =4096;
public const int MAX_LEN=100;

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct _tagHHP_DECODE_MSG
{
public UInt32 dwStructSize; // Size of decode structure.

//[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_MESAGE_LENGTH)]
[MarshalAs(UnmanagedType.LPStr, SizeConst=MAX_MESAGE_LENGTH)]
public string/*StringBuilder*/ pchMessage;
//MAX_MESAGE_LENGTH, decoded message data

[MarshalAs(UnmanagedType.LPStr, SizeConst=MAX_LEN)]
public string /*StringBuilder*/ chCodeID; // AIM Id of symbology

[MarshalAs(UnmanagedType.LPStr, SizeConst=MAX_LEN)]
public string /*StringBuilder*/ chSymLetter; // HHP Id of symbology

[MarshalAs(UnmanagedType.LPStr, SizeConst=MAX_LEN)]
public string /*StringBuilder*/ chSymModifier; // Modifier
characters.

public UInt32 nLength; // length of the decoded message

//this constructor is used with StringBuilder case
//public _tagHHP_DECODE_MSG(int x)
//{
//x is some unimportant value
// pchMessage=new StringBuilder(MAX_MESAGE_LENGTH);
// chCodeID=new StringBuilder(MAX_LEN);
// chSymLetter=new StringBuilder(MAX_LEN);
// chSymModifier=new StringBuilder(MAX_LEN);
// nLength=(UInt32)1;
// dwStructSize=(UInt32)1;
//}
};

the C++ DLL function is defined as

int hhpCaptureBarcode( _tagHHP_DECODE_MSG pDecodeMsg)
where
pDecodeMsg: Pointer to an _tagHHP_DECODE_MSG structure

the C# version of this function is
[DllImport("hhpImgrSdk.dll", CharSet=CharSet.Ansi)]
public static extern int hhpCaptureBarcode( ref _tagHHP_DECODE_MSG
pDecodeMsg)

>> now to my problem: i know that the strings (such as pchMessage) will be written inside hhpCaptureBarcode, i.e they should ne defined
as StringBuilder, i.e i should provide a non default struct for my
struct (as u can tell, its all commented out)

the problem is, when i do that i get tow errors.

1) first error: in my app, i do
_tagHHP_DECODE_MSG decodeInfo=new _tagHHP_DECODE_MSG();

//this line gives me an error when i use StringBuilder instead of
string for
//my variables in the struct
decodeInfo.dwStructSize =
(UInt32)System.Runtime.InteropServices.Marshal.Siz eOf(decodeInfo);

The error message is
"An unhandled exception of type 'System.ArgumentException' occurred
in barcode.exe Additional information: Type _tagHHP_DECODE_MSG can not
be marshaled as an unmanaged structure; no meaningful size or offset
can be computed."

However, This doesnt happen if i use String
2) if i ignore the previous line (comment it out), and i use
StringBuilder, i get the following error message on this line

int nResult;
if ( (nResult = hhpCaptureBarcode( ref decodeInfo) == 1 ) //1 is
success

i get the following error msg

"An unhandled exception of type 'System.TypeLoadException' occurred
in barcode.exe Additional information: Marshaler restriction:
StringBuilders can not be used in structure fields.
The same effect can usually be achieved by using a String field and
preinitializing it to a string with length matching the length of the
appropriate buffer."

However, i dont get the same error when i use string, but the result
returned by hhpCaptureBarCode is 0 (nResult=0 -which indicated there
was a problem reading the barcode, i verified that the barcode works
with the demo program provided by the Vendor)
I hope i made a point


I Apprciate any help.
Thanks
Mo

ma******@hotmail.com

Nov 16 '05 #3

Hi ,
thanks for taking the time to help me..
i did the changes that you and others specified, i got an error
(unhandled exception)
"
An unhandled exception of type 'System.NullReferenceException' occurred
in barcode.exe

Additional information: Object reference not set to an instance of an
object.
"
this is what i did,

[DllImport("hhpImgrSdk.dll",CharSet=CharSet.Ansi)]

public static extern int hhpCaptureBarcode(ref IntPtr pDecodeMsg);

i changed my structure to

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]

public struct _tagHHP_DECODE_MSG
{

public UInt32 dwStructSize; // Size of decode structure.

[MarshalAs(UnmanagedType.LPTStr)]
public String pchMessage;

public char chCodeID; // AIM Id of symbology
public char chSymLetter; // HHP Id of symbology
public char chSymModifier; // Modifier characters.
public UInt32 nLength;// length of the decoded message
};
in my code i do the following:


if ( (nResult = hhpImgrSdk.hhpImgrSdk.hhpCaptureBarcode(ref ptr) == 1)
{
//success

//i get the exception at this line
decodeInfo =
(HhpImgrCfg.HhpImgrCfg._tagHHP_DECODE_MSG)Marshal. PtrToStructure(ptr,typ
eof(HhpImgrCfg.HhpImgrCfg._tagHHP_DECODE_MSG));

}

i tried marshaling with CharSet. Unicode, .Auto,.Ansi
all gave me the same results

Any idea?

thanks
Mo

*** Sent via Devdex http://www.devdex.com ***
Don't just participate in USENET...get rewarded for it!
Nov 16 '05 #4

Hi Michael,
thanks for taking the time to help me..
i did the changes that you specified, i got an error
(unhandled exception)
"
An unhandled exception of type 'System.NullReferenceException' occurred
in barcode.exe

Additional information: Object reference not set to an instance of an
object.
"
this is what i did,

[DllImport("hhpImgrSdk.dll",CharSet=CharSet.Ansi)]

public static extern int hhpCaptureBarcode(ref IntPtr pDecodeMsg);

i changed my structure to

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]

public struct _tagHHP_DECODE_MSG
{

public UInt32 dwStructSize; // Size of decode structure.

[MarshalAs(UnmanagedType.LPTStr)]
public String pchMessage;

public char chCodeID; // AIM Id of symbology
public char chSymLetter; // HHP Id of symbology
public char chSymModifier; // Modifier characters.
public UInt32 nLength;// length of the decoded message
};
in my code i do the following:


if ( (nResult = hhpImgrSdk.hhpImgrSdk.hhpCaptureBarcode(ref ptr) == 1)
{
//success

//i get the exception at this line
decodeInfo =
(HhpImgrCfg.HhpImgrCfg._tagHHP_DECODE_MSG)Marshal. PtrToStructure(ptr,typ
eof(HhpImgrCfg.HhpImgrCfg._tagHHP_DECODE_MSG));

}

i tried marshaling with CharSet. Unicode, .Auto,.Ansi
all gave me the same results

Any idea?

thanks
Mo

*** Sent via Devdex http://www.devdex.com ***
Don't just participate in USENET...get rewarded for it!
Nov 16 '05 #5

Hi,
<inline>

"mo A" <ma******@hotmail.com> wrote in message
news:Of**************@TK2MSFTNGP10.phx.gbl...

Hi ,
thanks for taking the time to help me..
i did the changes that you and others specified, i got an error
(unhandled exception)
"
An unhandled exception of type 'System.NullReferenceException' occurred
in barcode.exe

Additional information: Object reference not set to an instance of an
object.
"
this is what i did,

[DllImport("hhpImgrSdk.dll",CharSet=CharSet.Ansi)]

public static extern int hhpCaptureBarcode(ref IntPtr pDecodeMsg);
You only need to use a IntPtr if you also want to pass null some time.
Otherwise use "ref _tagHHP_DECODE_MSG", like you first did.
If you do use an IntPtr then use it without ref (for this case).

i changed my structure to

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]

public struct _tagHHP_DECODE_MSG
{

public UInt32 dwStructSize; // Size of decode structure.

[MarshalAs(UnmanagedType.LPTStr)]
public String pchMessage;
I said you should use [MarshalAs(UnmanagedType.ByValTStr,SizeConst=....)]
for pchMessage.
HTH
Greetings


public char chCodeID; // AIM Id of symbology
public char chSymLetter; // HHP Id of symbology
public char chSymModifier; // Modifier characters.
public UInt32 nLength;// length of the decoded message
};
in my code i do the following:


if ( (nResult = hhpImgrSdk.hhpImgrSdk.hhpCaptureBarcode(ref ptr) == 1)
{
//success

//i get the exception at this line
decodeInfo =
(HhpImgrCfg.HhpImgrCfg._tagHHP_DECODE_MSG)Marshal. PtrToStructure(ptr,typ
eof(HhpImgrCfg.HhpImgrCfg._tagHHP_DECODE_MSG));

}

i tried marshaling with CharSet. Unicode, .Auto,.Ansi
all gave me the same results

Any idea?

thanks
Mo

*** Sent via Devdex http://www.devdex.com ***
Don't just participate in USENET...get rewarded for it!

Nov 16 '05 #6
What's the value of ptr at that point? Try putting a breakpoint at the line
you got the exception at, and then see what the value of ptr is at that
point. ptr may be null.

Michael C.

"mo A" <ma******@hotmail.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...

Hi Michael,
thanks for taking the time to help me..
i did the changes that you specified, i got an error
(unhandled exception)
"
An unhandled exception of type 'System.NullReferenceException' occurred
in barcode.exe

Additional information: Object reference not set to an instance of an
object.
"
this is what i did,

[DllImport("hhpImgrSdk.dll",CharSet=CharSet.Ansi)]

public static extern int hhpCaptureBarcode(ref IntPtr pDecodeMsg);

i changed my structure to

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]

public struct _tagHHP_DECODE_MSG
{

public UInt32 dwStructSize; // Size of decode structure.

[MarshalAs(UnmanagedType.LPTStr)]
public String pchMessage;

public char chCodeID; // AIM Id of symbology
public char chSymLetter; // HHP Id of symbology
public char chSymModifier; // Modifier characters.
public UInt32 nLength;// length of the decoded message
};
in my code i do the following:


if ( (nResult = hhpImgrSdk.hhpImgrSdk.hhpCaptureBarcode(ref ptr) == 1)
{
//success

//i get the exception at this line
decodeInfo =
(HhpImgrCfg.HhpImgrCfg._tagHHP_DECODE_MSG)Marshal. PtrToStructure(ptr,typ
eof(HhpImgrCfg.HhpImgrCfg._tagHHP_DECODE_MSG));

}

i tried marshaling with CharSet. Unicode, .Auto,.Ansi
all gave me the same results

Any idea?

thanks
Mo

*** Sent via Devdex http://www.devdex.com ***
Don't just participate in USENET...get rewarded for it!

Nov 16 '05 #7
Hi BMermuys,
Thanks man.. i got it all to work
really appreciate it

Regards
*** Sent via Devdex http://www.devdex.com ***
Don't just participate in USENET...get rewarded for it!
Nov 16 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by Daniel Brown | last post: by
1 post views Thread by jurot | last post: by
1 post views Thread by Waqarahmed | last post: by
reply views Thread by Salome Sato | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.