66
votes

We have some interop code that involves matrices. I was trying to call the native DLL and for the most part it works very reliably.

I am relying on the default marshalling by .net, avoiding unmanaged pointers and rather using .net arrays for the most part, and maybe a byref here and there. The .net article says, that multidimensional arrays are implicitly marshalled as column-major one-dimensional arrays, which would be fine.

The only thing that does not seem to work, is trying to marshal a multi-dimensional array, as the F# compiler complains that float[,] is not allowed in an extern declaration. Is there any way around this limitation?

I am aware of the PinnedArray and PinnedArray2 types from the F# PowerPack, but I was looking for a solution which relies on managed pointers and - more importantly - I'd like to avoid having to include F# PowerPack as a dependency just for the PinnedArray classes.

1
I suspect the article is referring to multidimensional arrays in the C sense. I'm not too familiar with C, but don't multidimensional C arrays use syntax similar to .NET jagged arrays? I don't think C has something like float[,]. So have you tried float[][]?Daniel
According to the article, jagged arrays cannot be implicitly marshalled and multi-dimensional arrays should be able to be marshalled.Daniel Fabian
Didn't you think on separation of concerns? You could organize business logic at F# side, having C# component responsible for interop, communications and other "inftrastructure" things. So, the problem just goes away...mikalai
Whilst an interesting idea to do it in a polyglot fashion, that really does not answer the question about how to do in F#. Apart from that, when doing just the p/invoke part in a polyglot fashion (we have an almost exclusive F# stack), C# is the wrong language. In the end, I ended up doing with C++/CLI and using real C headers for P/Invoke and providing a .net friendly interface to it. This had the added benefit of having a compiler for the P/Invoke signatures.Daniel Fabian
what does your c declarations look like?AK_

1 Answers

1
votes

By this discription about Blittable and Non-Blittable Types in the link below you could try the System.Double in place of float, because they do not require conversion when they are passed between managed and unmanaged code wich means no more special handling by the interop marshaler with a plus in performance: https://msdn.microsoft.com/en-us/library/75dwhxf7%28v=vs.110%29.aspx

I did a search and found this related topic wich may help you:

Threat like a single array: http://stackoverflow.com/a/18607817/4597705