[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 368
  • Last Modified:

converting Windows-DLL to Pocket PC-DLL

Hi!

I have the feeling, I'm trying to do the impossible...
So goal is to convert a DLL written for Windows OS to a DLL for the Pocket PC OS.
I'm using Visual Studio 2005 (C++)

Ok, the Original code had Multi-Byte Character Set. When I'm leaving it that way and making some changes in the code, it compiles BUT brigs up tons of unresolved Symbols, like
 error LNK2001: unresolved external symbol LoadStringA
error LNK2001: unresolved external symbol GetTempPathA
end so on (about 200 unresolved symbols)

When I change to Unicode, then the whole code does not compile, as I have chars everywhere!

Must I use Unicode? If not, what's with all the unresolved Symbols?

Thanks
0
hlienert
Asked:
hlienert
  • 5
  • 3
  • 2
  • +1
1 Solution
 
jkrCommented:
It seems that you are compiling with the 'regular' SDK header files, but linking with the PocketPC libs. Don't they come with their own set of headers? (The 'regular' SDK headers append either 'A' or 'W' when compiled as ANSI or UNICODE)
0
 
hlienertAuthor Commented:
Thanks 4 the reply!
Ok, I'm now a little more confused. For example:

THE ERROR: unresolved external symbol lstrcpyA
THE CODE: lstrcpy(fname, file_path);
THE Declaration of lstrcpy, as shown by the Studio: #define lstrcpy lstrcpyA
THE File containing this declaration: f:\programme\microsoft visual studio 8\smartdevices\sdk\pocketpc2003\include\winbase.h
THE LIB Linking: No Idea!!

Think you can help me out a little more?
0
 
jkrCommented:
Hm - right at this point, I am stumped. The 'per #define' translatoin of the API names was what I thought to be the problem. When you take a look at the .libs with e.g. 'lib.exe. or 'dumpbin.exe', what does that reveal?
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
Deepu AbrahamR & D Engineering ManagerCommented:
Can you get hold of Embedded VC++ from Microsoft Site?

http://www.microsoft.com/downloads/details.aspx?FamilyID=1dacdb3d-50d1-41b2-a107-fa75ae960856&DisplayLang=en

You can use this EVC++ IDE for pocket pc application development by just selecting pocket pc (sdk) (or whichever is the target platform) in project settings before building it. Also you will get the SDK functions help in the IDE itself provided you install the pocket pc SDK which is also avaliable in microsoft site for download.

Please let us know if you are not able to build your application with 0 errors.

Best Regards,
DeepuAbrahamK
0
 
Mikeh926Commented:
Hi,
The problem is that most of the ANSI functions (the ones that end in A) do not exist on the Pocket PC. MS stripped them out of the libraries to save memory. Unfortunately, they are still defined in the SDK headers. I think this is because the WM SDK headers are based upon the NT SDK and MS in their infinite wisdom did not remove the functions that do not exist. If you start looking closely at the Mobile SDK, you will find functions documented that don't exist, functions in the header files that do exist but are not documented, structures that are just wrong, missing #defines, and a whole bunch of other problems!

So, you don't have UNICODE defined, lstrcpy maps to lstrcpyA which although it exists in the headers, does not exist in any Pocket PC library, thus you get a linker error.

There are only a couple of ways you can fix this. One, is to convert your code to Unicode. This has the advantage that the same source should still compile for XP and is the solution that I would recommend. Another is to write some wrappers to convert all of the ANSI calls to UNICODE calls for the Pocket PC. In other words, create your own version of lstrcpyA(). You might be able to get source code for these missing functions from the WIN32 runtime library source.

Regards,
Mike.
0
 
hlienertAuthor Commented:
@ Mikeh926: I was afraid of that... Looks like u are right. I have to use the Unicode Calls, at least for those functions.
Can you give me some example, on how could I write my own version of lstrcpy?
If I change the whole project to Unicode, do I have to change everything (about 2000 errors) one by one, or is there a way, for instance converting all the chars* to wchar_t * (not even sure if that's right, as I never used Unicode before)?

@DeepuAbrahamK: I had EVC++ already on my system, did not get to import the XP Project, that's why using Visual Studio.
Now I had tested something: Started a new Project in EVC++. Used just this code:
      char fname[2048];
      lstrcpyA(fname, "bla");
Compiled->unresolved external.  The code
      wchar_t fname[2048];
      lstrcpyW(fname, "bla");
Compiles fine, no errors.

Thank you all.
0
 
Mikeh926Commented:
Well, there might be a way for you to keep using ANSI functions and reduce your errors.

lstrcpy() is a Windows API function, which is exported as lstrcpyA and lstrcpyW. It's the lstrcpyA that MS removed to save space. However, the CE runtime library has strcpy(). You could just use strcpy() instead of lstrcpy(). strcpyA() and strcpyW() are part of the CE runtime library and do exist on CE.

So, if you go through and change any windows API calls to run time library calls, you might reduce your error list. The CE runtime library does support ANSI string handling.

You will still have to convert any calls to W functions in the OS., so you would need code something like this (as a simplfied example, SetWindowTextA()):

BOOL SetWindowTextA(HWND hwnd,LPCSTR *str)
{
int len = MultiByteToWideChar(CP_ACP,0,str,-1,NULL,0);
WCHAR *wstr = new WCHAR[len+1];
MultiByteToWideChar(CP_ACP,0,str,-1,wstr,len+1);
wstr[len] = 0;
BOOL ret = SetWindowTextW(hwnd,wstr);
delete wstr;
return(ret);
}





0
 
hlienertAuthor Commented:
Ok Mikeh926, u're getting the points, as you really managed to explain everything I needed to understand my problem!
:)
Now I do have one last question.

Defined for example in the Header "Conversions.h"

#include <windows.h>
DWORD CharLowerBuffA(LPTSTR lpsz,DWORD cchLength);

Then in "Conversions.cpp"

DWORD CharLowerBuffA(LPTSTR lpsz,DWORD cchLength)
{
      int len = MultiByteToWideChar(CP_ACP,0,lpsz,-1,NULL,0);
      WCHAR *wstr = new WCHAR[len+1];
      MultiByteToWideChar(CP_ACP,0,lpsz,-1,wstr,len+1);
      wstr[len] = 0;
      DWORD ret = CharLowerBuffW(wstr,cchLength);
      delete wstr;
      return(ret);
}

Now I get

error C2373: 'CharLowerBuffA' : redefinition; different type modifiers
error C2491: 'CharLowerBuffA' : definition of dllimport function not allowed

Any Idea?
0
 
hlienertAuthor Commented:
Ok, I changed the code in the Conversions.h and renamed the function in the Conversions.cpp:

#undef CharLowerBuff
#define CharLowerBuff MyCharLowerBuffA
DWORD MyCharLowerBuffA(LPTSTR lpsz,DWORD cchLength);

Now it's ok!
:)
0
 
Mikeh926Commented:

One final point, don't assume that the length of an ansi string is the same as a wchar string after conversion by MultiByteToWideChar. In your CharLowerBuffA you should pass len to CharLowerBuffW, not cchLength.

Also, that function converts the characters in-place, so you would need to convert the resulting buffer back to ansi with WideCharToMultiByte afterwards, overwriting your original lpsz string.

Regards,
Mike.
0
 
hlienertAuthor Commented:
Right!

Thanks again!
0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

  • 5
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now