mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-21 08:28:53 +02:00
Merge branch 'win32-clear-com' into 'main'
GWin32: Add g_win32_com_clear() See merge request GNOME/glib!4392
This commit is contained in:
@@ -43,6 +43,11 @@ G_BEGIN_DECLS
|
|||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
|
|
||||||
|
/* needed include for C++ builds; including this in C mode will cause havoc of type conflicts */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#include <unknwn.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To get prototypes for the following POSIXish functions, you have to
|
* To get prototypes for the following POSIXish functions, you have to
|
||||||
* include the indicated non-POSIX headers. The functions are defined
|
* include the indicated non-POSIX headers. The functions are defined
|
||||||
@@ -135,8 +140,60 @@ gboolean g_win32_check_windows_version (const gint major,
|
|||||||
const gint spver,
|
const gint spver,
|
||||||
const GWin32OSType os_type);
|
const GWin32OSType os_type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_win32_clear_com:
|
||||||
|
* @com_obj: (not optional) (nullable): Pointer to COM object pointer to release and clear
|
||||||
|
*
|
||||||
|
* Releases the referenced COM object, and clears its pointer to `NULL`.
|
||||||
|
*
|
||||||
|
* The @com_obj pointer must not be `NULL`.
|
||||||
|
*
|
||||||
|
* If @com_obj references a `NULL` COM object, this function is a no-op.
|
||||||
|
*
|
||||||
|
* This is equivalent to `g_clear_object()` for dealing with
|
||||||
|
* Windows COM objects.
|
||||||
|
*
|
||||||
|
* Since: 2.84
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
|
||||||
|
#define g_win32_clear_com(com_obj) \
|
||||||
|
G_STMT_START {\
|
||||||
|
IUnknown **unknown_com_obj = (IUnknown **)(com_obj); \
|
||||||
|
\
|
||||||
|
if (*unknown_com_obj) \
|
||||||
|
{ \
|
||||||
|
(*unknown_com_obj)->lpVtbl->Release (*unknown_com_obj); \
|
||||||
|
*unknown_com_obj = NULL; \
|
||||||
|
} \
|
||||||
|
} G_STMT_END \
|
||||||
|
GLIB_AVAILABLE_MACRO_IN_2_84
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/*
|
||||||
|
* There are COM objects that only have C++-style definitions, such as DirectWrite
|
||||||
|
* from the Windows SDK (albeit a C interface is provided for the mingw-w64 toolchain),
|
||||||
|
* so we need to have a C++ version for this
|
||||||
|
*/
|
||||||
|
template <typename com_interface>
|
||||||
|
static inline void
|
||||||
|
g_win32_clear_com (com_interface **com_obj)
|
||||||
|
{
|
||||||
|
IUnknown **unknown_com_obj = reinterpret_cast<IUnknown **>(com_obj);
|
||||||
|
|
||||||
|
if (*unknown_com_obj != NULL)
|
||||||
|
{
|
||||||
|
(*unknown_com_obj)->Release ();
|
||||||
|
*unknown_com_obj = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* G_PLATFORM_WIN32 */
|
#endif /* G_PLATFORM_WIN32 */
|
||||||
|
|
||||||
#endif /* __G_WIN32_H__ */
|
#endif /* __G_WIN32_H__ */
|
||||||
|
@@ -19,6 +19,10 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
#include <wincodec.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined (G_CXX_STD_VERSION) || !defined (G_CXX_STD_CHECK_VERSION)
|
#if !defined (G_CXX_STD_VERSION) || !defined (G_CXX_STD_CHECK_VERSION)
|
||||||
#error G_CXX_STD_VERSION is not defined
|
#error G_CXX_STD_VERSION is not defined
|
||||||
#endif
|
#endif
|
||||||
@@ -532,6 +536,31 @@ test_string_free (void)
|
|||||||
g_free (data);
|
g_free (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
static void
|
||||||
|
test_clear_com (void)
|
||||||
|
{
|
||||||
|
IWICImagingFactory *tmp;
|
||||||
|
IWICImagingFactory *o = NULL;
|
||||||
|
|
||||||
|
CoInitialize (NULL);
|
||||||
|
g_win32_clear_com (&o);
|
||||||
|
g_assert_null (o);
|
||||||
|
g_assert_true (SUCCEEDED (CoCreateInstance (CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (void **)&tmp)));
|
||||||
|
g_assert_nonnull (tmp);
|
||||||
|
tmp->QueryInterface (IID_IWICImagingFactory, (void **)&o); /* IWICImagingFactory::QueryInterface increments tmp's refcount */
|
||||||
|
g_assert_nonnull (o);
|
||||||
|
g_assert_cmpint (tmp->AddRef (), ==, 3); /* tmp's refcount incremented again */
|
||||||
|
g_win32_clear_com (&o); /* tmp's refcount gets decremented */
|
||||||
|
g_assert_null (o);
|
||||||
|
g_assert_cmpint (tmp->Release (), ==, 1); /* tmp's refcount gets decremented, again */
|
||||||
|
g_win32_clear_com (&tmp);
|
||||||
|
g_assert_null (tmp);
|
||||||
|
|
||||||
|
CoUninitialize ();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -566,5 +595,8 @@ main (int argc, char *argv[])
|
|||||||
g_test_add_func ("/C++/string-append", test_string_append);
|
g_test_add_func ("/C++/string-append", test_string_append);
|
||||||
g_test_add_func ("/C++/string-free", test_string_free);
|
g_test_add_func ("/C++/string-free", test_string_free);
|
||||||
|
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
g_test_add_func ("/C++/test_clear_com", test_clear_com);
|
||||||
|
#endif
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
@@ -209,6 +209,7 @@ if have_cxx
|
|||||||
'cxx' : {
|
'cxx' : {
|
||||||
'source' : ['cxx.cpp'],
|
'source' : ['cxx.cpp'],
|
||||||
'suite': ['cpp'],
|
'suite': ['cpp'],
|
||||||
|
'dependencies' : [wincodecs],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,6 +219,7 @@ if have_cxx
|
|||||||
'source' : ['cxx.cpp'],
|
'source' : ['cxx.cpp'],
|
||||||
'suite' : ['cpp'],
|
'suite' : ['cpp'],
|
||||||
'cpp_args' : [arg, '-D_G_EXPECTED_CXX_STANDARD="@0@"'.format(std)],
|
'cpp_args' : [arg, '-D_G_EXPECTED_CXX_STANDARD="@0@"'.format(std)],
|
||||||
|
'dependencies' : [wincodecs],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
endforeach
|
endforeach
|
||||||
@@ -246,7 +248,9 @@ if host_machine.system() == 'windows'
|
|||||||
}
|
}
|
||||||
endif
|
endif
|
||||||
glib_tests += {
|
glib_tests += {
|
||||||
'win32' : {},
|
'win32' : {
|
||||||
|
'dependencies' : [wincodecs],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
glib_tests += {
|
glib_tests += {
|
||||||
|
@@ -28,6 +28,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
#define COBJMACROS
|
||||||
|
#include <wincodec.h>
|
||||||
|
|
||||||
static char *argv0 = NULL;
|
static char *argv0 = NULL;
|
||||||
|
|
||||||
#include "../gwin32-private.c"
|
#include "../gwin32-private.c"
|
||||||
@@ -154,6 +157,29 @@ veh_debugger (int argc, char *argv[])
|
|||||||
g_fprintf (stderr, "Debugger invoked, attaching to %lu and signalling %" G_GUINTPTR_FORMAT, pid, event);
|
g_fprintf (stderr, "Debugger invoked, attaching to %lu and signalling %" G_GUINTPTR_FORMAT, pid, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_clear_com (void)
|
||||||
|
{
|
||||||
|
IWICImagingFactory *o = NULL;
|
||||||
|
IWICImagingFactory *tmp;
|
||||||
|
|
||||||
|
CoInitialize (NULL);
|
||||||
|
g_win32_clear_com (&o);
|
||||||
|
g_assert_null (o);
|
||||||
|
g_assert_true (SUCCEEDED (CoCreateInstance (&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void **)&tmp)));
|
||||||
|
g_assert_nonnull (tmp);
|
||||||
|
IWICImagingFactory_QueryInterface (tmp, &IID_IWICImagingFactory, (void **)&o); /* IWICImagingFactory_QueryInterface increments tmp's refcount */
|
||||||
|
g_assert_nonnull (o);
|
||||||
|
g_assert_cmpint (IWICImagingFactory_AddRef (tmp), ==, 3); /* tmp's refcount incremented, again */
|
||||||
|
g_win32_clear_com (&o); /* tmp's refcount decrements */
|
||||||
|
g_assert_null (o);
|
||||||
|
g_assert_cmpint (IWICImagingFactory_Release (tmp), ==, 1); /* tmp's refcount decrements, again */
|
||||||
|
g_win32_clear_com (&tmp);
|
||||||
|
g_assert_null (tmp);
|
||||||
|
|
||||||
|
CoUninitialize ();
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc,
|
main (int argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
@@ -177,6 +203,7 @@ main (int argc,
|
|||||||
g_test_add_func ("/win32/subprocess/debuggee", test_veh_debuggee);
|
g_test_add_func ("/win32/subprocess/debuggee", test_veh_debuggee);
|
||||||
g_test_add_func ("/win32/subprocess/access_violation", test_access_violation);
|
g_test_add_func ("/win32/subprocess/access_violation", test_access_violation);
|
||||||
g_test_add_func ("/win32/subprocess/illegal_instruction", test_illegal_instruction);
|
g_test_add_func ("/win32/subprocess/illegal_instruction", test_illegal_instruction);
|
||||||
|
g_test_add_func ("/win32/com/clear", test_clear_com);
|
||||||
|
|
||||||
return g_test_run();
|
return g_test_run();
|
||||||
}
|
}
|
||||||
|
@@ -2338,8 +2338,11 @@ endif
|
|||||||
|
|
||||||
if host_system == 'windows'
|
if host_system == 'windows'
|
||||||
winsock2 = cc.find_library('ws2_32')
|
winsock2 = cc.find_library('ws2_32')
|
||||||
|
# Used for g_win32_clear_com() tests...
|
||||||
|
wincodecs = cc.find_library('windowscodecs')
|
||||||
else
|
else
|
||||||
winsock2 = not_found
|
winsock2 = not_found
|
||||||
|
wincodecs = not_found
|
||||||
endif
|
endif
|
||||||
|
|
||||||
selinux_dep = []
|
selinux_dep = []
|
||||||
|
Reference in New Issue
Block a user