Swift (Silver) and Island, managed and unmanaged Windows code

Don’t know if this should be somewhere else, as my issue deals in both Island and Silver.

I’m writing some complex numerical analysis – and the facilities in Swift are wonderful for the mathematical notation. But I also use complex GUI (including graphs reports etc.) which I also largely write or connect to from Swift (Silver) in the Windows .NET environment. (Develop on Visual Studio 2015, Elements 9.)

The outer layer of my question is how to write Silver libraries (mathematical only, no GUI) that run in native so they have the efficiency of native compile, and call them from the outer GUI related Silver code for .NET. (I have already verified that I get non-Sugar versions of the math library in Swift-Island, so it appears I can do the math I want.)

Right now, however, I find the documentation on Island sketchy or don’t know where to look. Want to know just what I get when I create Silver / Island / Class Library (Windows). I see that it produces a .DLL output. But don’t know how to access that.

(Fair experience using C# GUI to call DLL’s, I don’t need a DLL tutorial, there are plenty of those on the net. Rather I don’t know what I am getting specifically with the Island class library, and how to interface that to the outside world in any manner at the moment.)

Guess I’ll amend that above a bit: I’ve had bad luck trying to call native DLL’s (of any sort or origin) from a Silver GUI project (.NET on VS2015, Elements V 8). I have called “class libraries” of either Silver or other managed code with no problem from managed Silver. And I have called native DLL’s from C# successfully. Right now I’ll defer the questions of using a native code from Silver GUI vs just using a C# GUI and combining managed and unmanaged Silver code segments. WHAT I really mean is to defer those complexities to another question–RIGHT NOW my desire is to understand the native code capabilities of Island Silver class libraries–however they might be consumed.

What does a Visual Studio Silver / Island / Class Library (Windows) project produce? Any examples of using such a DLL in any circumstance?

Just curios Bravo, are you using __external / PInvoke to call from managed Silver to native, but you can’t get it to work?
I have a similar requirement coming up soon, to call from a silver managed dll into a native C++ DLL via C functions that should be P/Invokeable.

I don’t remember the problem exactly in (Silver) Swift, but relates to external tagging that is available in C#.

What I did that does work is to write a C# DLL / routine that imports my C++ unmanaged DLL. Then import that C# “class library” which works almost without thinking about it with the nice facilities of V.S., just list it in the references and it even imports the (glue) DLL into the project and installer files as well.

Then in that C# DLL I wrote various interface functions with qualifiers like:
[DllImport("…
for each of the functions.

In part I do understand what the individual lines are doing, but don’t necessarily have the experience to know if there is a better way.

I remember that when I tried to do equivalent things in Swift, I didn’t know how to cut through the weirdness that is available in the C# to qualify the DLL function calls.

There may be improvements in Elements 9, BTW, that I have not looked up or tried that may help with this.

So I’m not exactly sure of the terminology at the moment. I read up on all the examples and think I know a bit more when I am in the thick of setting something like this up, and usually find a way that works. And I research it so that I am confident that it really works – not just accidentally working. But then having dropped it a few months I now forget, and don’t have time to look up the terminology.

I will say that the above method was more an attempt to use the automatic binding facilities, rather than explicit calls to load the DLL, if that helps. (Once again fuzzy on terminology without getting into it completely at the moment.)

Guess there is a browser–I should examine the Island DLL to see what it is presenting as well.

THEN the actual question!

While able to get this to work using the kludge subterfuge of the intervening glue DLL, I could not figure out how to make the same glue directly in managed Silver. All I remember is that things I tried would not compile – but I may have lost the history in my frustration. I’ll check if I can find some commented examples in the next few days. Someone might provide some pointers here as well, but this is all the question I was going to ask later.

I guess that’s adding all the correct P/Invoke signature/attributes to the [DllImport] attribute.

DllImport is mentioned explicitly here:
https://docs.elementscompiler.com/Concepts/Aspects/SpecialAttributesNET/#DllImportAttribute
But no example of exactly how to use it with Silver.

Here is my glue DLL code in (Microsoft) C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Runtime.InteropServices;



namespace DLL2_Call
{
    public class DLL2
    {

        // Notice that the "public" extern reference builds the marshaling -- the reference,
        // now public, is available as DLL2.DLL2_Func. There is no need for a cover up routine
        // unless there is work to be done or naming conventions to be applied.

        // Also note we are still in "DLL Purgatory" (not "DLL Hell") because the system
        // does not move the (extern) unmanaged DLL into the output for us (yet). However
        // when placed there it works correctly. The "..\\..\\..\\x64\\Debug\\DLL2.dll" works
        // on temporary basis but does not land for external device........

        // Furthermore note that this (here) is a "Class Library" with full C# class feed to the
        // master project. The significance is that it DOES place properly when referenced (as
        // opposed to the unmanaged DLL that does not) and furthermore it is the means by why
        // one can easily mix Microsoft C# and the (Silver) Swift languages together, as this
        // class library can compile the entire required fully C# portion of the program.
        // It is similar to the J2i.Net.XInputWrapper code example which itself, whose XInput.cs
        // file is the similar DllImport group for its (Microsoft) DLL's.

        [DllImport("..\\..\\..\\x64\\Debug\\DLL2.dll")] // CANGE this back to local reference, FIX  move there!!!!!!!!!!!!!!! ???
        public static extern double DLL2_Func(double a, double b);  // Must match contents of DLL.

        //public static double DLL2_F(double a, double b)
        //{
        //    return DLL2_Func( a, b );
        //}

        // https://msdn.microsoft.com/en-us/library/hk9wyw21(v=vs.110).aspx
        [DllImport("..\\..\\..\\x64\\Debug\\DLL2.dll")] // CANGE this back to local reference, FIX  move there!!!!!!!!!!!!!!! ???
        public static extern double DLL2_ArrayFunc([In, Out] double[] a, int n);  // Also match DLL

        [DllImport("..\\..\\..\\x64\\Debug\\DLL2.dll")] // CANGE this back to local reference, FIX  move there!!!!!!!!!!!!!!! ???
        public static extern double DLL2_ArrayIOFunc([In, Out] double[] a, int n);  // Also match DLL


        public static double DLL2_ArrayFuncCall(double[] a)
        {
            return DLL2_ArrayFunc(a,a.Length);
        }

        public static double DLL2_ArrayIOFuncCall(double[] a)
        {
            return DLL2_ArrayFunc(a, a.Length);
        }
    }
}

And here is the actual C++ DLL:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"


// On creating and calling unmanaged (64 bit) DLL:
// http://www.ni.com/white-paper/3056/en/


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}

extern "C" __declspec(dllexport) double DLL2_Func(double a, double b);
extern "C" __declspec(dllexport) double DLL2_ArrayFunc(double a[], int n);
extern "C" __declspec(dllexport) double DLL2_ArrayIOFunc(double a[], int n);

double DLL2_Func(double a, double b) {
	return a*b;
}

double DLL2_ArrayFunc(double a[], int n) {
	double product = 1.0;
	for (int i = 0; i < n; ++i) {
		product *= a[i];
	}
	return product;
}

double DLL2_ArrayIOFunc(double a[], int n) {
	double product = 1.0;
	for (int i = 0; i < n; ++i) {
		product *= a[i];
		a[i] *= 3;
	}
	return product;
}

And the Swift code snipped that uses the “DLL2”:

        let x = Math.Cos(π/2)
        let y = Math.Cos(π)
        let z = DLL2.DLL2_Func(2.0,π)
        var a: Double[]! =[1.0, 2.0, 3.0, 4.0, 5.0]     // Is this syntax legal portable Swift?
        var ap=1.0
        ap = DLL2.DLL2_ArrayFuncCall(a)
        ap = DLL2.DLL2_ArrayFunc(a,a.Length)   // Apparently the last 2 lines do the same thing

These are totally stupid examples, done to test simple function, array read, and array read/write. I’m not sure where I was at on making array read/write work, either. Also there is probably a better way. And indeed, if I can figure out how to write that glue directly in or associated with the Silver rather than the glue DLL, would save a lot of work.

AAAK! Notes in above, figured out that I don’t have to write the “glue” code function calls in most instances! Just used the intervening DLL to import the “real” DLL, so that the function call lines could be declared correctly – then the Swift imported them directly so I didn’t really need any glue code to pass values! However there was one example above where the C++ needed 2 arguments, and glue code used the internal array knowledge to collapse to one argument — so a bit of intervening glue code is still useful.

(Also note that this code is not production ready technique, as the DLL was referenced in its location at compile time not on a target system. The problem of including and positioning the DLL needs to be handled.)

HEY! View / object browser shows details of my DLL.

AND

Oxidizer paste of the “working” C# glue code appears to convert the declaration syntax! So may be able to directly code even if I can’t find the documentation of how to do it.

@DllImport("..\\..\\..\\x64\\Debug\\DLL2.dll") // CANGE this back to local reference, FIX  move there!!!!!!!!!!!!!!! ???
public static __extern func DLL2_Func(_ a: Float64, _ b: Float64) -> Float64

Don’t have time tonight, but will try this in next few days. THEN will try to call my Island Silver code DLL.

[quote=“jnermut, post:4, topic:11566”]
DllImport is mentioned explicitly here:…[/quote]

Thanks also on link – once again don’t have time but might solve the problem of the array I/O to DLL as the C# “OUT” property is mentioned.

cool. I would be interested to see how Oxidizer converted it (and if it works!)

(Crossing posts – edited example in above)

PS does not compile as presented in above.

Island class library would produce a plain windows (32 or 64bits, depending on the project settings) DLL. If you use [DllExport, SymbolName(‘exportname’), callingconvention(callingconvention.stdcall)] you can export a method under the name ‘exportname’ with callingconvention stdcall (.NET side you can then use DLLImport to import it).

Thanks, Carlo

As above I’ve pasted some of the “oxidized” code for calling DLL and not had luck making a DLL call in the managed Silver compile yet (VS2015, Elements 9). Since documentation is sparse on this, I would appreciate some examples. Since you mention the unmanaged side, examples there would also be useful.

What I really want to accomplish is a Windows .NET high level managed Silver program (with WPF based GUI) calling an Island (native) Silver low level library. At minimum I need to pass argument values and arrays, with array values passed back from the lower level Island (native) Silver library.

Of course passing more complex structures can be useful – but the number of translations and restrictions may limit that ability. Any examples that actually compile in Elements 9 on Visual Studio 2015 would be appreciated.

As I mentioned, I can make them work by placing an (almost fake) glue DLL written in Microsoft C# in between – just a royal pain in the ##!!@@.

What makes this important is that your implementation of Swift allows users to write mathematical notation that is much more readable, and other advancements of Swift that make productive programming. Portability to the other environments is secondary to me right now, but could be important to others (and even myself on other projects). So right now I would accept a very high level GUI in Microsoft C# WPF, calling a managed Silver business code DLL, which then calls an unmanaged Island Silver DLL for some low level (efficient) business code numerical analysis.

In the future when Sugar is ported to Island, the ability to glue such assemblies together will allow efficient calculations in Microsoft GUI based environments, while writing more or less portable analysis business code in the Island side–all of which could have the messy glue layer abstracted as best as possible for porting to other environments. In the Apple world, for example, one gets the native efficiency for numerical analysis in Swift right out of the box, as opposed to the heavy penalty (say 10X???) in Windows environment.

While I doubt very much that .NET is 10 times slower (or even 2 times slower) than equivalent Swift code,here’s a sample: WPFApplication11.zip (33.0 KB)

Note that this topic is for .NET, not Island,