开发者

Architecture-Specific Eclipse Plug-in Fragments

I need to target both win32.x86 and win32.x86_64 architectures when building an RCP plug-in that uses OS.getRegOpenKey(...). The types of the arguments for the method are different for the two architectures.

I understand now that there is no straightforward way to have an x86 or x86_64 fragment (depending upon the build) override a method in my host plug-in.

However, from this post it sounds like a fragment can, for example, add a class that extends a class in the host. And the host plugin can then explicitly use the ClassLoader to find and instantiate the correct subclass from the fragment 开发者_开发知识库included in that architecture's build. What would this look like?


Based on the linked-to post, this is what I have so far (builds without error now for both architectures, and I just need to see if the built 64-bit app will run on 64-bit Windows!):

Use Eclipse's fragment plug-in wizard to create the x86 and x86_64 fragments. The manifests have a couple of extra lines manually added. For example, the important bits of the x86_64 fragment's Manifest.mf:

...
Bundle-SymbolicName: com.company.product.win32.x86_64;singleton:=true
Fragment-Host: com.company.product.win32;bundle-version="1.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Eclipse-PlatformFilter: (& (osgi.os=win32) (osgi.arch=x86_64))
Bundle-ClassPath: src/,. 

Then, added subclass to the fragment (used the same package name as the super class from the host plug-in, but that probably isn't necessary):

package com.company.product.win32;

import org.eclipse.swt.internal.win32.OS;
import org.eclipse.swt.internal.win32.TCHAR;

/**
 * Subclass the host's abstract OSUtilities
 */
public class OSUtilities64 extends OSUtilities {

    public String getRegKeyValue (String path, String key) {
         long [] phkResult = new long [1];
         if (OS.RegOpenKeyEx ((long) OS.HKEY_LOCAL_MACHINE, new TCHAR(0, path, true), 
             0, OS.KEY_READ, phkResult) != 0) {
    ...

Same for the OSUtilities32 class.

Added the fragments to the feature.xml containing the host plug-in:

   <plugin
     id="com.company.product.win32"
     os="win32"
     download-size="0"
     install-size="0"
     version="0.0.0"
     unpack="false"/>
   <plugin
     id="com.company.product.win32.x86"
     os="win32"
     arch="x86"
     download-size="0"
     install-size="0"
     version="0.0.0"
     fragment="true"
     unpack="false"/>
   <plugin
     id="com.company.product.win32.x86_64"
     os="win32"
     arch="x86_64"
     download-size="0"
     install-size="0"
     version="0.0.0"
     fragment="true"
     unpack="false"/>

Then the host plug-in can statically load the appropriate, available class:

/**
 * Get class from appropriate fragment
 */
public static OSUtilities getOSUtilities() {
    ClassLoader loader = OSUtilities.class.getClassLoader();
    try {
        Class<?> cls;
        try {
            cls = loader.loadClass("com.company.product.win32.OSUtilities32");
        } catch (ClassNotFoundException e) {
            cls = loader.loadClass("com.company.product.win32.OSUtilities64");
        }
        OSUtilities util = (OSUtilities) cls.newInstance();
        return util;

I should use the architecture system property to pick which to instantiate -- later.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