|
|
|
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 |
|
|
|
|
|