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.
Although it looks like you’re doing the same thing both times, it’s actually completely different: In the first code example:
what happens is you get
fc.Connection, and then invoke theSystem =property setter usingdynamic. 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
varto make things more clear):what happens is you get
fc.Connection, and then cast it toSAPLogonCtrl.Connection. You then try and callSAPLogonCtrl.Connection.System =and then it fails.I suspect that it’s failing because the object is not actually an instance of
SAPLogonCtrl.Connectionbut 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. Thedynamiccode 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.IConnectionexists, the solution may be as follows.At any rate, remember to call through the interface when dealing with COM interop