我在本地系统上注册了一个动态链接库。(我并不拥有它)
当我使用VBScript创建COM对象并调用函数时,一切都很正常:
set Elo = CreateObject("jniwrapper.elocomserver")
Elo.refreshIntray()但是在使用C#.net时,我得到了一个NotImplementedException

Type javaClientComServerType = Type.GetTypeFromProgID("jniwrapper.elocomserver");
dynamic eloJavaClient = Activator.CreateInstance(javaClientComServerType);
eloJavaClient.refreshIntray();你知道这里发生了什么以及如何修复它吗?
发布于 2012-05-31 01:24:40
这似乎是一个与通过DLR (动态语言运行时)的Java互操作相关的问题,该问题与COM -服务器(通过.NET包装的Java程序所利用的)相关联。我怀疑后者是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-31 15:04:13
仅供文档使用;有一种简单的方法:
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
}https://stackoverflow.com/questions/10800461
复制相似问题