Groups | Blog | Home
all groups > dotnet interop > february 2006 >

dotnet interop : Calling a Win32 dll problems



Jeronimo Bertran
2/7/2006 9:37:40 PM
I am having problems wiht the return type of calls to a particular dll.
The function is defined as follows in C++:


extern "C" DATREADER_API bool OpenFile(PTCHAR Name);

DATREADER_API is defined as
#define DATREADER_API __declspec(dllexport)


Now, from a C++ application I am able to use the dll using the following
project options :

/nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D
"_MBCS" /D
"_AFXDLL" /Fp"Debug/ApLector.pch" /Yu"stdafx.h" /Fo"Debug/" /Fd"Debug/" /FD
/GZ /c


I tried the following from my C# code:


[DllImport("datreader.dll")]
public static extern bool OpenFile(string name);


I am calling OpenFile the following way:

bool res = OpenFile("C:\\Data\\MyFile.DAT");

But the results is always true even when the dll returns FALSE when I use
it from the C++ project with the same string.... I tried changing the
return type on the DllImport to Int32 but the result is always a huge
number....

Thanks

Jeronimo Bertran



v-phuang NO[at]SPAM online.microsoft.com (
2/9/2006 12:00:00 AM
Hi Jeronimo,

Microsoft Specific
In Visual C++4.2, the Standard C++ header files contained a typedef that
equated bool with int. In Visual C++ 5.0 and later, bool is implemented as
a built-in type with a size of 1 byte. That means that for Visual C++ 4.2,
a call of sizeof(bool) yields 4, while in Visual C++ 5.0 and later, the
same call yields 1. This can cause memory corruption problems if you have
defined structure members of type bool in Visual C++ 4.2 and are mixing
object files (OBJ) and/or DLLs built with the 4.2 and 5.0 or later
compilers.

The __BOOL_DEFINED macro can be used to wrap code that is dependent on
whether or not bool is supported.

The problem is that ansi C defines bool as a single byte intrinsic value,
but most of windows API's (predating ansi C) return a BOOL which is a 4
byte value (a typedef), therefore the Interop team decided to marshal by
default to/from BOOL for PInvoke interop.
So we need to use Marshal instruction to tell the interop layer to marshal
it as one bytes.
I1 A 1-byte signed integer. You can use this member to transform a Boolean
value into a 1-byte, C-style bool (true = 1, false = 0).

[DllImport(@"..\..\..\debug\TestDLL.dll")]
[return:MarshalAs(UnmanagedType.I1)]
public static extern bool fnTestDLL();
private void button3_Click(object sender, EventArgs e)
{
bool rt = fnTestDLL();
MessageBox.Show(rt.ToString());
}




Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Jeronimo Bertran
2/9/2006 10:59:13 AM
v-phuang NO[at]SPAM online.microsoft.com (
2/10/2006 12:00:00 AM
Hi

You are welcomed!

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
AddThis Social Bookmark Button