Tech Off Thread

11 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

"Any CPU" - Is it evil?

Back to Forum: Tech Off
  • User profile image
    lensman

    Having recently upgraded to a 64 bit system, I encountered a problem of which I was ignorant before.  The default setting of a Visual Studio project is "Any CPU".  On a 64 bit system this means the program will automatically run as a 64 bit application.  On a 32 bit system it will automatically run as a 32 bit application.  This sounds ideal.

     

    Problem #1:  Data residing in "legacy" data sources such as Excel documents, Access data, or third party databases must run as 32 bit clients.  The "Any CPU" setting causes the previously working code to stop working.  Changing your application to 32 bit enables this code to work again.

     

    Problem #2:  Third party DLL's, which are 32 bit in nature, cannot be accessed from 64 bit clients.  I have yet to see any workarounds for this that actually work.  Apparently .NET DLL's will auto-adjust if compiled with "Any CPU" and called from a 32 bit or 64 bit host client.

     

    Problem #3:  The Click Once deployment process seems to be broken.  Applications deployed in the field, which used "Any CPU" cannot be updated.  Changing your program to "32 bit" (or 64 bit) and pressing "publish" warns you that your version differs than your previous publish.  If you actually tell it to go ahead your clients will lose all linkage to your project and require manual uninstall/re-installs.

     

    As a temporary workaround I have started coding all my deployed code, which requires 32 bit data access, as a 32 bit application.  I am no longer using the "Any CPU" setting on applications. Legacy programs deployed already, with the "Any CPU" option, are left in the "Any CPU" setting knowing that it will break on 64 bit systems. 

     

    I would prefer to put all my legacy 32 bit code into a DLL however that quickly renders it useless as 64 bit clients appear to have no means of communicating with 32 bit code. 

     

    I have yet to come up with any solution to my deployment problems.

     

    Does anyone have some advice on these or similar problem?

  • User profile image
    W3bbo

    This is why you should choose this carefully before deploying Smiley. But yes, x86 processes cannot load x64 code into themselves, and vice-versa.

     

    Techncially there is a workaround: to load the 32-bit stuff into its own process and use some kind of IPC to exchange data, but you'll go through hell getting any kind of object graph working with IPC. You're best sticking with the 32-bit option, the benefits of x64 JIT compilation probably won't be felt in your application.

  • User profile image
    BitFlipper

    Yes I was bitten by this when we tested our project on 64-bit systems. We P/Invoke into native libraries (our own libraries), and had to specifically set the project to only run as 32-bit. I guess we can build 64-bit native libraries too but since we don't really get any benefit from going 64-bit it was easier to just force the managed library to 32-bit only.

     

    I have read rumors that 4.0 will have better support for this kind of stuff when using P/Invoke. It would be great if the P/Invoke mechanism can automatically insert a 32<>64 bit thunking layer when it detects a mismatched P/Invoke call. Although I am not sure how difficult this would be to pull off.

     

    I also hope they fully implement reverse P/Invoke . This will allow us to write managed C# plugins that can be called from unmanaged code without a managed C++ intermediate assembly.

  • User profile image
    PerfectPhase

    I think they change the default target in 2010 to x86 for just this reason.

  • User profile image
    contextfree

    Unfortunately, I've had to build almost all our code in 32-bit for this reason.  I would eventually like to isolate all our third-party native components in separate processes, but there hasn't been time to do this.

  • User profile image
    LeoDavidson

    I would prefer to put all my legacy 32 bit code into a DLL however that quickly renders it useless as 64 bit clients appear to have no means of communicating with 32 bit code.

    You can do it, you just need a 32-bit process to load the 32-bit DLLs on your behalf and then act as a proxy between your main 64-bit process and the DLLs.

     

    Obviously, how well this works depends on what the DLLs do. If the DLLs require that lots of pointers and complex data structures be passed in and out of them then you have to write a lot of marshalling glue. If not, though, it's very easy.

     

    In C++ code, I've used COM to get all the marshalling I need for free. COM knows how to call across the 32/64-bit boundary between processes, converting arguments appropriately. (You're already unable to share pointers across processes so the 32/64-bit issue doesn't change things there.)  I'm not sure what the best approach for .Net code is, though.

     

  • User profile image
    lensman

    LeoDavidson said:

    *snip*

    You can do it, you just need a 32-bit process to load the 32-bit DLLs on your behalf and then act as a proxy between your main 64-bit process and the DLLs.

     

    Obviously, how well this works depends on what the DLLs do. If the DLLs require that lots of pointers and complex data structures be passed in and out of them then you have to write a lot of marshalling glue. If not, though, it's very easy.

     

    In C++ code, I've used COM to get all the marshalling I need for free. COM knows how to call across the 32/64-bit boundary between processes, converting arguments appropriately. (You're already unable to share pointers across processes so the 32/64-bit issue doesn't change things there.)  I'm not sure what the best approach for .Net code is, though.

     

    What do you mean by "proxy"?  If I have a seperate process load the 32 bit dll, do I not still have the same problem?  How do I communicate with the 32 bit process from 64 bit process?

     

  • User profile image
    W3bbo

    lensman said:
    LeoDavidson said:
    *snip*

    What do you mean by "proxy"?  If I have a seperate process load the 32 bit dll, do I not still have the same problem?  How do I communicate with the 32 bit process from 64 bit process?

     

    There are a variety of different methods of IPC you can use when processes have a different bit-ness. I don't know how well Shared Memory IPC works, but there's always IPC COM.

  • User profile image
    LeoDavidson

    lensman said:
    LeoDavidson said:
    *snip*

    What do you mean by "proxy"?  If I have a seperate process load the 32 bit dll, do I not still have the same problem?  How do I communicate with the 32 bit process from 64 bit process?

     

    COM can make calls to objects hosted in other processes (i.e. out-of-process objects). When doing so it doesn't matter if either/both processes are 32/64 bit or not; COM handles the details for you.

     

    You could also use other IPC mechanisms like pipes, shared memory, etc. but the beauty of the COM method is that you get all the marshalling code for free and if you're already using COM then you don't have to change much.

     

    COM isn't always the best way to do it, of course, but it often is.

     

  • User profile image
    Sven Groot

    LeoDavidson said:
    lensman said:
    *snip*

    COM can make calls to objects hosted in other processes (i.e. out-of-process objects). When doing so it doesn't matter if either/both processes are 32/64 bit or not; COM handles the details for you.

     

    You could also use other IPC mechanisms like pipes, shared memory, etc. but the beauty of the COM method is that you get all the marshalling code for free and if you're already using COM then you don't have to change much.

     

    COM isn't always the best way to do it, of course, but it often is.

     

    You could also have a main 64 bit .Net process, and a 32 bit .Net process doing the interop, and then have the two communicate via .Net Remoting or WCF. It's pretty easy to set up.

  • User profile image
    LeoDavidson

    Sven Groot said:
    LeoDavidson said:
    *snip*

    You could also have a main 64 bit .Net process, and a 32 bit .Net process doing the interop, and then have the two communicate via .Net Remoting or WCF. It's pretty easy to set up.

    .Net Remoting definitely makes more sense than COM for .Net projects. I forgot all about it, even though I've used it. It's great and, like you say, really easy to use.

     

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.