maug
Quick and dirty C mini-augmentation library.
Loading...
Searching...
No Matches
mplug.h
1
2#ifndef MPLUG_H
3#define MPLUG_H
4
5typedef MERROR_RETVAL (*mplug_proc_t)( void* data, size_t data_sz );
6
7/* TODO: Have plugins have a way to set log output. */
8
9#ifdef RETROFLAT_OS_WIN
10typedef HMODULE mplug_mod_t;
11# define MPLUG_EXPORT extern __declspec( dllexport )
12#else
13typedef void* mplug_mod_t;
14# define MPLUG_EXPORT
15#endif /* RETROFLAT_OS_WIN */
16
17MERROR_RETVAL mplug_load(
18 const char* plugin_path, mplug_mod_t* p_mod_exe );
19
20MERROR_RETVAL mplug_call(
21 mplug_mod_t mod_exe, const char* proc_name, void* data, size_t data_sz );
22
23void mplug_free( mplug_mod_t mod_exe );
24
25#ifdef MPLUG_C
26
27#if defined( RETROFLAT_OS_UNIX )
28# include <dlfcn.h>
29#endif /* RETROFLAT_OS_WIN */
30
31MERROR_RETVAL mplug_load(
32 const char* plugin_basename, mplug_mod_t* p_mod_exe
33) {
34 MERROR_RETVAL retval = MERROR_OK;
35 char plugin_path[MAUG_PATH_SZ_MAX + 1] = { 0 };
36#ifdef RETROFLAT_OS_WIN
37 size_t i = 0;
38# ifdef MAUG_WCHAR
39 wchar_t plugin_path_w[MAUG_PATH_SZ_MAX + 1] = { 0 };
40# endif /* MAUG_WCHAR */
41#endif /* RETROFLAT_OS_WIN */
42
43 memset( plugin_path, '\0', MAUG_PATH_SZ_MAX + 1 );
44
45#if defined( RETROFLAT_OS_UNIX )
46 maug_snprintf( plugin_path, MAUG_PATH_SZ_MAX, "%s.so", plugin_basename );
47 *p_mod_exe = dlopen( plugin_path, RTLD_LAZY );
48#elif defined( RETROFLAT_OS_WIN )
49 maug_snprintf(
50 plugin_path, MAUG_PATH_SZ_MAX, "%s.dll", plugin_basename );
51 for( i = 0 ; MAUG_PATH_SZ_MAX > i ; i++ ) {
52 if( '/' == plugin_path[i] ) {
53 plugin_path[i] = '\\';
54 }
55 }
56# ifdef MAUG_WCHAR
57 if( 0 == MultiByteToWideChar(
58 CP_ACP, MB_PRECOMPOSED, plugin_path, -1,
59 plugin_path_w, MAUG_PATH_SZ_MAX
60 ) ) {
61 error_printf(
62 "unable to convert wide path for module: %s", plugin_path );
63 retval = MERROR_FILE;
64 goto cleanup;
65 }
66
67 *p_mod_exe = (mplug_mod_t)LoadLibraryW( plugin_path_w );
68# else
69 *p_mod_exe = (mplug_mod_t)LoadLibrary( plugin_path );
70# endif /* MAUG_WCHAR */
71
72cleanup:
73
74# ifdef MAUG_WCHAR
75 if( NULL != plugin_path_w ) {
76 free( plugin_path_w );
77 }
78# endif /* MAUG_WCHAR */
79#else
80# pragma message( "warning: dlopen undefined!" )
81#endif /* RETROFLAT_OS_UNIX */
82
83 if( (mplug_mod_t)NULL == *p_mod_exe ) {
84 error_printf( "unable to load module: %s", plugin_path );
85 retval = MERROR_FILE;
86 }
87
88 return retval;
89}
90
91MERROR_RETVAL mplug_call(
92 mplug_mod_t mod_exe, const char* proc_name, void* data, size_t data_sz
93) {
94 MERROR_RETVAL retval = MERROR_OK;
95 mplug_proc_t plugin_proc = (mplug_proc_t)NULL;
96#ifdef RETROFLAT_OS_WIN
97 char proc_name_ex[MAUG_PATH_SZ_MAX + 1] = { 0 };
98# ifdef MAUG_WCHAR
99 wchar_t proc_name_ex_w[MAUG_PATH_SZ_MAX + 1] = { 0 };
100# endif /* MAUG_WCHAR */
101#endif /* RETROFLAT_OS_WIN */
102
103#ifdef RETROFLAT_OS_UNIX
104 plugin_proc = dlsym( mod_exe, proc_name );
105#elif defined( RETROFLAT_OS_WIN )
106 memset( proc_name_ex, '\0', MAUG_PATH_SZ_MAX + 1 );
107
108 /* Append a _ to the proc_name to match calling convention name scheme. */
109 maug_snprintf( proc_name_ex, MAUG_PATH_SZ_MAX, "%s_", proc_name );
110
111# if defined( MAUG_WCHAR ) && defined( RETROFLAT_API_WINCE )
112 if( 0 == MultiByteToWideChar(
113 CP_ACP, MB_PRECOMPOSED, proc_name_ex, -1, proc_name_ex_w,
114 MAUG_PATH_SZ_MAX
115 ) ) {
116 error_printf( "could not create wide proc name!" );
117 retval = MERROR_FILE;
118 goto cleanup;
119 }
120
121 plugin_proc = (mplug_proc_t)GetProcAddressW( mod_exe, proc_name_ex_w );
122# else
123 plugin_proc = (mplug_proc_t)GetProcAddress( mod_exe, proc_name_ex );
124# endif /* MAUG_WCHAR */
125#else
126# pragma message( "dlsym undefined!" )
127#endif
128
129 if( (mplug_proc_t)NULL == plugin_proc ) {
130 error_printf( "unable to load proc: %s", proc_name );
131 retval = MERROR_FILE;
132 goto cleanup;
133 }
134
135 retval = plugin_proc( data, data_sz );
136
137cleanup:
138 return retval;
139}
140
141void mplug_free( mplug_mod_t mod_exe ) {
142#ifdef RETROFLAT_OS_UNIX
143 dlclose( mod_exe );
144#elif defined( RETROFLAT_OS_WIN )
145 FreeLibrary( mod_exe );
146#else
147# pragma message( "dlclose undefined!" )
148#endif /* RETROFLAT_OS_UNIX || RETROFLAT_OS_WIN */
149}
150
151#endif /* MPLUG_C */
152
153#endif /* !MPLUG_H */
154
int MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition merror.h:19