Here is a solution that will wrap all extern C functions and allow one to then map them to a dll.

auto BuildDLLClassFromCHeader(alias modulename, string name)()
{
        import std.traits, std.algorithm, std.meta;
auto s = "extern (C) class " ~name~"\n{\n\timport ___import = "~moduleName!modulename~";\n";
        mixin("import "~moduleName!modulename~";");
        foreach(m; AliasSeq!(__traits(allMembers, modulename)))
        {               
mixin("alias member = " ~ fullyQualifiedName!(modulename) ~ "." ~ m ~ ";");
                static if (is(typeof(member) == function))
                        static if (functionLinkage!member != "C")
                                continue;
                        else
s ~= "\tpublic static typeof(___import."~__traits(identifier, member)~")* "~__traits(identifier, member)~";\n";
        }
        
        return s ~ "}";
}

void DllImport(alias T)(string dllName)
{
        import core.sys.windows.windows, std.conv, std.meta;
        auto dll = LoadLibrary(to!wstring(dllName~"\0").ptr);
        if (dll == null)
                assert(0, "Cannot load DLL `"~dllName~"'");

        foreach(fname; __traits(derivedMembers, T))
        {               
                auto func = GetProcAddress(dll, fname);
enum s = "auto p = cast(void**)&"~T.stringof~"."~fname~"; *p = cast(typeof(p))func;";
                mixin(s);
        }
}

e.g.,


mixin(BuildDLLClassFromCHeader!(portaudio, "PortAudioDLL")());
DllImport!PortAudioDLL("portaudio_x86.dll");

it generates the following for portaudio.di:

extern (C) class PortAudioDLL
{
        import ___import = portaudio;
        public static typeof(___import.Pa_GetVersion)* Pa_GetVersion;
public static typeof(___import.Pa_GetVersionText)* Pa_GetVersionText;
        public static typeof(___import.Pa_GetErrorText)* Pa_GetErrorText;
        public static typeof(___import.Pa_Initialize)* Pa_Initialize;
        public static typeof(___import.Pa_Terminate)* Pa_Terminate;
public static typeof(___import.Pa_GetHostApiCount)* Pa_GetHostApiCount; public static typeof(___import.Pa_GetDefaultHostApi)* Pa_GetDefaultHostApi; public static typeof(___import.Pa_GetHostApiInfo)* Pa_GetHostApiInfo; public static typeof(___import.Pa_HostApiTypeIdToHostApiIndex)* Pa_HostApiTypeIdToHostApiIndex; public static typeof(___import.Pa_HostApiDeviceIndexToDeviceIndex)* Pa_HostApiDeviceIndexToDeviceIndex; public static typeof(___import.Pa_GetLastHostErrorInfo)* Pa_GetLastHostErrorInfo; public static typeof(___import.Pa_GetDeviceCount)* Pa_GetDeviceCount; public static typeof(___import.Pa_GetDefaultInputDevice)* Pa_GetDefaultInputDevice; public static typeof(___import.Pa_GetDefaultOutputDevice)* Pa_GetDefaultOutputDevice; public static typeof(___import.Pa_GetDeviceInfo)* Pa_GetDeviceInfo; public static typeof(___import.Pa_IsFormatSupported)* Pa_IsFormatSupported;
        public static typeof(___import.Pa_OpenStream)* Pa_OpenStream;
public static typeof(___import.Pa_OpenDefaultStream)* Pa_OpenDefaultStream;
        public static typeof(___import.Pa_CloseStream)* Pa_CloseStream;
public static typeof(___import.Pa_SetStreamFinishedCallback)* Pa_SetStreamFinishedCallback;
        public static typeof(___import.Pa_StartStream)* Pa_StartStream;
        public static typeof(___import.Pa_StopStream)* Pa_StopStream;
        public static typeof(___import.Pa_AbortStream)* Pa_AbortStream;
public static typeof(___import.Pa_IsStreamStopped)* Pa_IsStreamStopped; public static typeof(___import.Pa_IsStreamActive)* Pa_IsStreamActive; public static typeof(___import.Pa_GetStreamInfo)* Pa_GetStreamInfo; public static typeof(___import.Pa_GetStreamTime)* Pa_GetStreamTime; public static typeof(___import.Pa_GetStreamCpuLoad)* Pa_GetStreamCpuLoad;
        public static typeof(___import.Pa_ReadStream)* Pa_ReadStream;
        public static typeof(___import.Pa_WriteStream)* Pa_WriteStream;
public static typeof(___import.Pa_GetStreamReadAvailable)* Pa_GetStreamReadAvailable; public static typeof(___import.Pa_GetStreamWriteAvailable)* Pa_GetStreamWriteAvailable; public static typeof(___import.Pa_GetSampleSize)* Pa_GetSampleSize;
        public static typeof(___import.Pa_Sleep)* Pa_Sleep;
}

and then maps the function pointers to the dll.

Should work for other dlls.

  • AutoDLL FoxyBrown via Digitalmars-d-learn
    • Re: AutoDLL Mike Parker via Digitalmars-d-learn
    • Re: AutoDLL FoxyBrown via Digitalmars-d-learn

Reply via email to