Any CPU: Dynamically selected assembly

General discussions about GdPicture.NET.
Post Reply
Mithon
Posts: 7
Joined: Fri Jul 02, 2010 11:14 pm

Any CPU: Dynamically selected assembly

Post by Mithon » Thu Oct 28, 2010 12:47 am

I would like my application to be deployed with both native 32 and 64 bit versions of your assembly, and select the appropriate one dynamically. I do not want to build separate assemblies 32 and 64bit platforms. I had hoped you'd have an Any CPU version of your assembly, which would make this scenario very easy for me. It appears that's not the case, so I'll have to try and find out how to resolve the assembly dynamically. It appears I need help with that...

So I thought, I'll just reference both assemblies in my application. I quickly ran into build errors, which I resolved by adding assembly aliases and extern alias importing them. I then thought to use a dynamic variable to hold whichever version of the main class were selected by testing Is64BitProcess or whatever the method was named. That made it build, but uppon starting the application it broke down in the runtime. It appears that if I have any instances of classes from the 32bit assembly my application breaks down in the runtime.

So, I'm guessing I must make sure that only the correct assembly loads. I did some looking around, and it appears I could make a bootstrapper, and initialize a custom assembly resolver. It doesn't look too bad I guess, but it just seems amazing to me if there is no standardized way to do this. I mean, wouldn't this be a pretty common scenario? 32 and 64bit versions of the same namespace, and select the correct assembly!

Here are the examples I looked at describing the bootstrapper and assembly resolver:
http://stackoverflow.com/questions/1089 ... n-of-a-dll
http://stackoverflow.com/questions/1159 ... olve-event

Any insight in how to do this by turning the correct setting or whatever would be much appreciated. Thanks!

User avatar
Loïc
Site Admin
Posts: 5597
Joined: Tue Oct 17, 2006 10:48 pm
Location: France
Contact:

Re: Any CPU: Dynamically selected assembly

Post by Loïc » Thu Oct 28, 2010 10:09 am

Hi,

I have no experience with this method. We plans to produce an Any Cpu version in 2nd mid 2011.

Here what I can suggest:

Create a new exe: runme.exe. If this exe detects a 64-bit platform starts the 64-bit application from this exe, and same things for 32-bit.

Kind regards,

Loïc

Mithon
Posts: 7
Joined: Fri Jul 02, 2010 11:14 pm

Re: Any CPU: Dynamically selected assembly

Post by Mithon » Thu Oct 28, 2010 11:40 am

Loïc wrote:We plans to produce an Any Cpu version in 2nd mid 2011.
Thanks for your swift answer Loïc. That is very good news. I guess I might just live with compiling separate assemblies untill then. To me, your suggestion is basically a bootstrapper with an exe approach instead of a within-the-application approach. I'm not overly fond of either.

Like I mentioned; It seems strange to me that this should be hard to do.

Mithon
Posts: 7
Joined: Fri Jul 02, 2010 11:14 pm

Re: Any CPU: Dynamically selected assembly

Post by Mithon » Sat Nov 06, 2010 5:07 pm

Ok. So I've been looking into the problem a little more closely. As it turns out the problem is very simple: Your x86 and x64 versions of your assembly should have the same strong names. It appears they both have different assembly names (with and without the .64 postfix) as well as being signed with different keys.

The way this works is you can install two such similar dll's into the GAC side by side when they target different platforms. But when they have different strong names the clr types I reference must come from the specified strongly named assembly. Since in the GdPicture case the strong names are different, I basically have to have two separate projects where I link all the code from one project to the other and reference the two different dll's. You can hopefully see that this creates rather a mess.

