c# - 动态与类型化产生奇怪的结果

标签 c# interop

我有我想要使用的 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/

相关文章:

c# - 如何将可枚举类型转换为 AsyncEnumerable 类型?

c# - winform c#中的弹出窗口

c# - 扩展方法和接口(interface)

c# - 如何最好地将文件读入列表<string>

c# - 线程同步 XNA 网络

c# - 如何为使用 ilasm 生成的 Interop DLL 设置文件版本

java - 使用 IKVM.NET 的经验

c# - 使相应的 native 和托管枚举保持同步的技术

java - 将包含 boolean 值的 Scala 映射转换为包含 java.lang.Boolean 的 Java 映射

c# - C# 是否强制 `unmanaged` 类型为 "blittable"?