• Welcome to Valhalla Legends Archive.
 

[C++/CLI] MSDN's Erroneous Interop documentation?

Started by Dyndrilliac, February 10, 2008, 08:04 PM

Previous topic - Next topic

Dyndrilliac

I've been porting some old C++ code to C++/CLI, and with that comes porting vast amounts of the Win32 Platform SDK. I instantly started having issues performing the most basic tasks according to the MSDN documentation. Example:[DllImport("User32.dll", EntryPoint = "FindWindow")]
extern "C" IntPtr FindWindow(String^ lpszWndClass,
String^ lpszWndName);
The compiler has this to say:
Quoteerror C2526: 'FindWindow' : C linkage function cannot return C++ class 'System::IntPtr'
1>        c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll : see declaration of 'System::IntPtr'
But that's exactly what MSDN claims you must do! The example MSDN provided is as follows:using namespace System::Runtime::InteropServices;
[DllImport("user32.dll")]
    extern "C" IntPtr MessageBox(int hWnd, String* pText,
    String* pCaption unsigned int uType);
I've also found that according to the compiler, '*' is an illegal indirection type for types of System::String. Is the documentation just flat-out wrong and untrustworthy, or am I missing something?
Quote from: Edsger W. DijkstraIt is practically impossible to teach good programming to students that have had a prior exposure to BASIC; as potential programmers they are mentally mutilated beyond hope of regeneration.

MyndFyre

First of all, why would you import MessageBox, when the System::Windows::Forms::MessageBox class already does that for you?

Secondly, System.String cannot be accessed via the * (pointer) operator in C++/CLI - it would be accurate I believe in MC++, but C++/CLI syntax (.NET 2.0) uses the ^ operator, for GC handles.  The appropriate decorator is String^.

Anyway, this was what I found to be the appropriate import:

[DllImport("user32")]
extern System::IntPtr FindWindow(String^ className, String^ wndName);

Usage:


void main()
{
IntPtr p;
p = FindWindow(nullptr, "Test - Microsoft Visual Studio");

}


Note that p is not declared with handle syntax (^) because it is a stack-type.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

Dyndrilliac

Well, I wasn't trying to import MessageBox - it is simply what MSDN used for their example. I just don't understand why the documentation at MSDN is so flawed. How is it that they got the C linkage specifier to work, and I couldn't, with the same code? At any rate, thanks for the suggestion. I will try leaving out the "C", as per your example. I may just go back to the system I was using, including windows.h and simply utilizing it in non-managed code. But, I've been trying to avoid all those loader-lock scenarios MSDN talks about, and figured that making my assemblies pure MSIL would do the trick and be even more helpful down the road.
Quote from: Edsger W. DijkstraIt is practically impossible to teach good programming to students that have had a prior exposure to BASIC; as potential programmers they are mentally mutilated beyond hope of regeneration.

K

If you're code isn't too low level and you want to make it all managed, I would suggest moving it over to C#.  C++/CLI is loads better than the old Managed C++, but I still wouldn't choose to use it unless you have to.

MyndFyre

Quote from: Dyndrilliac on February 11, 2008, 12:20 PM
Well, I wasn't trying to import MessageBox - it is simply what MSDN used for their example. I just don't understand why the documentation at MSDN is so flawed. How is it that they got the C linkage specifier to work, and I couldn't, with the same code? At any rate, thanks for the suggestion. I will try leaving out the "C", as per your example. I may just go back to the system I was using, including windows.h and simply utilizing it in non-managed code. But, I've been trying to avoid all those loader-lock scenarios MSDN talks about, and figured that making my assemblies pure MSIL would do the trick and be even more helpful down the road.
I think you might be looking at MC++ documentation as opposed to C++/CLI.  .NET 2.0 (the part with C++/CLI) solved the loader-lock problem, and it explains why you have String* as opposed to String^.

As K said, you should probably stick with C# if you're porting an app to managed code.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.