views:

214

answers:

2

I'm trying to use late binding to connect to a COM automation API provided by a program called Amibroker, using a C# WinForms project. So far I've been able to connect to everything in the API except one item, which I believe to be a "parameterized property" based on extensive Googling.

Here's what the API specification looks like according to the docs (Full version here: http://www.amibroker.com/guide/objects.html):

Property Filter(ByVal nType  As Integer, ByVal pszCategory As String) As Long [r/w]

A javascript snippet to update the value looks like this:

AB = new ActiveXObject("Broker.Application");
AA = AB.Analysis;
AA.Filter( 0, "market" ) = 0;

Using the following C# late-binding code, I can get the value of the property, but I can't for the life of me figure out how to set the value:

object[] parameter = new object[2];
parameter[0] = Number;
parameter[1] = Type;
object filters = _analysis.GetType().InvokeMember("Filter", BindingFlags.GetProperty, null, _analysis, parameter);

So far I have tried:

  • using BindingFlags.SetProperty, BindingFlags.SetField
  • casting the returned object to a PropertyInfo object and trying to update the value using it
  • adding extra object containing the value to the parameters object
  • various other things as last-ditch efforts

From what I can see, this should be straight-forward, but I'm finding the late binding in C# to be cumbersome at best. The property looks like a method call to me, which is what is throwing me off. How does one assign a value to a method, and what would the prototype for late-binding C# code look like for it?

Hopefully that explains it well enough, but feel free to ask if I've left anything unclear. Thanks in advance for any help!

Daniel

+1  A: 

Yes, properties in COM are implemented as methods under the hood. The method name ought to be "set_Filter". I reckon the real reason you are having a problem is because you are going by the VB6 declarations. The VB6 Long type isn't actually a long in C#, it is an int. Trying to assign the property with a long value will fail.

Writing this code in VB.NET could make it a lot easier, it fully supports late-bound method and property access, using the "natural" syntax similar to Java. And supports indexed properties, unlike C#. Write a little wrapper assembly that you can reference in your C# project. It is available in C# too since VS2010 with the new dynamic keyword.

Hans Passant
Thanks Hans. You are correct that it was easiest to use VB. I wrote a quick VB application to set the Filter then I used Reflector to convert it back to C#. What I ended up with is in my answer post, which I can embed in my C# class so I don't need a second DLL assembly.Thanks for your help!
optim
A: 

Here's the VB code that converted to C#. It didn't fit in the comments to Hans.

object x = RuntimeHelpers.GetObjectValue(Interaction.CreateObject("Broker.Application", ""));
NewLateBinding.LateSetComplex(NewLateBinding.LateGet(x, null, "Analysis", new object[0], null, null, null), null, "Filter", new object[] { 0, "market", 0x22 }, null, null, false, true);

Thanks to everyone for your help!

optim