When the dll's have the same strong names I can have 1 project and reference one of the dll's (from the GAC), and if I then build my project as ANY CPU, the correct GdPicture.dll will be loaded from the GAC depending on the platform the code runs on. (Install DLL's in GAC and set Copy local = False on referenced assembly for this to work in a consuming project.)

I suspect you've added the .64 postfix to be able to have both assemblies in the same solution. If this is the case, you could add different folders for the different build configurations and that way keep them in the same assembly but with the same namespace and assembly names. Signing both versions with the same key, using the same version numbers and both assemblies having the same assembly GUID are also musts.

I hope that with this information you see how you don't really have to make an ANY CPU build if that's very inconvenient. It is much more important that you align the strong names of your assemblies. Having an ANY CPU dll will of course add the benefit that we the consumers can more easily build for any cpu as we don't have to be concerned with the GAC, and can then simply include the any cpu dll in our projects directly. (We can also get around the GAC by implementing a custom dll resolver as explained in the OP, but this still requires the same strong names as described above.)

I found the following two sources of information highly illuminating:
http://blogs.msdn.com/b/gauravseth/arch ... 45104.aspx
http://www.thescarms.com/dotnet/Assembly.aspx

Thanks for reading, hopfully this was helpefull. I'm looking forward to this being fixed! :)

User avatar
Loïc
Site Admin
Posts: 5597
Joined: Tue Oct 17, 2006 10:48 pm
Location: France
Contact:

Re: Any CPU: Dynamically selected assembly

Post by Loïc » Sat Nov 06, 2010 6:19 pm

Hi dude,

I don't know of to thank you about all investigations information and you provided. So I just say thank you :)

I made first successful tests with this approach, but I have dozen of other to do indeed...
I think we will be able to provide this solution in GdPicture.NET 7.3 which will be released in December.
If I encounter any problematic situation I will let you aware.

Cheers,

Loïc

Mithon
Posts: 7
Joined: Fri Jul 02, 2010 11:14 pm

Re: Any CPU: Dynamically selected assembly

Post by Mithon » Sat Dec 25, 2010 7:10 pm

Hi Loïc,

You're very welcome. Did this make it into the 7.3 release? I didn't see it anywhere in the feature list. But then, you might not consider it a feature merely a technicality.

User avatar
Loïc
Site Admin
Posts: 5597
Joined: Tue Oct 17, 2006 10:48 pm
Location: France
Contact:

Re: Any CPU: Dynamically selected assembly

Post by Loïc » Mon Dec 27, 2010 2:25 pm

Hi,

Yes the enhancement have been included since 7.3 releases.
Let me know if any problem persisting.

Kind regards,

Loïc

Mithon
Posts: 7
Joined: Fri Jul 02, 2010 11:14 pm

Re: Any CPU: Dynamically selected assembly

Post by Mithon » Wed Jan 05, 2011 4:55 pm

Hi Löic,

Thanks for fixing this. I am happy to report that I got AnyCPU mode working well now. I didn't want to rely on the GAC for this, instead favouring a xcopy deployment. To get this working I added folders Lib\x86 and Lib\x64 with the relevant dlls, and set the reference to GdPicture.NET with Copy Local = false and uninstalled GdPicture (to remove it from the GAC). Then I implemented the following in my program.cs (bootstrapper):

Code: Select all

public static int Main(string[] args)
{
    System.AppDomain.CurrentDomain.AssemblyResolve += CustomResolve;
    
    //MyApp code...
}

private static System.Reflection.Assembly CustomResolve(object sender, System.ResolveEventArgs args)
{
    string dll = args.Name;
    if (dll.StartsWith("GdPicture"))
    {
        string myAssemblyPath= Path.GetDirectoryName(System.Reflection.Assembly.GetAssembly(typeof(MyApp)).Location);
        dll = Path.GetFullPath(String.Format(@"{0}\Lib\{2}\{1}{3}.dll", turboScanPath, dll.Substring(0, dll.IndexOf(".64")), IntPtr.Size == 8 ? "x64" : "x86", IntPtr.Size == 8 ? ".64" : ""));
        if (File.Exists(dll))
            return System.Reflection.Assembly.LoadFile(dll);
    }
    return null;
}
The IntPtr.Size == 8 is my way of checking if we're running in 64-bit mode or not, since I'm not using the version 4 of .NET framework here. Otherwise you could use the dedicated method for this.

I hope this helps somebody else who'd like the same sort of things I do.

User avatar
Loïc
Site Admin
Posts: 5597
Joined: Tue Oct 17, 2006 10:48 pm
Location: France
Contact:

Re: Any CPU: Dynamically selected assembly

Post by Loïc » Fri May 13, 2011 1:46 pm

Hi,

Just a quick update on this topic.
We have been able to create a new GdPciture.NET Core which is AnyCPU. We are now in debugging/optimization phase. So GdPicture.NET 8, which should come within 1-2 months, will be 100% AnyCPU.

Kind regards,

Loïc

Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests