LibreOffice Module basic (master) 1
dllmgr-x86.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <sal/config.h>
21
22#if defined(_WIN32)
23#include <prewin.h>
24#include <postwin.h>
25#endif
26
27#include <algorithm>
28#include <cstddef>
29#include <map>
30#include <vector>
31
32#include <basic/sbx.hxx>
33#include <basic/sbxvar.hxx>
34#include <comphelper/string.hxx>
35#include "runtime.hxx"
36#include <osl/thread.h>
37#include <rtl/ref.hxx>
38#include <rtl/string.hxx>
39#include <rtl/ustring.hxx>
40#include <sal/log.hxx>
43#include <o3tl/string_view.hxx>
44
45#undef max
46
47#include "dllmgr.hxx"
48
49using namespace css;
50using namespace css::uno;
51
52/* Open issues:
53
54 Missing support for functions returning structs (see TODO in call()).
55
56 Missing support for additional data types (64 bit integers, Any, ...; would
57 trigger assert(false) in various switches).
58
59 It is assumed that the variables passed into SbiDllMgr::Call to represent
60 the arguments and return value have types that exactly match the Declare
61 statement; it would be better if this code had access to the function
62 signature from the Declare statement, so that it could convert the passed
63 variables accordingly.
64*/
65
66extern "C" {
67
68int __stdcall DllMgr_call32(FARPROC, void const * stack, std::size_t size);
69double __stdcall DllMgr_callFp(FARPROC, void const * stack, std::size_t size);
70
71}
72
73namespace {
74
75char * address(std::vector< char > & blob) {
76 return blob.empty() ? 0 : &blob[0];
77}
78
79ErrCode convert(OUString const & source, OString * target) {
80 return
81 source.convertToString(
82 target, osl_getThreadTextEncoding(),
83 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
84 RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
86 //TODO: more specific errcode?
87}
88
89ErrCode convert(char const * source, sal_Int32 length, OUString * target) {
90 return
91 rtl_convertStringToUString(
92 &target->pData, source, length, osl_getThreadTextEncoding(),
93 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
94 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
95 RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))
97 //TODO: more specific errcode?
98}
99
100struct UnmarshalData {
101 UnmarshalData(SbxVariable * theVariable, void * theBuffer):
102 variable(theVariable), buffer(theBuffer) {}
103
104 SbxVariable * variable;
105 void * buffer;
106};
107
108struct StringData: public UnmarshalData {
109 StringData(SbxVariable * theVariable, void * theBuffer, bool theSpecial):
110 UnmarshalData(theVariable, theBuffer), special(theSpecial) {}
111
112 bool special;
113};
114
115class MarshalData {
116public:
117 MarshalData() = default;
118 MarshalData(const MarshalData&) = delete;
119 const MarshalData& operator=(const MarshalData&) = delete;
120
121 std::vector< char > * newBlob() {
122 blobs_.push_back(std::vector< char >());
123 return &blobs_.back();
124 }
125
126 std::vector< UnmarshalData > unmarshal;
127
128 std::vector< StringData > unmarshalStrings;
129
130private:
131 std::vector< std::vector< char > > blobs_;
132};
133
134std::size_t align(std::size_t address, std::size_t alignment) {
135 // alignment = 2^k for some k >= 0
136 return (address + (alignment - 1)) & ~(alignment - 1);
137}
138
139char * align(
140 std::vector< char > & blob, std::size_t alignment, std::size_t offset,
141 std::size_t add)
142{
143 std::vector< char >::size_type n = blob.size();
144 n = align(n - offset, alignment) + offset; //TODO: overflow in align()
145 blob.resize(n + add); //TODO: overflow
146 return address(blob) + n;
147}
148
149template< typename T > void add(
150 std::vector< char > & blob, T const & data, std::size_t alignment,
151 std::size_t offset)
152{
153 *reinterpret_cast< T * >(align(blob, alignment, offset, sizeof (T))) = data;
154}
155
156std::size_t alignment(SbxVariable * variable) {
157 assert(variable != 0);
158 if ((variable->GetType() & SbxARRAY) == 0) {
159 switch (variable->GetType()) {
160 case SbxINTEGER:
161 return 2;
162 case SbxLONG:
163 case SbxSINGLE:
164 case SbxSTRING:
165 return 4;
166 case SbxDOUBLE:
167 return 8;
168 case SbxOBJECT:
169 {
170 std::size_t n = 1;
171 SbxObject* pobj = dynamic_cast<SbxObject*>(variable->GetObject());
172 assert(pobj);
173 SbxArray* props = pobj->GetProperties();
174 for (sal_uInt32 i = 0; i < props->Count(); ++i)
175 {
176 n = std::max(n, alignment(props->Get(i)));
177 }
178 return n;
179 }
180 case SbxBOOL:
181 case SbxBYTE:
182 return 1;
183 default:
184 assert(false);
185 return 1;
186 }
187 } else {
188 SbxDimArray * arr = dynamic_cast<SbxDimArray*>( variable->GetObject() );
189 assert(arr);
190 sal_Int32 dims = arr->GetDims();
191 std::vector< sal_Int32 > low(dims);
192 for (sal_Int32 i = 0; i < dims; ++i) {
193 sal_Int32 up;
194 arr->GetDim(i + 1, low[i], up);
195 }
196 return alignment(arr->Get(&low[0]));
197 }
198}
199
200ErrCode marshal(
201 bool outer, SbxVariable * variable, bool special,
202 std::vector< char > & blob, std::size_t offset, MarshalData & data);
203
204ErrCode marshalString(
205 SbxVariable * variable, bool special, MarshalData & data, void ** buffer)
206{
207 assert(variable != 0 && buffer != 0);
208 OString str;
209 ErrCode e = convert(variable->GetOUString(), &str);
210 if (e != ERRCODE_NONE) {
211 return e;
212 }
213 std::vector< char > * blob = data.newBlob();
214 blob->insert(
215 blob->begin(), str.getStr(), str.getStr() + str.getLength() + 1);
216 *buffer = address(*blob);
217 data.unmarshalStrings.push_back(StringData(variable, *buffer, special));
218 return ERRCODE_NONE;
219}
220
221ErrCode marshalStruct(
222 SbxVariable * variable, std::vector< char > & blob, std::size_t offset,
223 MarshalData & data)
224{
225 assert(variable != 0);
226 SbxObject* pobj = dynamic_cast<SbxObject*>(variable->GetObject());
227 assert(pobj);
228 SbxArray* props = pobj->GetProperties();
229 for (sal_uInt32 i = 0; i < props->Count(); ++i)
230 {
231 ErrCode e = marshal(false, props->Get(i), false, blob, offset, data);
232 if (e != ERRCODE_NONE) {
233 return e;
234 }
235 }
236 return ERRCODE_NONE;
237}
238
239ErrCode marshalArray(
240 SbxVariable * variable, std::vector< char > & blob, std::size_t offset,
241 MarshalData & data)
242{
243 assert(variable != 0);
244 SbxDimArray * arr = dynamic_cast<SbxDimArray*>( variable->GetObject() );
245 assert(arr);
246 sal_Int32 dims = arr->GetDims();
247 std::vector< sal_Int32 > low(dims);
248 std::vector< sal_Int32 > up(dims);
249 for (sal_Int32 i = 0; i < dims; ++i) {
250 arr->GetDim(i + 1, low[i], up[i]);
251 }
252 for (std::vector< sal_Int32 > idx = low;;) {
253 ErrCode e = marshal(false, arr->Get(&idx[0]), false, blob, offset, data);
254 if (e != ERRCODE_NONE) {
255 return e;
256 }
257 sal_Int32 i = dims - 1;
258 while (idx[i] == up[i]) {
259 idx[i] = low[i];
260 if (i == 0) {
261 return ERRCODE_NONE;
262 }
263 --i;
264 }
265 ++idx[i];
266 }
267}
268
269// 8-aligned structs are only 4-aligned on stack, so alignment of members in
270// such structs must take that into account via "offset"
271ErrCode marshal(
272 bool outer, SbxVariable * variable, bool special,
273 std::vector< char > & blob, std::size_t offset, MarshalData & data)
274{
275 assert(variable != 0);
276
277 SbxDataType eVarType = variable->GetType();
278 bool bByVal = !(variable->GetFlags() & SbxFlagBits::Reference);
279 if( !bByVal && !SbiRuntime::isVBAEnabled() && eVarType == SbxSTRING )
280 bByVal = true;
281
282 if (bByVal) {
283 if ((eVarType & SbxARRAY) == 0) {
284 switch (eVarType) {
285 case SbxINTEGER:
286 add(blob, variable->GetInteger(), outer ? 4 : 2, offset);
287 break;
288 case SbxLONG:
289 add(blob, variable->GetLong(), 4, offset);
290 break;
291 case SbxSINGLE:
292 add(blob, variable->GetSingle(), 4, offset);
293 break;
294 case SbxDOUBLE:
295 add(blob, variable->GetDouble(), outer ? 4 : 8, offset);
296 break;
297 case SbxSTRING:
298 {
299 void * p;
300 ErrCode e = marshalString(variable, special, data, &p);
301 if (e != ERRCODE_NONE) {
302 return e;
303 }
304 add(blob, p, 4, offset);
305 break;
306 }
307 case SbxOBJECT:
308 {
309 align(blob, outer ? 4 : alignment(variable), offset, 0);
310 ErrCode e = marshalStruct(variable, blob, offset, data);
311 if (e != ERRCODE_NONE) {
312 return e;
313 }
314 break;
315 }
316 case SbxBOOL:
317 add(blob, variable->GetBool(), outer ? 4 : 1, offset);
318 break;
319 case SbxBYTE:
320 add(blob, variable->GetByte(), outer ? 4 : 1, offset);
321 break;
322 default:
323 assert(false);
324 break;
325 }
326 } else {
327 ErrCode e = marshalArray(variable, blob, offset, data);
328 if (e != ERRCODE_NONE) {
329 return e;
330 }
331 }
332 } else {
333 if ((eVarType & SbxARRAY) == 0) {
334 switch (eVarType) {
335 case SbxINTEGER:
336 case SbxLONG:
337 case SbxSINGLE:
338 case SbxDOUBLE:
339 case SbxBOOL:
340 case SbxBYTE:
341 add(blob, variable->data(), 4, offset);
342 break;
343 case SbxSTRING:
344 {
345 void * p;
346 ErrCode e = marshalString(variable, special, data, &p);
347 if (e != ERRCODE_NONE) {
348 return e;
349 }
350 std::vector< char > * blob2 = data.newBlob();
351 add(*blob2, p, 4, 0);
352 add(blob, address(*blob2), 4, offset);
353 break;
354 }
355 case SbxOBJECT:
356 {
357 std::vector< char > * blob2 = data.newBlob();
358 ErrCode e = marshalStruct(variable, *blob2, 0, data);
359 if (e != ERRCODE_NONE) {
360 return e;
361 }
362 void * p = address(*blob2);
363 if (outer) {
364 data.unmarshal.push_back(UnmarshalData(variable, p));
365 }
366 add(blob, p, 4, offset);
367 break;
368 }
369 default:
370 assert(false);
371 break;
372 }
373 } else {
374 std::vector< char > * blob2 = data.newBlob();
375 ErrCode e = marshalArray(variable, *blob2, 0, data);
376 if (e != ERRCODE_NONE) {
377 return e;
378 }
379 void * p = address(*blob2);
380 if (outer) {
381 data.unmarshal.push_back(UnmarshalData(variable, p));
382 }
383 add(blob, p, 4, offset);
384 }
385 }
386 return ERRCODE_NONE;
387}
388
389template< typename T > T read(void const ** pointer) {
390 T const * p = static_cast< T const * >(*pointer);
391 *pointer = static_cast< void const * >(p + 1);
392 return *p;
393}
394
395void const * unmarshal(SbxVariable * variable, void const * data) {
396 assert(variable != 0);
397 if ((variable->GetType() & SbxARRAY) == 0) {
398 switch (variable->GetType()) {
399 case SbxINTEGER:
400 variable->PutInteger(read< sal_Int16 >(&data));
401 break;
402 case SbxLONG:
403 variable->PutLong(read< sal_Int32 >(&data));
404 break;
405 case SbxSINGLE:
406 variable->PutSingle(read< float >(&data));
407 break;
408 case SbxDOUBLE:
409 variable->PutDouble(read< double >(&data));
410 break;
411 case SbxSTRING:
412 read< char * >(&data); // handled by unmarshalString
413 break;
414 case SbxOBJECT:
415 {
416 data = reinterpret_cast< void const * >(
417 align(
418 reinterpret_cast< sal_uIntPtr >(data),
419 alignment(variable)));
420 SbxObject* pobj = dynamic_cast<SbxObject*>(variable->GetObject());
421 assert(pobj);
422 SbxArray* props = pobj->GetProperties();
423 for (sal_uInt32 i = 0; i < props->Count(); ++i)
424 {
425 data = unmarshal(props->Get(i), data);
426 }
427 break;
428 }
429 case SbxBOOL:
430 variable->PutBool(read< sal_Bool >(&data));
431 break;
432 case SbxBYTE:
433 variable->PutByte(read< sal_uInt8 >(&data));
434 break;
435 default:
436 assert(false);
437 break;
438 }
439 } else {
440 SbxDimArray * arr = dynamic_cast<SbxDimArray*>( variable->GetObject() );
441 assert(arr);
442 sal_Int32 dims = arr->GetDims();
443 std::vector< sal_Int32 > low(dims);
444 std::vector< sal_Int32 > up(dims);
445 for (sal_Int32 i = 0; i < dims; ++i) {
446 arr->GetDim(i + 1, low[i], up[i]);
447 }
448 for (std::vector< sal_Int32 > idx = low;;) {
449 data = unmarshal(arr->Get(&idx[0]), data);
450 sal_Int32 i = dims - 1;
451 while (idx[i] == up[i]) {
452 idx[i] = low[i];
453 if (i == 0) {
454 goto done;
455 }
456 --i;
457 }
458 ++idx[i];
459 }
460 done:;
461 }
462 return data;
463}
464
465ErrCode unmarshalString(StringData const & data, SbxVariable & result) {
466 OUString str;
467 if (data.buffer != 0) {
468 char const * p = static_cast< char const * >(data.buffer);
469 sal_Int32 len;
470 if (data.special) {
471 len = static_cast< sal_Int32 >(result.GetULong());
472 if (len < 0) { // i.e., DWORD result >= 2^31
474 //TODO: more specific errcode?
475 }
476 } else {
477 len = rtl_str_getLength(p);
478 }
479 ErrCode e = convert(p, len, &str);
480 if (e != ERRCODE_NONE) {
481 return e;
482 }
483 }
484 data.variable->PutString(str);
485 return ERRCODE_NONE;
486}
487
488struct ProcData {
489 OString name;
490 FARPROC proc;
491};
492
493ErrCode call(
494 OUString const & dll, ProcData const & proc, SbxArray * arguments,
495 SbxVariable & result)
496{
497 std::vector< char > stack;
498 MarshalData data;
499 // For DWORD GetLogicalDriveStringsA(DWORD nBufferLength, LPSTR lpBuffer)
500 // from kernel32, upon return, filled lpBuffer length is result DWORD, which
501 // requires special handling in unmarshalString; other functions might
502 // require similar treatment, too:
503 bool special = dll.equalsIgnoreAsciiCase("KERNEL32.DLL") &&
504 (proc.name == OString("GetLogicalDriveStringsA"));
505 for (sal_uInt32 i = 1; i < (arguments == 0 ? 0 : arguments->Count()); ++i)
506 {
507 ErrCode e = marshal(true, arguments->Get(i), special && i == 2, stack, stack.size(),
508 data);
509 if (e != ERRCODE_NONE) {
510 return e;
511 }
512 align(stack, 4, 0, 0);
513 }
514 switch (result.GetType()) {
515 case SbxEMPTY:
516 DllMgr_call32(proc.proc, address(stack), stack.size());
517 break;
518 case SbxINTEGER:
519 result.PutInteger(
520 static_cast< sal_Int16 >(
521 DllMgr_call32(proc.proc, address(stack), stack.size())));
522 break;
523 case SbxLONG:
524 result.PutLong(
525 static_cast< sal_Int32 >(
526 DllMgr_call32(proc.proc, address(stack), stack.size())));
527 break;
528 case SbxSINGLE:
529 result.PutSingle(
530 static_cast< float >(
531 DllMgr_callFp(proc.proc, address(stack), stack.size())));
532 break;
533 case SbxDOUBLE:
534 result.PutDouble(
535 DllMgr_callFp(proc.proc, address(stack), stack.size()));
536 break;
537 case SbxSTRING:
538 {
539 char const * s1 = reinterpret_cast< char const * >(
540 DllMgr_call32(proc.proc, address(stack), stack.size()));
541 OUString s2;
542 ErrCode e = convert(s1, rtl_str_getLength(s1), &s2);
543 if (e != ERRCODE_NONE) {
544 return e;
545 }
546 result.PutString(s2);
547 break;
548 }
549 case SbxOBJECT:
550 //TODO
551 DllMgr_call32(proc.proc, address(stack), stack.size());
552 break;
553 case SbxBOOL:
554 result.PutBool(
555 bool(DllMgr_call32(proc.proc, address(stack), stack.size())));
556 break;
557 case SbxBYTE:
558 result.PutByte(
559 static_cast< sal_uInt8 >(
560 DllMgr_call32(proc.proc, address(stack), stack.size())));
561 break;
562 default:
563 assert(false);
564 break;
565 }
566 for (sal_uInt32 i = 1; i < (arguments == 0 ? 0 : arguments->Count()); ++i)
567 {
568 arguments->Get(i)->ResetFlag(SbxFlagBits::Reference);
569 //TODO: skipped for errors?!?
570 }
571 for (auto& rUnmarshalData : data.unmarshal)
572 {
573 unmarshal(rUnmarshalData.variable, rUnmarshalData.buffer);
574 }
575 for (const auto& rStringData : data.unmarshalStrings)
576 {
577 ErrCode e = unmarshalString(rStringData, result);
578 if (e != ERRCODE_NONE) {
579 return e;
580 }
581 }
582 return ERRCODE_NONE;
583}
584
585ErrCode getProcData(HMODULE handle, OUString const & name, ProcData * proc)
586{
587 assert(proc != 0);
588 if ( !name.isEmpty() && name[0] == '@' ) { //TODO: "@" vs. "#"???
589 sal_Int32 n = o3tl::toInt32(name.subView(1)); //TODO: handle bad input
590 if (n <= 0 || n > 0xFFFF) {
591 return ERRCODE_BASIC_BAD_ARGUMENT; //TODO: more specific errcode?
592 }
593 FARPROC p = GetProcAddress(handle, reinterpret_cast< LPCSTR >(n));
594 if (p != 0) {
595 proc->name = OString("#") + OString::number(n);
596 proc->proc = p;
597 return ERRCODE_NONE;
598 }
599 } else {
600 OString name8;
601 ErrCode e = convert(name, &name8);
602 if (e != ERRCODE_NONE) {
603 return e;
604 }
605 FARPROC p = GetProcAddress(handle, name8.getStr());
606 if (p != 0) {
607 proc->name = name8;
608 proc->proc = p;
609 return ERRCODE_NONE;
610 }
611 sal_Int32 i = name8.indexOf('#');
612 if (i != -1) {
613 name8 = name8.copy(0, i);
614 p = GetProcAddress(handle, name8.getStr());
615 if (p != 0) {
616 proc->name = name8;
617 proc->proc = p;
618 return ERRCODE_NONE;
619 }
620 }
621 OString real(OString("_") + name8);
622 p = GetProcAddress(handle, real.getStr());
623 if (p != 0) {
624 proc->name = real;
625 proc->proc = p;
626 return ERRCODE_NONE;
627 }
628 real = name8 + OString("A");
629 p = GetProcAddress(handle, real.getStr());
630 if (p != 0) {
631 proc->name = real;
632 proc->proc = p;
633 return ERRCODE_NONE;
634 }
635 }
637}
638
639struct Dll: public salhelper::SimpleReferenceObject {
640private:
641 typedef std::map< OUString, ProcData > Procs;
642
643 virtual ~Dll();
644
645public:
646 Dll(): handle(0) {}
647
648 ErrCode getProc(OUString const & name, ProcData * proc);
649
650 HMODULE handle;
651 Procs procs;
652};
653
654Dll::~Dll() {
655 if (handle != 0 && !FreeLibrary(handle)) {
656 SAL_WARN("basic", "FreeLibrary(" << handle << ") failed with " << GetLastError());
657 }
658}
659
660ErrCode Dll::getProc(OUString const & name, ProcData * proc) {
661 Procs::iterator i(procs.find(name));
662 if (i != procs.end()) {
663 *proc = i->second;
664 return ERRCODE_NONE;
665 }
666 ErrCode e = getProcData(handle, name, proc);
667 if (e == ERRCODE_NONE) {
668 procs.emplace(name, *proc);
669 }
670 return e;
671}
672
673OUString fullDllName(OUString const & name) {
674 OUString full(name);
675 if (full.indexOf('.') == -1) {
676 full += ".DLL";
677 }
678 return full;
679}
680
681}
682
683struct SbiDllMgr::Impl {
684private:
685 typedef std::map< OUString, rtl::Reference< Dll > > Dlls;
686
687public:
688 Impl() = default;
689 Impl(const Impl&) = delete;
690 const Impl& operator=(const Impl&) = delete;
691
692 Dll * getDll(OUString const & name);
693
694 Dlls dlls;
695};
696
697Dll * SbiDllMgr::Impl::getDll(OUString const & name) {
698 Dlls::iterator i(dlls.find(name));
699 if (i == dlls.end()) {
700 i = dlls.emplace(name, new Dll).first;
701 HMODULE h = LoadLibraryW(o3tl::toW(name.getStr()));
702 if (h == 0) {
703 dlls.erase(i);
704 return 0;
705 }
706 i->second->handle = h;
707 }
708 return i->second.get();
709}
710
712 std::u16string_view function, std::u16string_view library,
713 SbxArray * arguments, SbxVariable & result, bool cdeclConvention)
714{
715 if (cdeclConvention) {
717 }
718 OUString dllName(fullDllName(OUString(library)));
719 Dll * dll = impl_->getDll(dllName);
720 if (dll == 0) {
722 }
723 ProcData proc;
724 ErrCode e = dll->getProc(OUString(function), &proc);
725 if (e != ERRCODE_NONE) {
726 return e;
727 }
728 return call(dllName, proc, arguments, result);
729}
730
731void SbiDllMgr::FreeDll(OUString const & library) {
732 impl_->dlls.erase(library);
733}
734
735SbiDllMgr::SbiDllMgr(): impl_(new Impl) {}
736
737SbiDllMgr::~SbiDllMgr() {}
738
739/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ErrCode Call(std::u16string_view function, std::u16string_view library, SbxArray *arguments, SbxVariable &result, bool cdeclConvention)
Definition: dllmgr-none.cxx:94
void FreeDll(OUString const &library)
static bool isVBAEnabled()
Definition: runtime.cxx:115
Definition: sbx.hxx:95
sal_uInt32 Count() const
Definition: sbxarray.cxx:87
SbxFlagBits GetFlags() const
Definition: sbxcore.hxx:105
SbxArray * GetProperties()
Definition: sbxobj.hxx:79
OUString GetOUString() const
Definition: sbxvalue.cxx:380
bool PutDouble(double)
SbxBase * GetObject() const
Definition: sbxvar.hxx:157
SbxValues * data()
Definition: sbxvar.hxx:138
bool PutByte(sal_uInt8)
bool PutSingle(float)
bool PutBool(bool)
Definition: sbxvalue.cxx:543
sal_uInt8 GetByte() const
Definition: sbxvar.hxx:158
bool GetBool() const
Definition: sbxvar.hxx:153
bool PutInteger(sal_Int16)
sal_Int32 GetLong() const
Definition: sbxvar.hxx:142
sal_Int16 GetInteger() const
Definition: sbxvar.hxx:141
float GetSingle() const
Definition: sbxvar.hxx:149
bool PutLong(sal_Int32)
double GetDouble() const
Definition: sbxvar.hxx:150
virtual SbxDataType GetType() const override
Definition: sbxvar.cxx:321
int __stdcall DllMgr_call32(FARPROC, void const *stack, std::size_t size)
double __stdcall DllMgr_callFp(FARPROC, void const *stack, std::size_t size)
#define ERRCODE_NONE
const char * name
const sal_uInt16 idx[]
void * p
sal_Int64 n
DECL_LISTENERMULTIPLEXER_END void SAL_CALL up(const css::awt::SpinEvent &rEvent) override
#define SAL_WARN(area, stream)
convert
int i
arr
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
dictionary props
sal_Int32 h
#define ERRCODE_BASIC_PROC_UNDEFINED
Definition: sberrors.hxx:32
#define ERRCODE_BASIC_BAD_ARGUMENT
Definition: sberrors.hxx:26
#define ERRCODE_BASIC_NOT_IMPLEMENTED
Definition: sberrors.hxx:80
#define ERRCODE_BASIC_BAD_DLL_LOAD
Definition: sberrors.hxx:64
SbxBOOL
Definition: sbxdef.hxx:215
SbxDataType
Definition: sbxdef.hxx:37
@ SbxOBJECT
Definition: sbxdef.hxx:47
@ SbxLONG
Definition: sbxdef.hxx:41
@ SbxARRAY
Definition: sbxdef.hxx:80
@ SbxBYTE
Definition: sbxdef.hxx:55
@ SbxEMPTY
Definition: sbxdef.hxx:38
@ SbxSINGLE
Definition: sbxdef.hxx:42
@ SbxSTRING
Definition: sbxdef.hxx:46
@ SbxINTEGER
Definition: sbxdef.hxx:40
@ SbxDOUBLE
Definition: sbxdef.hxx:43
Impl()=default
std::map< OUString, ::rtl::Reference< Dll > > Dlls
Definition: dllmgr-x64.cxx:710
const Impl & operator=(const Impl &)=delete
Dll * getDll(OUString const &name)
Impl(const Impl &)=delete
std::map< OUString, rtl::Reference< Dll > > Dlls
Definition: dllmgr-x86.cxx:685
unsigned char sal_uInt8
Any result