free web page counters

Windows Mobile Pocket PC Smartphone Programming

==>Click here for the SiteMap<==. Original contents with decent amount of source codes.

Monday, April 03, 2006

Windows Mobile 5.0 New MAPI Functions Linker Error LNK2019 / LNK2001

====>SiteMap of this Blog<===

Windows Mobile 5.0 New MAPI Functions Linker Error LNK2019 / LNK2001

In Windows Mobile 5.0, a few new MAPI functions are exposed, namely:

  • MailComposeMessage
  • MailDisplayMessage
  • MailSwitchToAccount
  • MailSwitchToFolder
  • MailSyncMessages

If you have worked on MAPI, you may notice these functions are not really that much MAPI related. They are more like Outlook oriented, to facilitate developers to better control Outlooks' UI and built in forms. For example, MailComposeMessage brings up the form to compose an outgoing message, and MailDisplayMessage brings up the form to view a message. I guess the reason that Microsoft exposes these APIs is to help developers make use of Outlook in a very high level, not in the low level of MAPI coding.

I do like the two functions: MailSwitchToAccount and MailSyncMessages, as I need them for my customized transport. However, as soon as I add them to my code, I get a very puzzling linker error:

error LNK2019: unresolved external symbol "long __cdecl MailSwitchToAccount(wchar_t const *,unsigned long)" (?MailSwitchToAccount@@YAJPB_WK@Z) referenced in function _Sync

The lib file "cemapi.lib" is already added to the project's Additional Dependencies, otherwise other MAPI-related code won't even link. So the only reason is because mangled function name generated by the compiler does not match the one in the lib.

The function is declared as:

HRESULT MailSwitchToAccount( LPCTSTR pszAccount, DWORD dwFlags );

I decided to trace down to the root, so I did a "dumpbin /exports cemapi.lib" to see what name and signature should the compiler generate to appease the linker:

?MailSwitchToAccount@@YAJPBGK@Z (long __cdecl MailSwitchToAccount(unsigned short const *,unsigned long))

Aha! Do you, the reader, find the difference? Yes the mangled function names do not match, which is why the linker is not happy. But pay closer attention to the first parameter. In the source code, it is declared as LCPTSTR. My compiler compiles it to "wchar_t const *", but the compiler building the cemapi.lib makes it to "unsigned short const *"!

So here involves a change: Treat wchar_t as built-in type. VS2005 compiler changed the behavior how wchar_t is handled. The previous versions treats wchar_t as unsgined short (via Macro include), but the new compiler in VS2005 treats wchar_t as a built-in type, which is, of course, just wchar_t itself.

Apparently the people who built cemapi.lib turned the option off, which IMHO, was not a wise thing to do, as these APIs will be shipped as part of Windows Mobile 5.0 SDK, and will be used only in Visual Studio 2005 environment anyway.

To fix the issue is easy:

  • Open the project's Property Pages dialog box.
  • Click the C/C++ folder.
  • Click the Language property page.
  • Modify the Treat wchar_t as Built-in Type property.

There is also a very good blog post from Microsoft employees on the problem. The author summarized a few cases you may encounter such linker error:

  • You have created a new C++ MFC smart device project and changed the Project -> Properties -> C/C++ -> Language -> "Treat wchar_t as built in type" to "No (/Zc:wchar_t-)"
  • You have migrated an eVC project to visual Studio 2005, which links to some dependent ATL/MFC DLLs which are compiled using previous versions (like eVC3.0, eVC 4.0 or Visual Studio 2003).
  • You have migrated you eVC ATL/MFC project to Visual Studio 2005 that has no dependent DLLs, but the Project -> Properties -> C/C++ -> Language -> "Treat wchar_t as built in type" is set to "No (/Zc:wchar_t-)"

My case is exactly the second case, as I've migrated all my projects from Embedded Visual C++ 4 to Visual Studio 2005. Read my migration lessons here...

And at the end, he said "Microsoft are looking at fixing this issue". I certainly hope so!

Category: [Outlook / Transport / MAPI]

====>SiteMap of this Blog<===

[ [permalink] ]


At May 04, 2007 9:02 PM, Blogger sunisha said...


I am using MailswitchTofolder() function after creating my own folder using CreateFolder function. The folder is created inside the Inbox. The entryid being passed to the funcion seems to be correct but the view doesnt switch to my created folder.

Could you help me in finding out why it is so.


At October 31, 2007 8:35 AM, Anonymous Anonymous said...

Thanks, very helpful!


Post a Comment

Links to this post:

Create a Link

<< Home