22#include <com/sun/star/uno/genfunc.hxx>
25#include <typelib/typedescription.hxx>
37static typelib_TypeClass
40 typelib_TypeDescriptionReference* pReturnTypeRef,
41 const sal_Int32 nParams, typelib_MethodParameter* pParams,
void** pCallStack,
42 void**
const pReturnAddr)
47 TYPELIB_DANGER_GET(&pReturnTD, pReturnTypeRef);
50 int nFirstRealParam = 2;
51 if (pReturnAddr == pCallStack)
54 void* pUnoReturn =
nullptr;
56 void* pCppReturn =
nullptr;
61 pUnoReturn = pReturnAddr;
64 pCppReturn = pCallStack[nFirstRealParam++];
66 ? alloca(pReturnTD->nSize)
72 void** pUnoArgs =
static_cast<void**
>(alloca(
sizeof(
void*) * nParams));
75 void** pCppArgs =
static_cast<void**
>(alloca(
sizeof(
void*) * nParams));
78 sal_Int32 nTempIndex = 0;
80 sal_Int32* pTempIndexes =
static_cast<sal_Int32*
>(alloca(
sizeof(sal_Int32) * nParams));
85 for (std::pair<sal_Int32, void**>
p(0, pCallStack + nFirstRealParam);
p.first < nParams;
86 ++
p.first, ++
p.second)
88 const auto&
nPos =
p.first;
89 auto& pCppIncomingParams =
p.second;
91 const typelib_MethodParameter& rParam = pParams[
nPos];
93 TYPELIB_DANGER_GET(&pParamTD, rParam.pTypeRef);
97 pCppArgs[
nPos] = pCppIncomingParams;
98 pUnoArgs[
nPos] = pCppIncomingParams;
99 if (
sizeof(
void*) ==
sizeof(sal_Int32))
101 switch (pParamTD->eTypeClass)
103 case typelib_TypeClass_HYPER:
104 case typelib_TypeClass_UNSIGNED_HYPER:
105 case typelib_TypeClass_DOUBLE:
106 ++pCppIncomingParams;
112 TYPELIB_DANGER_RELEASE(pParamTD);
116 pCppArgs[
nPos] = *pCppIncomingParams;
121 pUnoArgs[
nPos] = alloca(pParamTD->nSize);
123 pTempIndexes[nTempIndex] =
nPos;
124 ppTempParamTD[nTempIndex++] = pParamTD;
129 ::uno_copyAndConvertData(pUnoArgs[
nPos] = alloca(pParamTD->nSize),
130 *pCppIncomingParams, pParamTD,
133 pTempIndexes[nTempIndex] =
nPos;
134 ppTempParamTD[nTempIndex++] = pParamTD;
138 pUnoArgs[
nPos] = *pCppIncomingParams;
139 TYPELIB_DANGER_RELEASE(pParamTD);
149 pThis->
getUnoI()->pDispatcher(pThis->
getUnoI(), pMemberTD, pUnoReturn, pUnoArgs, &pUnoExc);
157 const sal_Int32
nIndex = pTempIndexes[nTempIndex];
159 ::uno_destructData(pUnoArgs[
nIndex], ppTempParamTD[nTempIndex],
nullptr);
160 TYPELIB_DANGER_RELEASE(ppTempParamTD[nTempIndex]);
163 TYPELIB_DANGER_RELEASE(pReturnTD);
168 return typelib_TypeClass_VOID;
175 const sal_Int32
nIndex = pTempIndexes[nTempIndex];
181 ::uno_destructData(pCppArgs[
nIndex], pParamTD, uno::cpp_release);
182 ::uno_copyAndConvertData(pCppArgs[
nIndex], pUnoArgs[
nIndex], pParamTD,
186 ::uno_destructData(pUnoArgs[
nIndex], pParamTD,
nullptr);
188 TYPELIB_DANGER_RELEASE(pParamTD);
194 if (pUnoReturn != pCppReturn)
196 ::uno_copyAndConvertData(pCppReturn, pUnoReturn, pReturnTD,
199 ::uno_destructData(pUnoReturn, pReturnTD,
nullptr);
201 *pReturnAddr = pCppReturn;
205 return typelib_TypeClass_VOID;
208 typelib_TypeClass eRet = pReturnTD->eTypeClass;
209 TYPELIB_DANGER_RELEASE(pReturnTD);
215typelib_TypeClass __cdecl
cpp_mediate(
void** pCallStack,
const sal_Int32 nFunctionIndex,
216 const sal_Int32 nVtableOffset,
217 sal_Int64*
const pRegisterReturn)
228 void**
const pReturnAddr
229 = pRegisterReturn ?
reinterpret_cast<void**
>(pRegisterReturn) : pCallStack;
231 void*
const pThis =
static_cast<char*
>(pCallStack[pRegisterReturn ? 1 : 2]) - nVtableOffset;
235 typelib_InterfaceTypeDescription* pInterfaceTD = pCppI->
getTypeDescr();
237 SAL_INFO(
"bridges",
"cpp_vtable_call: pCallStack=["
238 << std::hex << pCallStack[0] <<
"," << pCallStack[1] <<
","
239 << pCallStack[2] <<
",...], pThis=" << pThis <<
", pCppI=" << pCppI
240 << std::dec <<
", nFunctionIndex=" << nFunctionIndex
241 <<
", nVtableOffset=" << nVtableOffset);
242 SAL_INFO(
"bridges",
"name=" << OUString::unacquired(&pInterfaceTD->aBase.pTypeName));
244 if (nFunctionIndex >= pInterfaceTD->nMapFunctionIndexToMemberIndex)
246 OUString sError =
"illegal " + OUString::unacquired(&pInterfaceTD->aBase.pTypeName)
247 +
" vtable index " + OUString::number(nFunctionIndex) +
"/"
248 + OUString::number(pInterfaceTD->nMapFunctionIndexToMemberIndex);
250 throw uno::RuntimeException(sError,
static_cast<uno::XInterface*
>(pThis));
254 sal_Int32 nMemberPos = pInterfaceTD->pMapFunctionIndexToMemberIndex[nFunctionIndex];
255 assert(nMemberPos < pInterfaceTD->nAllMembers);
257 uno::TypeDescription aMemberDescr(pInterfaceTD->ppAllMembers[nMemberPos]);
259 SAL_INFO(
"bridges",
"Calling " << OUString::unacquired(&aMemberDescr.get()->pTypeName));
261 typelib_TypeClass eRet = typelib_TypeClass_VOID;
262 switch (aMemberDescr.get()->eTypeClass)
264 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
266 typelib_TypeDescriptionReference* pAttrTypeRef
267 =
reinterpret_cast<typelib_InterfaceAttributeTypeDescription*
>(aMemberDescr.get())
270 if (pInterfaceTD->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
272 eRet =
cpp2uno_call(pCppI, aMemberDescr.get(), pAttrTypeRef, 0,
nullptr, pCallStack,
277 typelib_MethodParameter aParam;
278 aParam.pTypeRef = pAttrTypeRef;
282 eRet =
cpp2uno_call(pCppI, aMemberDescr.get(),
nullptr, 1, &aParam, pCallStack,
287 case typelib_TypeClass_INTERFACE_METHOD:
290 switch (nFunctionIndex)
295 eRet = typelib_TypeClass_VOID;
299 eRet = typelib_TypeClass_VOID;
303 const unsigned int nCppStackPos = (pReturnAddr == pCallStack) ? 4 : 3;
307 static_cast<uno::Type*
>(pCallStack[nCppStackPos])->getTypeLibType());
310 uno::XInterface* pInterface =
nullptr;
315 reinterpret_cast<typelib_InterfaceTypeDescription*
>(pQueryTD));
319 const unsigned int nReturnAddrPos = nCppStackPos - 1;
320 ::uno_any_construct(
static_cast<uno_Any*
>(pCallStack[nReturnAddrPos]),
321 &pInterface, pQueryTD, uno::cpp_acquire);
322 pInterface->release();
323 TYPELIB_DANGER_RELEASE(pQueryTD);
325 *pReturnAddr = pCallStack[nReturnAddrPos];
326 eRet = typelib_TypeClass_ANY;
329 TYPELIB_DANGER_RELEASE(pQueryTD);
335 typelib_InterfaceMethodTypeDescription* pMethodTD
336 =
reinterpret_cast<typelib_InterfaceMethodTypeDescription*
>(
339 eRet =
cpp2uno_call(pCppI, aMemberDescr.get(), pMethodTD->pReturnTypeRef,
340 pMethodTD->nParams, pMethodTD->pParams, pCallStack,
347 throw uno::RuntimeException(
"no member description found!",
348 static_cast<uno::XInterface*
>(pThis));
uno_Mapping * getUno2Cpp()
uno_ExtEnvironment * getCppEnv()
uno_Mapping * getCpp2Uno()
A cpp proxy wrapping a uno interface.
uno_Interface * getUnoI()
static CppInterfaceProxy * castInterfaceToProxy(void *pInterface)
typelib_InterfaceTypeDescription * getTypeDescr()
const OUString & getOid() const
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
struct _typelib_TypeDescription typelib_TypeDescription
typelib_TypeClass __cdecl cpp_mediate(void **pCallStack, const sal_Int32 nFunctionIndex, const sal_Int32 nVtableOffset, sal_Int64 *const pRegisterReturn)
static typelib_TypeClass cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy *pThis, const typelib_TypeDescription *pMemberTD, typelib_TypeDescriptionReference *pReturnTypeRef, const sal_Int32 nParams, typelib_MethodParameter *pParams, void **pCallStack, void **const pReturnAddr)
void msvc_raiseException(uno_Any *pUnoExc, uno_Mapping *pUno2Cpp)
bool isSimpleType(typelib_TypeClass typeClass)
Determines whether a type is a "simple" type (VOID, BOOLEAN, BYTE, SHORT, UNSIGNED SHORT,...
bool relatesToInterfaceType(typelib_TypeDescription const *type)
Determines whether a type relates to an interface type (is itself an interface type,...