1

ローカル システムに DLL を登録しました。(私は所有していませんでした)

VBScript を使用して COM オブジェクトを作成し、関数を呼び出すと、すべて正常に動作します。

set Elo = CreateObject("jniwrapper.elocomserver")
Elo.refreshIntray()

しかし、C#.net を使用すると、次のようになりますNotImplementedException

NotImplementedException がスローされました。

Type javaClientComServerType = Type.GetTypeFromProgID("jniwrapper.elocomserver");
dynamic eloJavaClient = Activator.CreateInstance(javaClientComServerType);

eloJavaClient.refreshIntray();

ここで何が起こっているのか、それを修正する方法はありますか?

4

2 に答える 2

1

これは、COM-Server (JNI でラップされた Java プログラム) が利用する COM ブリッジに関連する DLR (動的言語ランタイム) を介した .NET COM 相互運用に関連する問題のようです。後者は Teamdev の ComfyJ だと思います。IDynamicMetaObjectProvider と DynamicMetaObject の実装を提供することで、この問題を回避できます。まず、以下のコードを参照してください。

using System;
using System.Collections.Generic;
using System.Text;
using System.Dynamic;
using System.IO;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Diagnostics;

class DynamicCOMObject : IDynamicMetaObjectProvider, IDisposable 
{
    private Type m_comType = null;
    private object m_comHolder = null;

    public DynamicCOMObject(string progId)
    {        
        m_comType = Type.GetTypeFromProgID(progId);
        m_comHolder = Activator.CreateInstance(m_comType);
    }

    public void Dispose()
    {
        if (m_comHolder != null)
        {
            Marshal.ReleaseComObject(m_comHolder);
            m_comHolder = null;
        }
    }

    #region IDynamicMetaObjectProvider Members
    DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(
        System.Linq.Expressions.Expression parameter)
    {
        return new DynamicCOMObjectMetaObject(parameter, this);
    }
    #endregion

    private class DynamicCOMObjectMetaObject : DynamicMetaObject
    {
        internal DynamicCOMObjectMetaObject(
            System.Linq.Expressions.Expression parameter,
            DynamicCOMObject value)
            : base(parameter, BindingRestrictions.Empty, value)
        {
        }

        public override DynamicMetaObject BindSetMember(SetMemberBinder binder,
            DynamicMetaObject value)
        {
            // Method to call in the containing class:
            string methodName = "SetValue";

            // setup the binding restrictions.
            BindingRestrictions restrictions =
                BindingRestrictions.GetTypeRestriction(Expression, LimitType);

            // setup the parameters:
            Expression[] args = new Expression[2];
            // First parameter is the name of the property to Set
            args[0] = Expression.Constant(binder.Name);
            // Second parameter is the value
            args[1] = Expression.Convert(value.Expression, typeof(object));

            // Setup the 'this' reference
            Expression self = Expression.Convert(Expression, LimitType);

            // Setup the method call expression
            Expression methodCall = Expression.Call(self,
                    typeof(DynamicCOMObject).GetMethod(methodName),
                    args);

            // Create a meta object to invoke Set later:
            DynamicMetaObject setDictionaryEntry = new DynamicMetaObject(
                methodCall,
                restrictions);
            // return that dynamic object
            return setDictionaryEntry;
        }

        public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
        {
            // Method call in the containing class:
            string methodName = "GetValue";

            // One parameter
            Expression[] parameters = new Expression[]
            {                
                Expression.Constant(binder.Name)
            };

            DynamicMetaObject getDictionaryEntry = new DynamicMetaObject(
                Expression.Call(
                    Expression.Convert(Expression, LimitType),
                    typeof(DynamicCOMObject).GetMethod(methodName),
                    parameters),
                BindingRestrictions.GetTypeRestriction(Expression, LimitType));
            return getDictionaryEntry;
        }

        public override DynamicMetaObject BindInvokeMember(
            InvokeMemberBinder binder, DynamicMetaObject[] args)
        {
            Expression[] parameters = new Expression[2];
            Expression[] subs = new Expression[args.Length];

            parameters[0] = Expression.Constant(binder.Name);

            for (int i = 0; i < args.Length; i++)
                subs[i] = args[i].Expression;

            parameters[1] = Expression.NewArrayInit(typeof(object), subs);

            DynamicMetaObject methodInfo = new DynamicMetaObject(
                Expression.Call(
                Expression.Convert(Expression, LimitType),
                typeof(DynamicCOMObject).GetMethod("CallMethod"),
                parameters),
                BindingRestrictions.GetTypeRestriction(Expression, LimitType));
            return methodInfo;
        }
    }

    public object SetValue(string key, object value)
    {
        return m_comType.InvokeMember(key,
            BindingFlags.Instance | BindingFlags.SetProperty | BindingFlags.Public,
            null,
            m_comHolder,
            new object[] { value });   
    }

    public object GetValue(string key)
    {
        return m_comType.InvokeMember(key,
            BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.Public,
            null,
            m_comHolder,
            null);          
    }

    public object CallMethod(string methodName, params object[] parameters)
    {
        return m_comType.InvokeMember(methodName,
            BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,
            null,
            m_comHolder,
            parameters);        
    }
}

使用法:

        using (dynamic client = new DynamicCOMObject("jniwrapper.elocomserver"))
        {                
            client.refreshIntray();
        }
于 2012-05-30T17:24:40.333 に答える
0

ドキュメント用です。短い方法があります:

class EloComServer : DynamicObject, IDisposable
{
    private Type javaClientType;
    private object elo;

    public EloComServer()
    {
        javaClientType = Type.GetTypeFromProgID("jniwrapper.elocomserver");
        elo = Activator.CreateInstance(javaClientType);
    }

    ~EloComServer()
    {
        this.Dispose();
    }

    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        try
        {
            result = javaClientType.InvokeMember(binder.Name,
                    BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance,
                    null, elo, args);

            return true;
        }
        catch
        {
            result = null;
            return false;
        }
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        try
        {
            javaClientType.InvokeMember(binder.Name,
                    BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance,
                    null, elo, new object[] { value });

            return true;
        }
        catch
        {
            return false;
        }
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        try
        {
            result = javaClientType.InvokeMember(binder.Name,
                    BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance,
                    null, elo, new object[0]);

            return true;
        }
        catch
        {
            result = null;
            return false;
        }
    }

    #region IDisposable Members

    public void Dispose()
    {
        if (this.elo != null)
        {
            Marshal.ReleaseComObject(elo); 
        }
    }

    #endregion
}
于 2012-05-31T07:04:12.810 に答える