Commit d35bfcde authored by Carsten Schlote's avatar Carsten Schlote

Added support code for module loader to avoid static linkage to SO file

Change code to dynamically load the mediainfo library, either as dll or
so file from the usual location. It is no longer required to link
against the mediainfo library
parent ac9525a6
......@@ -12,6 +12,13 @@ int main(string[] args)
assert(args.length >= 2, "Pass a filename to scan to the program.");
fileName = args[1];
auto rc0 = MediaInfoDLL_Load();
writeln("Loader result: ", rc0);
auto rc1 = MediaInfoDLL_IsLoaded();
writeln("IsLoaded result:", rc1);
MediaInfoDLL_UnLoad();
auto info = MediaInfo();
string vstring = info.option("Info_Version", "0.7.38.0;DTest;0.1");
......@@ -39,9 +46,9 @@ int main(string[] args)
const ulong nText = info.getCount(MediaInfo_stream_t.MediaInfo_Stream_Text);
if (nText == 0 && nVideo == 0 && nAudio == 0) {
writeln("Found no media info on this file.");
writeln("Found no media info on this file.");
return 0;
}
}
writefln("---%s---", info.get(MediaInfo_stream_t.MediaInfo_Stream_General, 0, "FileName"));
for (uint i = 0; i < nVideo; i++)
......
This diff is collapsed.
......@@ -18,11 +18,18 @@ import core.stdc.config;
/*Char types */
/* D is always unicode! Note: wchar_t is different on Poxix and Windows! */
version(Windows) {
alias MediaInfo_Char = char;
alias MediaInfo_WChar = wchar;
alias MediaInfo_Char = char;
version(UNICODE) {
enum MEDIAINFO_Ansi = "";
alias MediaInfo_WChar = wchar;
} else {
enum MEDIAINFO_Ansi = "A";
alias MediaInfo_WChar = char;
}
}
else {
alias MediaInfo_Char = char;
enum MEDIAINFO_Ansi = "";
alias MediaInfo_WChar = dchar;
}
......@@ -150,3 +157,271 @@ version(MediaInfo_Ansi)
extern __gshared c_ulong MediaInfoA_Count_Get_Files (void*);
extern __gshared c_ulong MediaInfoListA_Count_Get_Files (void*);
}
/* Module loader support */
version(MEDIAINFO_GLIBC) {
template MEDIAINFO_ASSIGN(string _Name) {
void MEDIAINFO_ASSIGN(ref size_t Errors) {
auto rv = g_module_symbol (MediaInfo_Module, "MediaInfo" ~ MEDIAINFO_Ansi ~ "_" ~_Name, mixin("cast(gpointer*) & ptrMediaInfo_" ~ _Name ~")" ));
if (!rv) Errors++;
}
}
template MEDIAINFOLIST_ASSIGN(string _Name) {
void MEDIAINFOLIST_ASSIGN(ref size_t Errors) {
auto rv = g_module_symbol (MediaInfo_Module, "MediaInfoList" ~ MEDIAINFO_Ansi ~ "_" ~_Name, mixin("cast(gpointer*) & ptrMediaInfoList_" ~ _Name ~")" ));
if (!rv) Errors++;
}
}
} else version(WINDOWS) {
template MEDIAINFO_ASSIGN(string _Name) {
void MEDIAINFO_ASSIGN(ref size_t Errors) {
auto rv = GetProcAddress(MediaInfo_Module, "MediaInfo" ~ MEDIAINFO_Ansi ~ "_" ~ _Name);
mixin("ptrMediaInfo_" ~ _Name) = mixin("cast(MEDIAINFO" ~ MEDIAINFO_Ansi ~ "_" ~ _Name ~ ")rv");
if (mixin("ptrMediaInfo_" ~ _Name) == null) Errors++;
}
}
template MEDIAINFOLIST_ASSIGN(string _Name) {
void MEDIAINFOLIST_ASSIGN(ref size_t Errors) {
auto rv = GetProcAddress(MediaInfo_Module, "MediaInfoList" ~ MEDIAINFO_Ansi ~ "_" ~ _Name);
mixin("ptrMediaInfoList_" ~ _Name) = mixin("cast(MEDIAINFOLIST" ~ MEDIAINFO_Ansi ~ "_" ~ _Name ~ ")rv");
if (mixin("ptrMediaInfoList_" ~ _Name) == null) Errors++;
}
}
} else {
template MEDIAINFO_ASSIGN(string _Name) {
void MEDIAINFO_ASSIGN(ref size_t Errors) {
auto rv = dlsym(MediaInfo_Module, "MediaInfo" ~ MEDIAINFO_Ansi ~ "_" ~ _Name);
mixin("ptrMediaInfo_" ~ _Name) = mixin("cast(MEDIAINFO" ~ MEDIAINFO_Ansi ~ "_" ~ _Name ~ ")rv");
if (mixin("ptrMediaInfo_" ~ _Name) == null) Errors++;
}
}
template MEDIAINFOLIST_ASSIGN(string _Name) {
void MEDIAINFOLIST_ASSIGN(ref size_t Errors) {
auto rv = dlsym(MediaInfo_Module, "MediaInfoList" ~ MEDIAINFO_Ansi ~ "_" ~ _Name);
mixin("ptrMediaInfoList_" ~ _Name) = mixin("cast(MEDIAINFOLIST" ~ MEDIAINFO_Ansi ~ "_" ~ _Name ~ ")rv");
if (mixin("ptrMediaInfoList_" ~ _Name) == null) Errors++;
}
}
}
/* Define function pointers the hard way - use traits to get membertypes of struct functions */
alias MEDIAINFO_New = typeof(MediaInfo_New)*;
MEDIAINFO_New ptrMediaInfo_New;
alias MEDIAINFOLIST_New = typeof(MediaInfo_New)*;
MEDIAINFOLIST_New ptrMediaInfoList_New;
alias MEDIAINFO_Delete = typeof(MediaInfo_Delete)*;
MEDIAINFO_Delete ptrMediaInfo_Delete;
alias MEDIAINFOLIST_Delete = typeof(MediaInfoList_Delete)*;
MEDIAINFOLIST_Delete ptrMediaInfoList_Delete;
alias MEDIAINFO_Open = typeof(MediaInfo_Open)*;
MEDIAINFO_Open ptrMediaInfo_Open;
alias MEDIAINFOLIST_Open = typeof(MediaInfoList_Open)*;
MEDIAINFOLIST_Open ptrMediaInfoList_Open;
alias MEDIAINFO_Open_Buffer_Init = typeof(MediaInfo_Open_Buffer_Init)*;
MEDIAINFO_Open_Buffer_Init ptrMediaInfo_Open_Buffer_Init;
alias MEDIAINFO_Open_Buffer_Continue = typeof(MediaInfo_Open_Buffer_Continue)*;
MEDIAINFO_Open_Buffer_Continue ptrMediaInfo_Open_Buffer_Continue;
alias MEDIAINFO_Open_Buffer_Continue_GoTo_Get = typeof(MediaInfo_Open_Buffer_Continue_GoTo_Get)*;
MEDIAINFO_Open_Buffer_Continue_GoTo_Get ptrMediaInfo_Open_Buffer_Continue_GoTo_Get;
alias MEDIAINFO_Open_Buffer_Finalize = typeof(MediaInfo_Open_Buffer_Finalize)*;
MEDIAINFO_Open_Buffer_Finalize ptrMediaInfo_Open_Buffer_Finalize;
alias MEDIAINFO_Open_NextPacket = typeof(MediaInfo_Open_NextPacket)*;
MEDIAINFO_Open_NextPacket ptrMediaInfo_Open_NextPacket;
alias MEDIAINFO_Close = typeof(MediaInfo_Close)*;
MEDIAINFO_Close ptrMediaInfo_Close;
alias MEDIAINFOLIST_Close = typeof(MediaInfoList_Close)*;
MEDIAINFOLIST_Close ptrMediaInfoList_Close;
alias MEDIAINFO_Inform = typeof(MediaInfo_Inform)*;
MEDIAINFO_Inform ptrMediaInfo_Inform;
alias MEDIAINFOLIST_Inform = typeof(MediaInfoList_Inform)*;
MEDIAINFOLIST_Inform ptrMediaInfoList_Inform;
alias MEDIAINFO_GetI = typeof(MediaInfo_GetI)*;
MEDIAINFO_GetI ptrMediaInfo_GetI;
alias MEDIAINFOLIST_GetI = typeof(MediaInfoList_GetI)*;
MEDIAINFOLIST_GetI ptrMediaInfoList_GetI;
alias MEDIAINFO_Get = typeof(MediaInfo_Get)*;
MEDIAINFO_Get ptrMediaInfo_Get;
alias MEDIAINFOLIST_Get = typeof(MediaInfoList_Get)*;
MEDIAINFOLIST_Get ptrMediaInfoList_Get;
alias MEDIAINFO_Output_Buffer_Get = typeof(MediaInfo_Output_Buffer_Get)*;
MEDIAINFO_Output_Buffer_Get ptrMediaInfo_Output_Buffer_Get;
alias MEDIAINFO_Output_Buffer_GetI = typeof(MediaInfo_Output_Buffer_GetI)*;
MEDIAINFO_Output_Buffer_GetI ptrMediaInfo_Output_Buffer_GetI;
alias MEDIAINFO_Option = typeof(MediaInfo_Option)*;
MEDIAINFO_Option ptrMediaInfo_Option;
alias MEDIAINFOLIST_Option = typeof(MediaInfoList_Option)*;
MEDIAINFOLIST_Option ptrMediaInfoList_Option;
alias MEDIAINFO_State_Get = typeof(MediaInfo_State_Get)*;
MEDIAINFO_State_Get ptrMediaInfo_State_Get;
alias MEDIAINFOLIST_State_Get = typeof(MediaInfoList_State_Get)*;
MEDIAINFOLIST_State_Get ptrMediaInfoList_State_Get;
alias MEDIAINFO_Count_Get = typeof(MediaInfo_Count_Get)*;
MEDIAINFO_Count_Get ptrMediaInfo_Count_Get;
alias MEDIAINFOLIST_Count_Get = typeof(MediaInfoList_Count_Get)*;
MEDIAINFOLIST_Count_Get ptrMediaInfoList_Count_Get;
alias MEDIAINFO_Count_Get_Files = typeof(MediaInfo_Count_Get_Files)*;
MEDIAINFO_Count_Get_Files ptrMediaInfo_Count_Get_Files;
alias MEDIAINFOLIST_Count_Get_Files = typeof(MediaInfoList_Count_Get_Files)*;
MEDIAINFOLIST_Count_Get_Files ptrMediaInfoList_Count_Get_Files;
version(WINDOWS)
enum MEDIAINFODLL_NAME = "MediaInfo.dll";
else {
enum MEDIAINFODLL_NAME = "libmediainfo.so.0";
}
extern(C) {
shared(void *) dlopen(const char *filename, int flag);
char *dlerror();
void *dlsym(shared void *handle, const char *symbol);
int dlclose(shared void *handle);
}
enum RTLD_LAZY = 0x00001;
shared void* MediaInfo_Module = null;
shared size_t Module_Count = 0;
static import core.atomic;
size_t MediaInfoDLL_Load()
{
size_t Errors = 0;
if (Module_Count > 0) {
core.atomic.atomicOp!"+="(Module_Count, 1);
return 1;
}
/* Load library */
version(MEDIAINFO_GLIBC) {
MediaInfo_Module = g_module_open(MEDIAINFODLL_NAME, G_MODULE_BIND_LAZY);
} else version(WINDOWS) {
MediaInfo_Module = LoadLibrary(MEDIAINFODLL_NAME);
} else {
version(MACOSX) {
MediaInfo_Module = dlopen("@executable_path/" ~ MEDIAINFODLL_NAME, RTLD_LAZY);
if (!MediaInfo_Module)
{
CFBundleRef mainBundle = CFBundleGetMainBundle();
// get full app path and delete app name
CFURLRef app_url = CFBundleCopyExecutableURL(mainBundle);
CFURLRef app_path_url = CFURLCreateCopyDeletingLastPathComponent(NULL, app_url);
CFStringRef app_path = CFURLCopyFileSystemPath(app_path_url, kCFURLPOSIXPathStyle);
CFMutableStringRef mut_app_path = CFStringCreateMutableCopy(NULL, NULL, app_path);
CFStringAppend(mut_app_path, CFSTR("/"));
CFStringAppend(mut_app_path, CFSTR(MEDIAINFODLL_NAME));
CFStringEncoding encodingMethod = CFStringGetSystemEncoding();
const char *fullPath = CFStringGetCStringPtr(mut_app_path, encodingMethod);
MediaInfo_Module = dlopen(fullPath, RTLD_LAZY);
CFRelease(app_url);
CFRelease(app_path_url);
CFRelease(app_path);
CFRelease(mut_app_path);
}
} /* MACOSX*/
if (!MediaInfo_Module)
MediaInfo_Module = dlopen(MEDIAINFODLL_NAME, RTLD_LAZY);
if (!MediaInfo_Module)
MediaInfo_Module = dlopen("./" ~ MEDIAINFODLL_NAME, RTLD_LAZY);
if (!MediaInfo_Module)
MediaInfo_Module = dlopen("/usr/local/lib/" ~ MEDIAINFODLL_NAME, RTLD_LAZY);
if (!MediaInfo_Module)
MediaInfo_Module = dlopen("/usr/local/lib64/" ~ MEDIAINFODLL_NAME, RTLD_LAZY);
if (!MediaInfo_Module)
MediaInfo_Module = dlopen("/usr/lib/" ~ MEDIAINFODLL_NAME, RTLD_LAZY);
if (!MediaInfo_Module)
MediaInfo_Module = dlopen("/usr/lib64/" ~ MEDIAINFODLL_NAME, RTLD_LAZY);
}
if (!MediaInfo_Module)
return - 1;
/* Load function pointers */
MEDIAINFO_ASSIGN!("New")(Errors);
MEDIAINFOLIST_ASSIGN!("New")(Errors);
MEDIAINFO_ASSIGN!("Delete")(Errors);
MEDIAINFOLIST_ASSIGN!("Delete")(Errors);
MEDIAINFO_ASSIGN!("Open")(Errors);
MEDIAINFOLIST_ASSIGN!("Open")(Errors);
MEDIAINFO_ASSIGN!("Open_Buffer_Init")(Errors);
MEDIAINFO_ASSIGN!("Open_Buffer_Continue")(Errors);
MEDIAINFO_ASSIGN!("Open_Buffer_Continue_GoTo_Get")(Errors);
MEDIAINFO_ASSIGN!("Open_Buffer_Finalize")(Errors);
MEDIAINFO_ASSIGN!("Open_NextPacket")(Errors);
MEDIAINFO_ASSIGN!("Close")(Errors);
MEDIAINFOLIST_ASSIGN!("Close")(Errors);
MEDIAINFO_ASSIGN!("Inform")(Errors);
MEDIAINFOLIST_ASSIGN!("Inform")(Errors);
MEDIAINFO_ASSIGN!("GetI")(Errors);
MEDIAINFOLIST_ASSIGN!("GetI")(Errors);
MEDIAINFO_ASSIGN!("Get")(Errors);
MEDIAINFOLIST_ASSIGN!("Get")(Errors);
MEDIAINFO_ASSIGN!("Output_Buffer_Get")(Errors);
MEDIAINFO_ASSIGN!("Output_Buffer_GetI")(Errors);
MEDIAINFO_ASSIGN!("Option")(Errors);
MEDIAINFOLIST_ASSIGN!("Option")(Errors);
MEDIAINFO_ASSIGN!("State_Get")(Errors);
MEDIAINFOLIST_ASSIGN!("State_Get")(Errors);
MEDIAINFO_ASSIGN!("Count_Get")(Errors);
MEDIAINFOLIST_ASSIGN!("Count_Get")(Errors);
MEDIAINFOLIST_ASSIGN!("Count_Get_Files")(Errors);
if (Errors > 0) {
// Unload DLL with errors
version(MEDIAINFO_GLIBC) {
g_module_close(MediaInfo_Module);
} else version(WINDOWS) {
FreeLibrary(MediaInfo_Module);
} else {
dlclose(MediaInfo_Module);
MediaInfo_Module = null;
return - 1;
}
}
core.atomic.atomicOp!("+=")(Module_Count, 1);
return 1;
}
size_t MediaInfoDLL_IsLoaded()
{
if (MediaInfo_Module)
return 1;
else
return 0;
}
void MediaInfoDLL_UnLoad()
{
core.atomic.atomicOp!("-=")(Module_Count, 1);
if (Module_Count > 0)
return;
version(MEDIAINFO_GLIBC)
g_module_close(MediaInfo_Module);
else version(WINDOWS)
FreeLibrary(MediaInfo_Module);
else {
dlclose(MediaInfo_Module);
}
MediaInfo_Module = null;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment