x64/anycpu

Topics: General
Mar 10, 2011 at 10:22 AM

hi radioman!

for all that are struggeling with anycpu builds:

add this in your csproj and build with anycpu.
add the 2 sqlite files, set copy to output location
:)
<Choose>
    <When Condition="$(PROCESSOR_ARCHITECTURE) == 'AMD64' Or $(PROCESSOR_ARCHITEW6432) == 'AMD64'">
      <ItemGroup>
        <Reference Include="System.Data.SQLite, processorArchitecture=AMD64">
          <SpecificVersion>False</SpecificVersion>
          <HintPath>System.Data.SQLite_x64.dll</HintPath>
        </Reference>
      </ItemGroup>
    </When>
    <Otherwise>
      <ItemGroup>
        <Reference Include="System.Data.SQLite, processorArchitecture=x86">
          <SpecificVersion>False</SpecificVersion>
          <HintPath>System.Data.SQLite_x86.dll</HintPath>
        </Reference>
      </ItemGroup>
    </Otherwise>
  </Choose>


greetz
Manuel
Mar 10, 2011 at 12:34 PM

That's great!! We never think of using MSBuild for such case!!

Thanks!

Coordinator
Mar 10, 2011 at 5:25 PM

and how do you deploy this to your user? Different dll are loaded at runtime?

Mar 10, 2011 at 5:48 PM

Exactly because both files are shipped and outputed to the build drop folder.

Coordinator
Mar 10, 2011 at 5:58 PM

why i doubt this ;/

Mar 10, 2011 at 6:33 PM

Hum... you're right... this is only working when you build... So that when you're building using AnyCPU, it will output only one SQLite dll: the one that fits with your OS architecture. We need a runtime solution.

Coordinator
Mar 10, 2011 at 6:38 PM

indeed ;}

Mar 10, 2011 at 7:08 PM

I have something that works... but the code must be executed BEFORE any other assembly needs SQLite. I've placed it in my SQLiteCacheProvider static ctor. Problem is I'm using an obsolete method: AppDomain.AppendPrivatePath:

static SQLitePureImageCacheProvider()
        {

            if (IntPtr.Size == 8)
            {
                // x64
                AppDomain.CurrentDomain.AppendPrivatePath(@".\x64");
            }
            else
            {
                //x86
                AppDomain.CurrentDomain.AppendPrivatePath(@".\x86");
            }
            
        }

In my project , I have both files (x64 and x86) in sub folders as content files with the "Copy always" option enabled. So in runtime, static ctor code is executed and the runtime finds the correct assembly with the private probing path.

Its working!

 

Coordinator
Mar 10, 2011 at 7:30 PM
Edited Mar 10, 2011 at 8:08 PM

another example:

static SQLitePureImageCache()
{
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}

static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    if(args.Name.StartsWith("System.Data.SQLite, ", StringComparison.OrdinalIgnoreCase))
    {
    string dir = AppDomain.CurrentDomain.BaseDirectory + (IntPtr.Size == 8 ? "x64" : "x86") + Path.DirectorySeparatorChar;
    return System.Reflection.Assembly.LoadFile(dir + "System.Data.SQLite.dll");
    }
    return null;
}

Mar 10, 2011 at 8:02 PM

Indeed!

Coordinator
Mar 10, 2011 at 8:07 PM

...the bad side is that you can target only AnyCPU, if you use only x86 or only x64 then it fails ;/

Mar 10, 2011 at 8:22 PM

My code is working AnyCPU as well as x86 or x64. In fact, all assemblies are ALWAYS AnyCPU, the only assembly that could possibly target x86 or x64 explicitly is the EXE project like Demo.Winforms or Demo.WindowsPresentation. As all the DLLs are AnyCPU, there working in both scenario. When build EXE in x86, all the DLLs will be executed as x86 dlls. The problem is, my code is in my SQLite.CacheProvider.dll and right now, GMap.Core.dll is referencing also System.Data.SQLite.dll because of the method GetRouteFromMobileGPSLog or something like that. So my code is not executed as the GMap.Core.dll already tried to load the wrong Dll.

I'm wondering if we could move the MobileGPSLog elsewhere from the core. I'd love the GMap.Core not depending on SQLite. This way, it would be a really independant platform and developpers should pick any Cache providers the same way they would pick a Map Data Provider.

Coordinator
Mar 10, 2011 at 8:36 PM

but that means another dll, i've focused to keep the number as low as possible

Mar 11, 2011 at 12:18 PM

I agree but loosely coupled design automatically means more dlls. For example, my Map Data Providers dll. One's project will probably use only one data provider Dll. It's unlikely that a project will support Google, Bing, ArcGIS at the same time! See my project is only using Google data provider dll. So its really only one dll more. Plus the selected Cache provider dll. So that'a two... not a big deal. I was seeing the MobileGPSLog thing more like a user defined feature than a GMap.NET Core feature. Because many GMap.NET users probably don't need Mobile stuff. I know it's rather big change but GMap.NET is a very hot project and I would like it to be as much as generic and flexible as possible!

Coordinator
Mar 11, 2011 at 1:15 PM

anyway i'll put all current maps providers in core dll, using generic design it will be much easier for other people to add more providers without messing with the core functionality...

Mar 11, 2011 at 2:15 PM

Problem with this approch is that as soon as someone wants to add support for a new Map Provider, I'll need to get source code, add his provider rebuild GMap.NET and checkin back. Let's say the Data Provider is private to his company, so he cannot checkin the code in Codeplex because it's not public matter, then he will need to get GMap.NET source code and start developpement on his own. He won't get latest bug fixes and feature unless he manually merge every source files. His GMap.NET will be disconnected, that's a shame for Open Development project! Well, it's my opinion!

I think it a big drawback just for couples of Dlls that anyway only the Demo project will reference all of them...

Coordinator
Mar 11, 2011 at 2:28 PM

no, i mean, all providers you put in separate dll can be in core dll by default, any other user can build their own provider without changing core at all

Mar 11, 2011 at 2:35 PM

That's true. Hehe, I did not see it! Ok, another argument (the last one, this discussion must end ;-)): Suppose Google Maps changes their URL format and the current release of GMap.NET is not working anymore. You'll have to release all GMap.NET just for Google Map support. If Data Providers were in separate dll, you could only fix the Google Data Provider and ship it as a single download file (drop-in). Moreover, as you'll have like 20 Data Providers embedded into the Core dll, there is much more chance any of them might have breaking changes in time... But anyway, you're the project manager so its your call. I just want to try to convince you to keep my architecture.