views:

74

answers:

2

I have created a simple GUI using Windows Forms in visual C++ 2008. There is a button in the GUI. When the button is pressed I want mouse cursor to point at coordinates (0,900). I have created separate header and c++ source file that sets the cursor position to specified location (x,y). For this I have used Win32's SetCursorPos() function. I wrote the code for setting the cursor position in a separate file because I want only the GUI to be built using .NET. For other functions I want to use native C++ and Win32 library.

While building the code, I get following error messages at the time of linking:

1>SimpleForms.obj : error LNK2028: unresolved token (0A00000F) "extern "C" int __stdcall SetCursorPos(int,int)" (?SetCursorPos@@$$J18YGHHH@Z) referenced in function "private: void __clrcall SimpleForms::Form1::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click@Form1@SimpleForms@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)

1>SimpleForms.obj : error LNK2019: unresolved external symbol "extern "C" int __stdcall SetCursorPos(int,int)" (?SetCursorPos@@$$J18YGHHH@Z) referenced in function "private: void __clrcall SimpleForms::Form1::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click@Form1@SimpleForms@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)

plz help me rectify errors

+1  A: 

You can't do that.

If you want to use C++ from .NET, you must expose a C interface to .NET which you can P/Invoke, or you need to use C++/CLI instead, which will result in managed code. (Well, I suppose you could expose a COM element as well, but thats a whole other can of worms)

This sounds like you're just asking for difficulty -- is there any reason you don't want to use either completely managed code, or completely native code? Getting them to mix is a royal PITA.

Billy ONeal
Actually the main program that I need to develop is performance-oriented. So I wanted to code the complex algorithms using native C++ and win32 libraries. For building GUI .NET is an easy option. So I thought of merging the two options. Seems that I will have to look for other feasible alternatives.
nishant
@nishant: That said, the workload of doing the P/Invokes across the native/managed barrier is probably much more overhead than you'd save by writing the main parts of the program in native code. If you need native speed, just `ngen` the libraries on the target machine before running them.
Billy ONeal
@Billy: Thnx for your suggestion my friend!! I will surely try this.
nishant
@Billy: C++ interop is even faster than p/invoke, and the BCL is full of p/invoke calls. For example, the `Cursor::Position` property suggested by Hans is implemented with a security check followed by a call to `SetCursorPos` in user32.dll.
Ben Voigt
+2  A: 

(?SetCursorPos@@$$J18YGHHH@Z)

Note how the function name got the C++ name decoration. Your declaration of the function is wrong, using extern "C" is required. Avoid these kind of mistakes by simply including <windows.h>.

But, don't do it this way. Windows Forms lets you move the cursor too:

    System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
        System::Windows::Forms::Cursor::Position = Point(0, 900);
    }

I was seriously misled by the name decoration, that's an unpleasant linker error message. The real problem is that your project isn't linking the required Windows import library. Right-click the project, Properties, Linker, Input. Remove the $(NoInherit) from the Additional Dependencies setting. If you use VS2010 then put "user32.lib" in that setting.

You should still use the .NET Cursor class in this specific case.

Hans Passant
@Hans thats what I have done. I have included <windows.h> and I am using its SetCursorPos() function. I havent coded SetCursorPos() on my own.
nishant
I dunno, you'll have to post repro code to let us diagnose that. It certainly isn't normal.
Hans Passant
Earlier I wrote the code for setting the mouse position in a separate file as I have described in the main problem. But now I have integrated it in Form1.h file itself. I have included windows.h at the beginning of Form1.h. And thn in the click event of the button I have called SetCursorPos() function.
nishant
@hans you can see the code here: http://paste.pocoo.org/show/260035/
nishant
@nish - answer updated with the likely cause of the problem.
Hans Passant
@hans thanx man !! prob solved..
nishant
@nish - are you sure you selected the correct answer? There's another one with 2 helpful votes, this one has none. Please remove the check mark so I can delete it.
Hans Passant
@hans my prob got solved by linking user32.lib as you described..
nishant
@Hans: This definitely is the right answer, listing user32.lib in the linker inputs configuration is needed to resolve the call.
Ben Voigt
@Ben - I'm experimenting with different ways to get out of the doldrums of having well over 300 answers that are marked answered without a helpful vote. That's an unbeaten record at SO. I'm about to write off this particular approach, the OP removed the answer mark, then upvoted it. Fail. The notion of good answers also being helpful is remarkably opaque to many SO users. I have yet to understand the way they think. Working on it, although not quite sure I'd really like the answer.
Hans Passant