问题描述
||
我有要使用的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\",false);
var connection = fc.Connection as SAPlogonCtrl.Connection
connection.System = \"\";
引发以下错误:
\“试图读取或写入受保护的内存。这通常表明其他内存已损坏。”
最奇怪的事实是:
System.Type t = System.Type.GetTypeFromProgID(\"SAP.Functions\",false);
dynamic c1 = fc.Connection;
var c2 = fc.Connection as SAPlogonCtrl.Connection;
if (c1 == c2)
c2.System = \"\";
最后一行被执行并引发相同的异常!!!
按预期将c2替换为c1 ...
我觉得自己缺少了一些琐碎的东西,但我完全不知所措...
请帮忙?
附加信息:
从:
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 =
属性设置器。动态语言运行时关闭并查询COM接口,并在特定的COM接口上调用特定的方法。从C#方面,您实际上看不到它在使用什么接口或方法。
在第二个示例中(为了使情况更清楚,我替换了ѭ9):
SAPLogonCtrl.Connection connection = fc.Connection as SAPLogonCtrl.Connection
connection.System = \"\";
发生的情况是您得到fc.Connection
,然后将其投放到SAPLogonCtrl.Connection
。然后,您尝试呼叫SAPLogonCtrl.Connection.System =
,然后失败。
我怀疑它失败了,因为该对象实际上不是SAPLogonCtrl.Connection
的实例,但它可能是代理或某些其他对象。
大多数COM互操作都分为一个接口(最有可能是SAPLogonCtrl.IConnection
)和一个类。调用方法时,通常需要通过接口进行调用。 dynamic
代码将在后台为您完成所有操作。
您可以尝试搜索该接口,然后使用该接口进行调用。如果最后发现ѭ15,则解决方法如下。
var connection = fc.Connection as SAPLogonCtrl.IConnection // note the I!
connection.System = \"\";
无论如何,请记住在处理COM互操作时通过接口进行调用
,您是否可以不只是将实际控件添加为对您项目的引用并通过Visual Studio创建的互操作代码来使用它,而不是尝试通过COM和反射来创建它?
,这只是一个主意,但由于动态功能直到执行时才绑定,而var则在编译时绑定,是否可能是fc类型无法用于连接?
编辑:作为附带问题,是否有任何需要使用:
var connection = fc.Connection as SAPLogonCtrl.Connection
您可以使用的地方:
SAPLogonCtrl.Connection连接= fc.Connection;
我想念什么吗?为什么要将其设置为隐式类型然后显式转换它?
,您必须在运行时意识到动态运行是一个对象,而对象可以接受任何东西。在开始C#4.0中指出了这个简单的事实
注意通常情况下,动态类型仅在编译时存在。在运行时,改用System.Object类型。这是次要的实现细节,但值得记住,因为它可以澄清后面的一些讨论。一旦有了动态变量,就可以继续访问其成员(此处未显示实际获取变量值的代码):myDynamicVar.DoSomething(“ With this!”);
沃森(Karl);内格尔,基督徒; Pedersen,Jacob Hammer;里德,乔恩D。摩根·斯金纳(2011年2月8日)。从Visual C#2010开始(Wrox程序员到程序员)(第414页)。约克Kindle版。