|
|
|
| 1 |
|
/*** |
| 2 |
|
*appdomain.h |
| 3 |
|
* |
| 4 |
|
* Copyright (c) Microsoft Corporation. All rights reserved. |
| 5 |
|
* |
| 6 |
|
*Purpose: Utitily for cross App Domain Calls |
| 7 |
|
* |
| 8 |
|
* [Public] |
| 9 |
|
* |
| 10 |
|
****/ |
| 11 |
|
|
| 12 |
|
#pragma once |
| 13 |
|
|
| 14 |
|
#if !defined(_INC_MSCLR_APPDOMAIN) |
| 15 |
|
|
| 16 |
|
#ifndef __cplusplus_cli |
| 17 |
|
#error ERROR: msclr libraries require /clr and are not compatible with /clr:oldSyntax |
| 18 |
|
#endif |
| 19 |
|
|
| 20 |
|
#ifdef _M_CEE_PURE |
| 21 |
|
#error ERROR: msclr appdomain helpers can only be used in mixed mode. Use a cross-domain delegate in pure mode |
| 22 |
|
#endif |
| 23 |
|
#include <mscoree.h> |
| 24 |
|
#include <crtdbg.h> |
| 25 |
|
|
| 26 |
|
#if defined(_M_IX86) |
| 27 |
|
#define _MSCLR_STDCALL_DISTINCT 1 |
| 28 |
|
#elif defined(_M_IA64) |
| 29 |
|
#define _MSCLR_STDCALL_DISTINCT 0 |
| 30 |
|
#elif defined(_M_AMD64) |
| 31 |
|
#define _MSCLR_STDCALL_DISTINCT 0 |
| 32 |
|
#else |
| 33 |
|
#error Need to add setting for different CPU |
| 34 |
|
#endif |
| 35 |
|
|
| 36 |
|
namespace msclr |
| 37 |
|
{ |
| 38 |
|
|
| 39 |
|
namespace _detail |
| 40 |
|
{ |
| 41 |
|
|
| 42 |
|
/* helper functions */ |
| 43 |
|
|
| 44 |
|
inline |
| 45 |
|
void validate(HRESULT hr) |
| 46 |
|
{ |
| 47 |
|
_ASSERT(SUCCEEDED(hr)); |
| 48 |
|
if (FAILED(hr)) |
| 49 |
|
{ |
| 50 |
|
System::Runtime::InteropServices::Marshal::ThrowExceptionForHR(hr); |
| 51 |
|
} |
| 52 |
|
} |
| 53 |
|
|
| 54 |
|
inline |
| 55 |
|
ICLRRuntimeHost *get_clr_runtime_host(void) |
| 56 |
|
{ |
| 57 |
|
ICLRRuntimeHost *pClrHost = NULL; |
| 58 |
|
|
| 59 |
|
HRESULT hr = CorBindToRuntimeEx( |
| 60 |
|
NULL, // version of the runtime to request |
| 61 |
|
NULL, // flavor of the runtime to request |
| 62 |
|
0, // runtime startup flags |
| 63 |
|
CLSID_CLRRuntimeHost, // clsid of ICLRRuntimeHost |
| 64 |
|
IID_ICLRRuntimeHost, // IID of ICLRRuntimeHost |
| 65 |
|
(PVOID*)&pClrHost); // a pointer to our punk that we get back |
| 66 |
|
|
| 67 |
|
if (FAILED(hr)) |
| 68 |
|
{ |
| 69 |
|
if (pClrHost != NULL) |
| 70 |
|
{ |
| 71 |
|
pClrHost->Release(); |
| 72 |
|
} |
| 73 |
|
validate(hr); |
| 74 |
|
} |
| 75 |
|
return pClrHost; |
| 76 |
|
} |
| 77 |
|
|
| 78 |
|
/* callback struct */ |
| 79 |
|
|
| 80 |
|
/* __stdcall version */ |
| 81 |
|
|
| 82 |
|
#if _MSCLR_STDCALL_DISTINCT |
| 83 |
|
|
| 84 |
|
template <typename RetType> |
| 85 |
|
struct callback_stdcall_struct0 |
| 86 |
|
{ |
| 87 |
|
RetType (__stdcall *func)(); |
| 88 |
|
RetType retValue; |
| 89 |
|
|
| 90 |
|
static HRESULT __stdcall callback(void *cookie) |
| 91 |
|
{ |
| 92 |
|
HRESULT hr = E_FAIL; |
| 93 |
|
if (cookie == NULL) |
| 94 |
|
{ |
| 95 |
|
return hr; |
| 96 |
|
} |
| 97 |
|
callback_stdcall_struct0 *pcs = (callback_stdcall_struct0*)cookie; |
| 98 |
|
pcs->retValue = pcs->func(); |
| 99 |
|
hr = S_OK; |
| 100 |
|
return hr; |
| 101 |
|
} |
| 102 |
|
}; |
| 103 |
|
|
| 104 |
|
template <typename RetType, typename ArgType1> |
| 105 |
|
struct callback_stdcall_struct1 |
| 106 |
|
{ |
| 107 |
|
RetType (__stdcall *func)(ArgType1); |
| 108 |
|
RetType retValue; |
| 109 |
|
ArgType1 arg1; |
| 110 |
|
|
| 111 |
|
static HRESULT __stdcall callback(void *cookie) |
| 112 |
|
{ |
| 113 |
|
HRESULT hr = E_FAIL; |
| 114 |
|
if (cookie == NULL) |
| 115 |
|
{ |
| 116 |
|
return hr; |
| 117 |
|
} |
| 118 |
|
callback_stdcall_struct1 *pcs = (callback_stdcall_struct1*)cookie; |
| 119 |
|
pcs->retValue = pcs->func(pcs->arg1); |
| 120 |
|
hr = S_OK; |
| 121 |
|
return hr; |
| 122 |
|
} |
| 123 |
|
}; |
| 124 |
|
|
| 125 |
|
template <typename RetType, typename ArgType1, typename ArgType2> |
| 126 |
|
struct callback_stdcall_struct2 |
| 127 |
|
{ |
| 128 |
|
RetType (__stdcall *func)(ArgType1, ArgType2); |
| 129 |
|
RetType retValue; |
| 130 |
|
ArgType1 arg1; |
| 131 |
|
ArgType2 arg2; |
| 132 |
|
|
| 1768 |
|
HRESULT hr = E_FAIL; |
| 1769 |
|
if (cookie == NULL) |
| 1770 |
|
{ |
| 1771 |
|
return hr; |
| 1772 |
|
} |
| 1773 |
|
callback_cdecl_void_struct14 *pcs = (callback_cdecl_void_struct14*)cookie; |
| 1774 |
|
pcs->func(pcs->arg1, pcs->arg2, pcs->arg3, pcs->arg4, pcs->arg5, pcs->arg6, pcs->arg7, pcs->arg8, pcs->arg9, pcs->arg10, pcs->arg11, pcs->arg12, pcs->arg13, pcs->arg14); |
| 1775 |
|
hr = S_OK; |
| 1776 |
|
return hr; |
| 1777 |
|
} |
| 1778 |
|
}; |
| 1779 |
|
|
| 1780 |
|
template <typename ArgType1, typename ArgType2, typename ArgType3, typename ArgType4, typename ArgType5, typename ArgType6, typename ArgType7, typename ArgType8, typename ArgType9, typename ArgType10, typename ArgType11, typename ArgType12, typename ArgType13, typename ArgType14, typename ArgType15> |
| 1781 |
|
struct callback_cdecl_void_struct15 |
| 1782 |
|
{ |
| 1783 |
|
void (__cdecl * func)(ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, ArgType9, ArgType10, ArgType11, ArgType12, ArgType13, ArgType14, ArgType15); |
| 1784 |
|
ArgType1 arg1; |
| 1785 |
|
ArgType2 arg2; |
| 1786 |
|
ArgType3 arg3; |
| 1787 |
|
ArgType4 arg4; |
| 1788 |
|
ArgType5 arg5; |
| 1789 |
|
ArgType6 arg6; |
| 1790 |
|
ArgType7 arg7; |
| 1791 |
|
ArgType8 arg8; |
| 1792 |
|
ArgType9 arg9; |
| 1793 |
|
ArgType10 arg10; |
| 1794 |
|
ArgType11 arg11; |
| 1795 |
|
ArgType12 arg12; |
| 1796 |
|
ArgType13 arg13; |
| 1797 |
|
ArgType14 arg14; |
| 1798 |
|
ArgType15 arg15; |
| 1799 |
|
|
| 1800 |
|
static HRESULT __stdcall callback(void *cookie) |
| 1801 |
|
{ |
| 1802 |
|
HRESULT hr = E_FAIL; |
| 1803 |
|
if (cookie == NULL) |
| 1804 |
|
{ |
| 1805 |
|
return hr; |
| 1806 |
|
} |
| 1807 |
|
callback_cdecl_void_struct15 *pcs = (callback_cdecl_void_struct15*)cookie; |
| 1808 |
|
pcs->func(pcs->arg1, pcs->arg2, pcs->arg3, pcs->arg4, pcs->arg5, pcs->arg6, pcs->arg7, pcs->arg8, pcs->arg9, pcs->arg10, pcs->arg11, pcs->arg12, pcs->arg13, pcs->arg14, pcs->arg15); |
| 1809 |
|
hr = S_OK; |
| 1810 |
|
return hr; |
| 1811 |
|
} |
| 1812 |
|
}; |
| 1813 |
|
|
| 1814 |
|
} // namespace _detail |
| 1815 |
|
|
| 1816 |
|
/* __stdcall version */ |
| 1817 |
|
#if _MSCLR_STDCALL_DISTINCT |
| 1818 |
|
|
| 1819 |
|
template <typename RetType> |
| 1820 |
|
RetType inline call_in_appdomain(DWORD dwAppDomainId, RetType (__stdcall * func)()) |
| 1821 |
|
{ |
| 1822 |
|
ICLRRuntimeHost *pClrHost = _detail::get_clr_runtime_host(); |
| 1823 |
|
_detail::callback_stdcall_struct0<RetType> cs; |
| 1824 |
|
|
| 1825 |
|
// fill up the callback_stdcall_struct |
| 1826 |
|
cs.func = func; |
| 1827 |
|
|
| 1828 |
|
// call the function |
| 1829 |
|
HRESULT hr = pClrHost->ExecuteInAppDomain(dwAppDomainId, &cs.callback, &cs); |
| 1830 |
|
pClrHost->Release(); |
| 1831 |
|
_detail::validate(hr); |
| 1832 |
|
|
| 1833 |
|
return cs.retValue; |
| 1834 |
|
} |
| 1835 |
|
|
| 1836 |
|
template <typename RetType, typename ArgType1> |
| 1837 |
|
RetType inline call_in_appdomain(DWORD dwAppDomainId, RetType (__stdcall * func)(ArgType1), ArgType1 arg1) |
| 1838 |
|
{ |
| 1839 |
|
ICLRRuntimeHost *pClrHost = _detail::get_clr_runtime_host(); |
| 1840 |
|
_detail::callback_stdcall_struct1<RetType, ArgType1> cs; |
| 1841 |
|
|
| 1842 |
|
// fill up the callback_stdcall_struct |
| 1843 |
|
cs.func = func; |
| 1844 |
|
cs.arg1 = arg1; |
| 1845 |
|
|
| 1846 |
|
// call the function |
| 1847 |
|
HRESULT hr = pClrHost->ExecuteInAppDomain(dwAppDomainId, &cs.callback, &cs); |
| 1848 |
|
pClrHost->Release(); |
| 1849 |
|
_detail::validate(hr); |
| 1850 |
|
|
| 1851 |
|
return cs.retValue; |
| 1852 |
|
} |
| 1853 |
|
|
| 1854 |
|
template <typename RetType, typename ArgType1, typename ArgType2> |
| 1855 |
|
RetType inline call_in_appdomain(DWORD dwAppDomainId, RetType (__stdcall * func)(ArgType1, ArgType2), ArgType1 arg1, ArgType2 arg2) |
| 1856 |
|
{ |
| 1857 |
|
ICLRRuntimeHost *pClrHost = _detail::get_clr_runtime_host(); |
| 1858 |
|
_detail::callback_stdcall_struct2<RetType, ArgType1, ArgType2> cs; |
| 1859 |
|
|
| 1860 |
|
// fill up the callback_stdcall_struct |
| 1861 |
|
cs.func = func; |
| 1862 |
|
cs.arg1 = arg1; |
| 1863 |
|
cs.arg2 = arg2; |
| 1864 |
|
|
| 1865 |
|
// call the function |
| 1866 |
|
HRESULT hr = pClrHost->ExecuteInAppDomain(dwAppDomainId, &cs.callback, &cs); |
| 1867 |
|
pClrHost->Release(); |
| 3278 |
|
cs.arg5 = arg5; |
| 3279 |
|
cs.arg6 = arg6; |
| 3280 |
|
cs.arg7 = arg7; |
| 3281 |
|
cs.arg8 = arg8; |
| 3282 |
|
cs.arg9 = arg9; |
| 3283 |
|
cs.arg10 = arg10; |
| 3284 |
|
cs.arg11 = arg11; |
| 3285 |
|
cs.arg12 = arg12; |
| 3286 |
|
cs.arg13 = arg13; |
| 3287 |
|
cs.arg14 = arg14; |
| 3288 |
|
|
| 3289 |
|
// call the function |
| 3290 |
|
HRESULT hr = pClrHost->ExecuteInAppDomain(dwAppDomainId, &cs.callback, &cs); |
| 3291 |
|
pClrHost->Release(); |
| 3292 |
|
_detail::validate(hr); |
| 3293 |
|
} |
| 3294 |
|
|
| 3295 |
|
template <typename ArgType1, typename ArgType2, typename ArgType3, typename ArgType4, typename ArgType5, typename ArgType6, typename ArgType7, typename ArgType8, typename ArgType9, typename ArgType10, typename ArgType11, typename ArgType12, typename ArgType13, typename ArgType14, typename ArgType15> |
| 3296 |
|
void inline call_in_appdomain(DWORD dwAppDomainId, void (__cdecl * func)(ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, ArgType9, ArgType10, ArgType11, ArgType12, ArgType13, ArgType14, ArgType15), ArgType1 arg1, ArgType2 arg2, ArgType3 arg3, ArgType4 arg4, ArgType5 arg5, ArgType6 arg6, ArgType7 arg7, ArgType8 arg8, ArgType9 arg9, ArgType10 arg10, ArgType11 arg11, ArgType12 arg12, ArgType13 arg13, ArgType14 arg14, ArgType15 arg15) |
| 3297 |
|
{ |
| 3298 |
|
ICLRRuntimeHost *pClrHost = _detail::get_clr_runtime_host(); |
| 3299 |
|
_detail::callback_cdecl_void_struct15<ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, ArgType9, ArgType10, ArgType11, ArgType12, ArgType13, ArgType14, ArgType15> cs; |
| 3300 |
|
|
| 3301 |
|
// fill up the callback_cdecl_struct |
| 3302 |
|
cs.func = func; |
| 3303 |
|
cs.arg1 = arg1; |
| 3304 |
|
cs.arg2 = arg2; |
| 3305 |
|
cs.arg3 = arg3; |
| 3306 |
|
cs.arg4 = arg4; |
| 3307 |
|
cs.arg5 = arg5; |
| 3308 |
|
cs.arg6 = arg6; |
| 3309 |
|
cs.arg7 = arg7; |
| 3310 |
|
cs.arg8 = arg8; |
| 3311 |
|
cs.arg9 = arg9; |
| 3312 |
|
cs.arg10 = arg10; |
| 3313 |
|
cs.arg11 = arg11; |
| 3314 |
|
cs.arg12 = arg12; |
| 3315 |
|
cs.arg13 = arg13; |
| 3316 |
|
cs.arg14 = arg14; |
| 3317 |
|
cs.arg15 = arg15; |
| 3318 |
|
|
| 3319 |
|
// call the function |
| 3320 |
|
HRESULT hr = pClrHost->ExecuteInAppDomain(dwAppDomainId, &cs.callback, &cs); |
| 3321 |
|
pClrHost->Release(); |
| 3322 |
|
_detail::validate(hr); |
| 3323 |
|
} |
| 3324 |
|
|
| 3325 |
|
} // namespace msclr |
| 3326 |
|
|
| 3327 |
|
#define _INC_MSCLR_APPDOMAIN |
| 3328 |
|
|
| 3329 |
|
#endif // _INC_MSCLR_APPDOMAIN |
| 3330 |
|
|
|
|
|