AutoDLL
FoxyBrown via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Jul 6 05:15:57 PDT 2017
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;
}
More information about the Digitalmars-d-learn
mailing list