Using a DLL exported from D
Question: I've created a simple encryption program in D, and I had the idea to make a
DLL from it and try to import it to, for example, Python.

I've could simply call my `main` function, becouse it dosn't need any params.
But when I get to my encrytion method, **it uses dynamic-lenght`ubyte[]`
arrays**, but as far as I know, they **don't exist in other C/C++ based
langs**.

For example, there's the first line of one of my funcs:  
`ubyte[] encode(ubyte[] data, ubyte[] key){`

But I can't use an array without fixed lenght in other languages! How can I
import that function, for example, in Python?

**EDIT:**

I know that I can create a wrapper that takes a pointer and the lenght of the
array, but isn't there a more elegant solution?  
(Where I don't need to use D to use a lib written in D)


Answer: Well tbh. there's no real elegant way other than wrapping a pointer with a
length or wrapping to C arrays and then to D.

However you can make a somewhat elegant purpose with the first way using a
struct that has a pointer, a length and a property that converts it to a D
array.

Then the function you export takes your struct, all that function should do is
call an internal function that takes an actual D array and you'd simply pass
the array to it and the conversion would happen at that moment through alias
this and the conversion property.

An example usage is here: module main;

    
    
    import core.stdc.stdlib : malloc;
    
    import std.stdio;
    
    struct DArray(T) {
        T* data;
        size_t length;
        /// This field can be removed, only used for testing purpose
        size_t offset;
    
        @property T[] array() {
            T[] arr;
    
            foreach(i; 0 .. length) {
                arr ~= data[i];
            }
    
            return arr;
        }
    
        alias array this;
    
        /// This function can be removed, only used for testing purpose
        void init(size_t size) {
            data = cast(T*)malloc(size * T.sizeof);
            length = size;
        }
    
        /// This function can be removed, only used for testing purpose
        void append(T value) {
            data[offset] = value;
    
            offset++;
        }
    }
    
    // This function is the one exported
    void externalFoo(DArray!int intArray) {
        writeln("Calling extern foo");
    
        internalFoo(intArray);
    }
    
    // This function is the one you use
    private void internalFoo(int[] intArray) {
        writeln("Calling internal foo");
    
        writeln(intArray);
    }
    
    
    void main() {
        // Constructing our test array
        DArray!int arrayTest;
        arrayTest.init(10);
    
        foreach (int i; 0 .. 10) {
            arrayTest.append(i);
        }
    
        // Testing the exported function 
        externalFoo(arrayTest);
    }
    

Here is an absolute minimum version of how to do it

    
    
    struct DArray(T) {
        T* data;
        size_t length;
    
        @property T[] array() {
            T[] arr;
    
            foreach(i; 0 .. length) {
                arr ~= data[i];
            }
    
            return arr;
        }
    
        alias array this;
    
    }
    
    // This function is the one exported
    void externalFoo(DArray!int intArray) {
        writeln("Calling extern foo");
    
        internalFoo(intArray);
    }
    
    // This function is the one you use
    private void internalFoo(int[] intArray) {
        writeln("Calling internal foo");
    
        writeln(intArray);
    }
    

