I've a COM object for some simple mathematical utilities. Amongst others, it exports 2 interfaces - the IDL is as follows:
interface IUnivariateFunction : IDispatch
{
HRESULT evaluate([in] double a, [out, retval] double* b);
};
interface IOneDimSolver : IDispatch
{
HRESULT Solve([in] double min, [in] double max, [in] double targetAccuracy, [in] LONG maxIterations, [in] IUnivariateFunction* function, [out, retval] double* result);
};
And then an implementation of IOneDimSolver is:
coclass Brent
{
[default] interface IOneDimSolver;
};
If I want to use this object in C# and I have the TypeLibrary available, using this functionality is very easy - I can implement some function to solve:
public class CalculatePi : IUnivariateFunction
{
public double evaluate(double x)
{
return x - Math.PI;
}
}
And then use it:
var brent = new Brent();
var result = brent.Solve(-10.0, 10.0, 1E-10, 100, new CalculatePi());
This works really well, so no issues there. However, I also want to demonstrate that I can use it with late binding (almost purely for academic purposes at this point).
var brent = Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")));
var result = brent.GetType().InvokeMember("Solve", BindingFlags.InvokeMethod, null, brent, new object[] { -10.0, 10.0, 1E-10, 100, new CalculatePi() });
It looks like the brent object is being created OK, but the call to InvokeMember fails with the message {"Specified cast is not valid."}
I'm guessing the type of CalculatePi isn't compatible with whatever the COM IDispatch machinery is expecting, but I'm just not sure how to make it work. Any help would be great!
dynamickeyword with COM late binding, it's much easier, likedynamic brent = /*create instance*/; var result brent.Solve(-10.0, 10.0, 1E-10, 100, new CalculatePi());. If this still doesn't work, how is IDispatch implemented? The IOneDimSolver interface is probably useless, late binding will use only IDispatch.dynamicis much better! Unfortunately I get exactly the same error - I'll have a think about IDispatch, I'm not entirely sure what to try next.