Passing multidimensional D arrays to C (sorry if duplicate)

Andrej Mitrovic none at none.com
Thu Oct 14 09:39:27 PDT 2010


I don't have a minimal working example right now so I'll just have to show you the client code and the C function prototype. I have a C++ DLL with a C interface for some of its functions and I am dynamically loading it in my D application. Here's some code with the usual DLL loading bits left out:

alias extern(C) void function(float** inputs) ProcessProc;
// Some code that loads the DLL, calls Windows' GetProcAddress.. and now we have a function pointer processFunc:
ProcessProc processFunc;

I have no trouble passing single pointer parameters to C functions, and even callback functions. But I haven't figured out an elegant way of passing multidimensional arrays to functions expecting pointers to pointers. I've tried forcing a 2-dimensional array with a cast, or even changing the function pointer signature to *fake* that it takes a 2-dimensional array and not a ptr-2-ptr, but that doesn't work properly as the C code ends up working only partially and I get back an access violation. 

So my calling code looks like the following. Disregard that I'm using GC's malloc and not std.c.stdlib.malloc for now please :) :

float[][] _inputs;
float** inputs;

enum numInputs = 4;
enum kBlockSize = 512;

_inputs = new float[][](numInputs, kBlockSize);

// we would now fill the inputs with some random data

inputs = cast(float**)GC.malloc((float*).sizeof * numInputs);

foreach (index; 0 .. numInputs)
{
    inputs[index] = _inputs[index].ptr;
}

// some loop that runs for a number of cycles, im using while true just for demonstration
while (true)
{
    processFunc(inputs);
}

I don't want to leave you in the dark, so let me explain. I'm using the popular VST plugin standard, which is used for digital audio plugin effects. The loaded DLL can be any DLL file that conforms to this standard and has a certain number and type of functions ready to be called from the client code. 

Basically how it's used is: I send a pointer to a number of buffers to the DLL's processing function, and the effect does some processing on the data and writes it back to the buffers.

If it's necessary I'll try to write a simplified C DLL and calling code to show what's wrong.

P.S. (for those in the know) I have a fully working Host example that can load VST instruments/effects, check their capabilities, do some processing, and load their GUI (if they have one). I have not ported any VST classes used to build the VST instruments yet.

P.P.S. I also have a working ASIO Host, however it's only a wrapper around the C++ classes. I'm currently having huge issues with COM, and I'm not yet sure if there's a bug in DMD or in my implementation.

P.P.P.S. Hopefully I'll be able to provide a clean implementation of both VST and ASIO, and after the necessary registration at Steinberg I'll create a repository for the projects. Wish me luck. :>


More information about the Digitalmars-d-learn mailing list