MattBecker82
MattBecker82

Reputation: 337

DnaMarshalException when running Excel DNA FSharp Registration Sample

I'm trying to follow the sample project for using Excel-DNA Registration Helpers for F Sharp. In particular, I'm interested in the sample for using optional arguments.

I've built the sample project (using Visual Studio 2015), but when I load the resulting Xll into Excel 2010 I receive the error

Registration [Error] Method not registered due to unsupported signature: 'Func`4.Invoke' : DnaMarshalException - Unknown Data Type: Microsoft.FSharp.Core.FSharpOption`1[System.Double]

in the diagnostics window, and the function dnaFSharpOptional is unavailable in Excel. It's as if the parameter conversion FsParameterConversions.FsOptionalParameterConversion is not being applied or is not working as intended.

Any ideas of the source of the error, and how to fix it?

N.B.

  1. As I'm only building the sample project, and not the whole Excel-DNA Registration solution, I had to change some of the project references (namely ExcelDna.Registration, ExcelDna.Registration.FSharp) to point to pre-built assemblies from nuget. But I don't imagine this would make a difference.
  2. The sample project references Excel 2013 in the project Debug settings but I'm using Excel 2010.
  3. The other example functions in the project (i.e. the Async functions) are available, so it's not a case of registration failing generally - it's something specific to the optional arguments.

Upvotes: 3

Views: 290

Answers (1)

MattBecker82
MattBecker82

Reputation: 337

Looks like the issue is that a filter is applied to the parameter conversion FsParameterConversions.FsOptionalParameterConversion where it only matches against parameters of type obj (i.e. System.Object).

My fix/workaround is to modify the FsAsync.Addin.AutoOpen method to call a different overload of ParameterConversionConfiguration.AddParameterConversion, passing null to the second argument. This forces the conversion to match against all parameters, regardless of type.

Oddly, I also had to explicitly convert the parameter conversion object to a delegate type when calling this overload in order to get it to compile (not sure why).

Change lines 10-11 of ExampleAddIn.fs from:

let paramConvertConfig = ParameterConversionConfiguration()
                             .AddParameterConversion(FsParameterConversions.FsOptionalParameterConversion)

to:

let paramConvertConfig = ParameterConversionConfiguration()
                            .AddParameterConversion(
                                new Func<Type, ExcelParameterRegistration, LambdaExpression>(
                                    FsParameterConversions.FsOptionalParameterConversion),
                                null) // null forces the parameter conversion to be tried against all params

Upvotes: 2

Related Questions