Using a DLL exported from D
<p>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.</p>

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

<p>For example, there's the first line of one of my funcs:<br>
<code>ubyte[] encode(ubyte[] data, ubyte[] key){</code></p>

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

<p><strong>EDIT:</strong></p>

<p>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?<br>
(Where I don't need to use D to use a lib written in D)</p>

<p>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.</p>

<p>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.</p>

<p>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.</p>

<p>An example usage is here:
    module main;</p>

<pre><code>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);
}
</code></pre>

<p>Here is an absolute minimum version of how to do it</p>

<pre><code>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);
}
</code></pre>

python dll d