Dynamic vs Typed gives strange results

I have an SAP RPC OCX control that I would like to use. In C # 4, the following code works fine:

System.Type t = System.Type.GetTypeFromProgID("SAP.Functions", true); dynamic fc = System.Activator.CreateInstance(t, false); dynamic connection = fc.Connection; connection.System = ""; 

The following code does NOT work (although the connection is not null)

 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 = ""; 

The following error is raised: "Attempting to read or write protected memory. This often indicates that another memory is corrupt."

The most bizarre fact is that:

 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 = ""; 

The last line is completed and throws the same exception !!! Replace c2 with c1 works as expected ...

I feel that I am missing something trivial, and yet I am in complete loss ... Please help?

Additional information: Change:

 dynamic fc = System.Activator.CreateInstance(t, false); 

in

 var fc = System.Activator.CreateInstance(t, false) as SAPFunctionsOCX.SAPFunctions; 

Irrelevant. c1 is still working, and c2 is still not working.

Additional Information No. 2: Changing properties on the FC itself also works in both cases.

+7
source share
4 answers

Although it looks like you are doing the same thing both times, it is actually completely different: in the first code example:

 dynamic connection = fc.Connection; connection.System = ""; 

what happens, you get fc.Connection , and then call the System = property installer using dynamic . The runtime of a dynamic language is turned off and requests COM interfaces and calls a specific method on a specific COM interface. You cannot see which interface or method it is using from C #.

In the second example (I replaced var to make everything more clear):

 SAPLogonCtrl.Connection connection = fc.Connection as SAPLogonCtrl.Connection connection.System = ""; 

what happens, you get fc.Connection , and then drop it to SAPLogonCtrl.Connection . Then you try to call SAPLogonCtrl.Connection.System = , and then it fails.

I suspect that it does not work, because the object is not actually an instance of SAPLogonCtrl.Connection , but may be a proxy server or some other object.

Most COM connections are divided into an interface (there is most likely SAPLogonCtrl.IConnection ) and a class. When calling methods, you usually need to call the interface. The dynamic code will do everything behind the scenes for you.

You can try to find the interface and call it. If this ends up with SAPLogonCtrl.IConnection existing, the solution may be as follows.

 var connection = fc.Connection as SAPLogonCtrl.IConnection // note the I! connection.System = ""; 

Anyway, do not forget to call through the interface when working with the COM interface

+1
source

Can't you just add the actual control as a reference to your project and use it through the interaction code. Does Visual Studio create instead of trying to create it through COM and reflection?

0
source

Just an idea, but since the dynamics are not bound before runtime, while var is bound at compile time, maybe the type fc is not available for connection?

EDIT: As a side issue, is there any need to use:

var connection = fc.Connection as SAPLogonCtrl.Connection

Where you could just use:

SAPLogonCtrl.Connection connection = fc.Connection;

Am I missing something? Why are you setting it as an implicit type and then throwing it explicitly?

0
source

You must implement dynamic runs at run time, because the object and the object can take anything. This simple fact is indicated at the beginning of C # 4.0.

Note. Unusually, a dynamic type exists only at compile time; at run time, the System.Object type is used instead. This is a small implementation detail, but worth remembering, as this may clarify some of the following discussions. When you have a dynamic variable, you can go to its members (the code for actually getting the value for the variable is not shown here): myDynamicVar.DoSomething ("With this!");

Watson, Carly; Nagel, Christian; Pedersen, Jacob Hammer; Reed, John D .; Skinner, Morgan (2011-02-08). Beginning of Visual C # 2010 (Wrox programmer) (p. 414). Wrox. Kindle Edition.

0
source

All Articles