Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic vs Typed produces strange results

Tags:

c#

interop

I have SAP RPC OCX control that I'd like to use. In C# 4 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 = "";

Following code does NOT work (even though 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 = "";

Following error is thrown: "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

The most bizarre fact is this though:

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

Last line is executed and throws the same exception!!! Replace c2 with c1 works as expected...

I feel I am missing something trivial and yet I am at a complete loss... Please help?

Additional info: Changing from:

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

to:

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

Makes no difference. c1 still works and c2 still does not.

Additional info #2: Changing properties on FC itself also works in both cases.

like image 743
Michael Feinstein Avatar asked May 26 '11 14:05

Michael Feinstein


People also ask

What is the difference between static and dynamic typing?

Somewhere between traditional static typing and dynamic typing lies soft typing, which is the use of a static type system as an advisory addition to a dynamically typed language. In a soft typing system, the programmer writes his/her program as if in a dynamically typed language.

What is the difference between weak typing and dynamically typed languages?

On the other hand, weak typing supposedly has more lax type verification rules. Generally, dynamically typed languages tend to be associated with interpreted languages like Python, Ruby, Perl or Javascript, while statically typed languages tend to be compiled, like Golang, Java* or C.

What is the difference between strongly typed and weakly typed?

If a language specification requires its typing rules strongly (i.e., more or less allowing only those automatic type conversions that do not lose information), one can refer to the process as Strongly typed, if not, as Weakly typed. Type checking is all about ensuring that the program is type-safe, minimizing the possibility of type errors.

What is soft typing and dynamic typing?

Soft typing. Somewhere between traditional static typing and dynamic typing lies soft typing, which is the use of a static type system as an advisory addition to a dynamically typed language. In a soft typing system, the programmer writes his/her program as if in a dynamically typed language.


1 Answers

Although it looks like you're doing the same thing both times, it's actually completely different: In the first code example:

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

what happens is you get fc.Connection, and then invoke the System = property setter using dynamic. The dynamic language runtime goes off and queries the COM interfaces, and invokes a particular method on a particular COM interface. You can't actually see what interface or method it's using from the C# side of things.

In the second example (I've replaced the var to make things more clear):

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

what happens is you get fc.Connection, and then cast it to SAPLogonCtrl.Connection. You then try and call SAPLogonCtrl.Connection.System = and then it fails.

I suspect that it's failing because the object is not actually an instance of SAPLogonCtrl.Connection but it may be a proxy or some other object.

Most COM interop is split into an interface (there's most likely an SAPLogonCtrl.IConnection) and a class. When calling methods, you usually need to call through the interface. The dynamic code will be doing it all for you behind the scenes.

You could try searching for the interface, and calling using that. If it ends up that SAPLogonCtrl.IConnection exists, the solution may be as follows.

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

At any rate, remember to call through the interface when dealing with COM interop

like image 177
Orion Edwards Avatar answered Sep 22 '22 23:09

Orion Edwards