我有我想要使用的 SAP RPC OCX 控件。 在 C# 4 中,以下代码工作正常:
System.Type t = System.Type.GetTypeFromProgID("SAP.Functions", true);
dynamic fc = System.Activator.CreateInstance(t, false);
dynamic connection = fc.Connection;
connection.System = "";
以下代码不起作用(即使连接不为空)
System.Type t = System.Type.GetTypeFromProgID("SAP.Functions", true);
dynamic fc = System.Activator.CreateInstance(t, false);
var connection = fc.Connection as SAPLogonCtrl.Connection
connection.System = "";
抛出以下错误: “试图读取或写入 protected 内存。这通常表明其他内存已损坏。”
最奇怪的事实是:
System.Type t = System.Type.GetTypeFromProgID("SAP.Functions", true);
dynamic fc = System.Activator.CreateInstance(t, false);
dynamic c1 = fc.Connection;
var c2 = fc.Connection as SAPLogonCtrl.Connection;
if (c1 == c2)
c2.System = "";
最后一行被执行并抛出同样的异常!!! 用 c1 替换 c2 按预期工作...
我觉得我错过了一些微不足道的东西,但我完全不知所措...... 请帮忙?
附加信息: 更改自:
dynamic fc = System.Activator.CreateInstance(t, false);
到:
var fc = System.Activator.CreateInstance(t, false) as SAPFunctionsOCX.SAPFunctions;
没有区别。 c1 仍然有效,c2 仍然无效。
附加信息 #2: 更改 FC 本身的属性在这两种情况下也适用。
最佳答案
虽然看起来你两次都在做同样的事情,但实际上是完全不同的:在第一个代码示例中:
dynamic connection = fc.Connection;
connection.System = "";
您获得 fc.Connection
,然后使用 dynamic
调用 System =
属性 setter 。动态语言运行时运行并查询 COM 接口(interface),并调用特定 COM 接口(interface)上的特定方法。您实际上无法从 C# 方面看到它使用的是什么接口(interface)或方法。
在第二个示例中(我替换了 var
以使事情更清楚):
SAPLogonCtrl.Connection connection = fc.Connection as SAPLogonCtrl.Connection
connection.System = "";
您得到 fc.Connection
,然后将其转换为 SAPLogonCtrl.Connection
。然后您尝试调用 SAPLogonCtrl.Connection.System =
然后失败。
我怀疑它失败了,因为对象实际上不是 SAPLogonCtrl.Connection
的实例,但它可能是代理或其他一些对象。
大多数 COM 互操作被分成一个接口(interface)(很可能有一个 SAPLogonCtrl.IConnection
)和一个类。调用方法时,通常需要通过接口(interface)调用。 动态
代码将在幕后为您完成这一切。
您可以尝试搜索接口(interface),然后使用该接口(interface)进行调用。如果最终SAPLogonCtrl.IConnection
存在,解决方案可能如下。
var connection = fc.Connection as SAPLogonCtrl.IConnection // note the I!
connection.System = "";
无论如何,在处理COM互操作的时候记得通过接口(interface)调用
关于c# - 动态与类型化产生奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6140211/