Something is wrong with my data marshaling

A

Andrew Falanga

Hello,

I have a solution that's purpose is to ultimately build a C# class
library for other programs to use. The C# class library must make use
of two unmanaged dlls being build in the same solution. I have post
build events for those two projects which copy the dll into the
%windows%/system32 directory.

Then using platform invoke I bring in the appropriate functions from
the unmanaged libraries using DllImport. I do this thusly:

[DllImport("Comparison.dll", CharSet = CharSet.Ansi)]
private static extern bool CheckStrings(String arg1, String arg2);

The in the code I check the return value for true or false:

bool returnVal;

if(returnVal = CheckStrings("String 1", "String 2"))
Console.WriteLine("the return was true");
else
Console.WriteLine("the return was false");

Since the dlls are being built in my solution I've turned on the
ability to debug unmanaged code. Here's where things get dicey. I
set a break point at the point where TheFunction is called and then
step into that function. I step my way through that function and then
hover over the return value variable before executing that line of
code. The return value is "false." Then, back in managed space, I
hover over "returnVal" and to my astonishment it's "true."

I can see using the debugger that the unmanaged code is going to
return "false" but then in managed space the value "true" gets
assigned. The only idea I've come up with at this point is that I'm
not marshaling something correctly. I do know that a bool in C# is 4
bytes whereas a bool in C++ is one byte. I'm wondering about this
being the issue. I've not been able to find any reasonable help in
MSDN as yet. The links I have found do talk about marshaling data, in
fact I had to "decorate" some values in structures used by these
functions with the

[MarshalAs(Unmanaged.uint8)
bool thisBool;

However, I've not found anything about how to marshal return values.
Am I on the right path with this? This just doesn't make sense to me.

If there isn't a means of marshaling a functions return value
correctly, would I want to redefine the function to return an int and
then cast the boolean value to a 4-byte wide data type?

Thanks for any help,
Andy
 
G

G Himangi

If there isn't a means of marshaling a functions return value
correctly,>>

There is - use :

[return: MarshalAs(UnmanagedType....)]
private static extern bool CheckStrings(String arg1, String arg2);
would I want to redefine the function to return an int and
then cast the boolean value to a 4-byte wide data type?
If above doesn't work, this is the way to go. However, dont redefine the
function to return 'int', use 'byte' instead since 'bool' in C++ is 1 byte.

---------
- G Himangi, LogicNP Software http://www.ssware.com
Shell MegaPack: Drop-In GUI Controls For Windows Explorer Like File And
Folder Browser Functionality
CryptoLicensing: Add licensing, copy-protection and activation to your
software
EZNamespaceExtensions: Fast and painless development of namespace extensions
EZShellExtensions: Rapid development of all shell extensions,explorer bars
and BHOs
---------



Andrew Falanga said:
Hello,

I have a solution that's purpose is to ultimately build a C# class
library for other programs to use. The C# class library must make use
of two unmanaged dlls being build in the same solution. I have post
build events for those two projects which copy the dll into the
%windows%/system32 directory.

Then using platform invoke I bring in the appropriate functions from
the unmanaged libraries using DllImport. I do this thusly:

[DllImport("Comparison.dll", CharSet = CharSet.Ansi)]
private static extern bool CheckStrings(String arg1, String arg2);

The in the code I check the return value for true or false:

bool returnVal;

if(returnVal = CheckStrings("String 1", "String 2"))
Console.WriteLine("the return was true");
else
Console.WriteLine("the return was false");

Since the dlls are being built in my solution I've turned on the
ability to debug unmanaged code. Here's where things get dicey. I
set a break point at the point where TheFunction is called and then
step into that function. I step my way through that function and then
hover over the return value variable before executing that line of
code. The return value is "false." Then, back in managed space, I
hover over "returnVal" and to my astonishment it's "true."

I can see using the debugger that the unmanaged code is going to
return "false" but then in managed space the value "true" gets
assigned. The only idea I've come up with at this point is that I'm
not marshaling something correctly. I do know that a bool in C# is 4
bytes whereas a bool in C++ is one byte. I'm wondering about this
being the issue. I've not been able to find any reasonable help in
MSDN as yet. The links I have found do talk about marshaling data, in
fact I had to "decorate" some values in structures used by these
functions with the

[MarshalAs(Unmanaged.uint8)
bool thisBool;

However, I've not found anything about how to marshal return values.
Am I on the right path with this? This just doesn't make sense to me.

If there isn't a means of marshaling a functions return value
correctly, would I want to redefine the function to return an int and
then cast the boolean value to a 4-byte wide data type?

Thanks for any help,
Andy
 
A

Andrew Falanga

If there isn't a means of marshaling a functions return value
correctly,>>

There is - use :

[return: MarshalAs(UnmanagedType....)]
private static extern bool CheckStrings(String arg1, String arg2);



 would I want to redefine the function to return an int and
then cast the boolean value to a 4-byte wide data type?



If above doesn't work, this is the way to go. However, dont redefine the
function to return 'int', use 'byte' instead since 'bool' in C++ is 1 byte.

Thanks for the help. I googled for "return marshalas boolean" and got
a great link on MSDN describing what you have above. I'm glad I was
on the right track. I redefined my function to return a byte, just as
you suggest because I knew that C++ uses a single byte for a bool.
Thanks for the insight.

Andy
 
R

Rob

See BOOL vs bool in c++
BOOL is 4 bytes afaik....

Kind regards,
Rob
www.robtso.nl

Andrew Falanga said:
If there isn't a means of marshaling a functions return value
correctly,>>

There is - use :

[return: MarshalAs(UnmanagedType....)]
private static extern bool CheckStrings(String arg1, String arg2);



would I want to redefine the function to return an int and
then cast the boolean value to a 4-byte wide data type?



If above doesn't work, this is the way to go. However, dont redefine the
function to return 'int', use 'byte' instead since 'bool' in C++ is 1 byte.

Thanks for the help. I googled for "return marshalas boolean" and got
a great link on MSDN describing what you have above. I'm glad I was
on the right track. I redefined my function to return a byte, just as
you suggest because I knew that C++ uses a single byte for a bool.
Thanks for the insight.

Andy
 
A

Arne Vajhøj

Rob said:
See BOOL vs bool in c++
BOOL is 4 bytes afaik....

In C++ as in standard C++ bool is an integer type which is at least
large enough to keep the values 0 and 1, while BOOL is not defined.

In C++ as in any recent VC++ then you are absolutely correct BOOL
is four bytes and bool is one byte.

Arne
 

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