A DLL Loader prototype that loads DLL's, just specify the declaration. Probably should be worked up so it is easy to load DLL's.

Example:



import portaudio;
import std.conv, std.stdio;
import core.stdc.stdio;

//pragma(lib, "portaudio_x86.lib"); // Doesn't work because libs are invalid



alias BOOL = ubyte;
alias DWORD = uint;

struct dllimport
{
  string dllName;
}

template hasAttribute(alias sym, T)
{
        static bool helper()
        {
                foreach(a; __traits(getAttributes, sym))
                {
if(is(a == T) || __traits(compiles, typeof(a)) && is(typeof(a) == T))
                                return true;
                }
                return false;
        }
        enum bool hasAttribute = helper();
}

template getAttribute(alias sym, T)
{
        static T helper()
        {
                foreach(a; __traits(getAttributes, sym))
                {
static if(is(a == T) || __traits(compiles, typeof(a)) && is(typeof(a) == T))
                                return a;
                }
                assert(0, "attribute " ~ T.stringof ~ " not found");
        }
        enum T getAttribute = helper();
}

void doImport(alias T)()
{
        import core.sys.windows.windows, std.conv;
        bool isDLLLoaded = false;
        HINSTANCE dll;
        foreach(m; __traits(allMembers, T))
        {               
                static if(__traits(compiles, typeof(__traits(getMember, T, m))))
                {                       
                        static if(hasAttribute!(__traits(getMember, T, m), 
dllimport))
                        {
auto dllName = getAttribute!(__traits(getMember, T, m), dllimport).dllName;
                                if (!isDLLLoaded)
                                {
                                        writeln("Loading DLL `"~dllName~"'...");
                                        isDLLLoaded = true;
                                        dll = 
LoadLibrary(to!wstring(dllName~"\0").ptr);
                                        if (dll == null)
                                        {
                                                // ERROR, handle
                                                writeln("Error, aborting!");
                                                return;
                                        }

                                }
                                auto q = GetProcAddress(dll, m);
                                mixin(m~" = cast(typeof("~m~"))q;");

//func(m, getAttribute!(__traits(getMember, T, m), dllimport).dllName, cast(void**)&__traits(getMember, T, m));
                        }
                }
        }
}

mixin template DllImportFunctions()
{
        struct DllImporter
        {
                shared static this()
                {
                        doImport!(__traits(parent, DllImporter))();
                }

static loadFunction(string name, const(char)[] dllName, void** addr)
                {
printf("import %.*s from %.*s into %llx\n", name.length, name.ptr, dllName.length, dllName.ptr, addr);
                }
        }
}

extern(Windows) @dllimport("portaudio_x86.dll") __gshared
{
        PaError function() Pa_Initialize;
        PaError function() Pa_Terminate;
        PaHostApiIndex function() Pa_GetHostApiCount;
        PaHostApiIndex function() Pa_GetDefaultHostApi;
        PaDeviceIndex function() Pa_GetDefaultOutputDevice;
        PaDeviceIndex function() Pa_GetDefaultInputDevice;
        PaDeviceIndex function() Pa_GetDeviceCount;
        const(PaHostErrorInfo)* function() Pa_GetLastHostErrorInfo;
PaDeviceIndex function(PaHostApiIndex hostApi, int hostApiDeviceIndex ) Pa_HostApiDeviceIndexToDeviceIndex; PaHostApiIndex function(PaHostApiTypeId type) Pa_HostApiTypeIdToHostApiIndex; const(PaHostApiInfo)* function(PaHostApiIndex hostApi) Pa_GetHostApiInfo; PaError function(PaStream *stream, PaStreamFinishedCallback streamFinishedCallback) Pa_SetStreamFinishedCallback;
        PaError function(PaStream *stream) Pa_CloseStream;
PaError function(PaStream** stream, int numInputChannels, int numOutputChannels, PaSampleFormat sampleFormat, double sampleRate, ulong framesPerBuffer, PaStreamCallback streamCallback, void *userData) Pa_OpenDefaultStream; PaError function(PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, ulong framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback streamCallback, void *userData) Pa_OpenStream; PaError function(const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate) Pa_IsFormatSupported; const(PaDeviceInfo)* function(PaDeviceIndex device) Pa_GetDeviceInfo;
        PaError function(PaStream *stream) Pa_StartStream;
        PaError function(PaStream *stream) Pa_StopStream;
        PaError function(PaStream *stream) Pa_AbortStream;
        PaError function(PaStream *stream) Pa_IsStreamStopped;
        void function(long msec) Pa_Sleep;
        PaError function(PaSampleFormat format) Pa_GetSampleSize;
        long function(PaStream* stream) Pa_GetStreamWriteAvailable;
        long function(PaStream* stream) Pa_GetStreamReadAvailable;
PaError function(PaStream* stream, const void *buffer, ulong frames) Pa_WriteStream; PaError function(PaStream* stream, void *buffer, ulong frames) Pa_ReadStream;
        double function(PaStream* stream) Pa_GetStreamCpuLoad;
        PaTime function(PaStream *stream) Pa_GetStreamTime;
        const(PaStreamInfo)* function(PaStream *stream) Pa_GetStreamInfo;
        PaError function(PaStream *stream) Pa_IsStreamActive;

}

mixin DllImportFunctions;



struct Phase
{
    float left=0, right=0;
}

extern(C) int sawtooth(const(void)* inputBuffer, void* outputBuffer, size_t framesPerBuffer, const(PaStreamCallbackTimeInfo)* timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
{
    auto phase = cast(Phase*)userData;

    auto pout = cast(float*)outputBuffer;

    enum vol = 0.2f;

    foreach(i; 0 .. framesPerBuffer)
    {
        *pout++ = vol * phase.left;
        *pout++ = vol * phase.right;

        phase.left += 0.01f;
        if (phase.left >= 1.0f) phase.left -= 2.0f;

        phase.right += 0.03f;
        if (phase.right >= 1.0f) phase.right -= 2.0f;
    }
    return 0;
}

int main()
{
    enum SAMPLE_RATE = 44100;
    enum NUM_SECONDS = 15;

    PaStream* stream;
    PaError err;
    Phase phase_data;

        auto x = Pa_Initialize;

    if ((err = Pa_Initialize()) != paNoError) goto Lerror;

if ((err = Pa_OpenDefaultStream(&stream, 0, 2, paFloat32, SAMPLE_RATE, paFramesPerBufferUnspecified, &sawtooth, &phase_data)) != paNoError) goto Lerror;

    if ((err = Pa_StartStream(stream)) != paNoError) goto Lerror;

    Pa_Sleep(NUM_SECONDS * 1000);

    if ((err = Pa_StopStream(stream)) != paNoError) goto Lerror;
    if ((err = Pa_CloseStream(stream)) != paNoError) goto Lerror;
    if ((err = Pa_Terminate()) != paNoError) goto Lerror;

    return 0;
 Lerror:
//stderr.writefln("error %s", to!string(Pa_GetErrorText(err)));
    return 1;
}

  • AutoDLL FoxyBrown via Digitalmars-d-learn

Reply via email to