Author | Message | Time |
---|---|---|
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:[code][DllImport("User32.dll", EntryPoint = "FindWindow")] extern "C" IntPtr FindWindow(String^ lpszWndClass, String^ lpszWndName);[/code]The compiler has this to say:[quote]error 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'[/quote]But that's exactly what MSDN claims you must do! The example MSDN provided is as follows:[code]using namespace System::Runtime::InteropServices; [DllImport("user32.dll")] extern "C" IntPtr MessageBox(int hWnd, String* pText, String* pCaption unsigned int uType);[/code]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? | February 11, 2008, 2:04 AM |
Myndfyr | 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: [code] [DllImport("user32")] extern System::IntPtr FindWindow(String^ className, String^ wndName); [/code] Usage: [code] void main() { IntPtr p; p = FindWindow(nullptr, "Test - Microsoft Visual Studio"); } [/code] Note that p is not declared with handle syntax (^) because it is a stack-type. | February 11, 2008, 3:50 PM |
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. | February 11, 2008, 6:20 PM |
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. | February 11, 2008, 6:41 PM |
Myndfyr | [quote author=Dyndrilliac link=topic=17315.msg176301#msg176301 date=1202754053] 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] 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. | February 11, 2008, 8:06 PM |