Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
White Owl Код: plaintext 1. 2. 3. 4. 1>.\LicenseDll.cpp(73) : error C2664: 'strncpy' : cannot convert parameter 1 from 'LPTSTR' to 'char *' 1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2013, 21:42 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77 Как реализовать _Out_ LPTSTR lpString без фокусов получать BSTR* а передавать byref as string ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2013, 21:42 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77White Owl Код: plaintext 1. 2. 3. 4. 1>.\LicenseDll.cpp(73) : error C2664: 'strncpy' : cannot convert parameter 1 from 'LPTSTR' to 'char *' 1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style castДай угадаю, у тебя включен UNICODE режим и ты компилируешь в С++? Выключи первое в настройках проекта. И переименуй свой исходник в .c для выключения второго. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2013, 22:01 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
бейсик конвертит свои юникодные строки в ANSI и обратно при вызове функций из dll чтоб избавиться от геморроя можно вернуть из dll единственный объект (IDispatch) и далее просто вызывать его методы и обращаться к свойствам ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2013, 22:36 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
White Owl, 1) Юникод я отключил в Property Pages -> Configuration Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions Снял галку Inherit from parent or project defaults где что-то про это говорилось Надеюсь это касается только тек. проекта и не "испортит" компилятор? В принципе мне Юникод не нужен и в VB6 я например борюсь со случайными его "проявлениями". Это когда len(String) вдруг начинает выдавать невменяемое значение после какого-нибудь strconv(,vbUnicode). 2) Файл в .c переименовывать не стал 3) Заменил Код: plaintext 1. на Код: plaintext 1. (как присоветовал компилятор, читать Warning! допустимо, но не особо приятно) Ничего не попутал, два раза воткнув именно nMaxCount (а не lenth напр.)? Короче, к коду ниже претезии есть? Память чиста? Совесть чиста? Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Все работает. И плюс свел ф-цию к стандартному приему используемому в VB6. У меня и первый вариант с char * работал, но Вам не понравилось. Я бы забил, но мне хотелось привести к "стандарту". Мой PtrToString это не тривиально и не стандарт, и я ее написал в прошлом году исключительно потому, что с Opal с его ветвящимися структурами из ссылок на const char * по другому из VB6 работать не получилось. Просто у вас в C++ тут очень интересно. Какая то дурацкая строчка с NULL вызывает бурные дискуссии на неделю вперед. Мало того что 5 строчек кода высасываются из пальца 2 дня, так тебе еще неделю объясняют про 10 других способов. Вот нафига мне этот IDispatch? Работать с IЧтонибудь из VB6 ой как нелегко, если только не через tlb-обертку. Не, я делал Windows Audio API (это которые New), но в VB6 с этим повеситься можно, но пришлось это сделать т.к. Вистовские миксеры со старыми multimedia API глючат. В данном случае никакой необходимости IИздеватьсяНадСобой нету. Просто ответьте. Последний вариант безупречен? Если В НЕМ что не так то что? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 00:25 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
А по поводу Код: plaintext 1. на который все так дружно набросились, Ну если dll не "защищена", то NULL там так и останется, соотв. вызов API элементарно вызовет crash. Я думаю вариант Код: plaintext 1. лучше подойдет для инициализации, не так ли? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 00:39 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77White Owl, 1) Юникод я отключил в Property Pages -> Configuration Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions Снял галку Inherit from parent or project defaults где что-то про это говорилось Надеюсь это касается только тек. проекта и не "испортит" компилятор? В принципе мне Юникод не нужен и в VB6 я например борюсь со случайными его "проявлениями". Это когда len(String) вдруг начинает выдавать невменяемое значение после какого-нибудь strconv(,vbUnicode). Нет, это не испортит компилятор. Просто ты используешь LPSTR в своем проекте. Это собственный микрософтовский "тип" данных который является синонимом либо char*, либо unsigned short *. В первом случае ты будешь работать с обычной ASCIIz строкой, во втором с двухбайтовыми строками. И надо будет вместо strncpy использовать функцию wstrncpy. Первый случай это без UNICODE флага, второй случай с ним. Дмитрий772) Файл в .c переименовывать не сталТы в любом случае вынужден писать верхний уровень на С. Потому что VB не способен импортировать С++ классы и методы классов. Поэтому у тебя весь исходник и обернут в extern "C" блок. Если у тебя имя исходного файла some.cpp, то extern "C"{} обязателен. Если some.c, то не обязателен. На мой взгляд, если тебе нет нужды использовать классы и/или чьи-то С++ библиотеки, то проще писать сразу на С. Дмитрий773) Заменил Код: plaintext 1. на Код: plaintext 1. (как присоветовал компилятор, читать Warning! допустимо, но не особо приятно) Ничего не попутал, два раза воткнув именно nMaxCount (а не lenth напр.)? Вообще-то попутал. nMaxCount относится к lpString, но не имеет никакого отношения к UserName. Дмитрий77Короче, к коду ниже претезии есть? Память чиста? Совесть чиста? Есть претензии. Если ты используешь strncpy_s, то и обработку ошибок делай соответствующую. Вот так получше будет: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 00:59 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
White OwlВообще-то попутал. nMaxCount относится к lpString, но не имеет никакого отношения к UserName.ну и что? он же обрезает результирующую строку, если length <= nMaxCount, а больше в неё не попадёт по определению. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 01:22 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
egorych, хотя твой вариант красивее, согласен. замучали меня под вечер абстракциями своими в программировании, прости ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 01:24 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77А по поводу Код: plaintext 1. на который все так дружно набросились, Ну если dll не "защищена", то NULL там так и останется, соотв. вызов API элементарно вызовет crash. Я думаю вариант Код: plaintext 1. лучше подойдет для инициализации, не так ли?Нет, так не будет лучше ни в коем случае. Пойми одну простую вещь: В С и С++ нету строк. Вообще нету. Никаких. По определению. Любая запись типа кавычки-буковки-кавычки это на самом деле объявление константного массива который будет содержать указанные буковки и конечный ноль. Каждый массив лежит где-то в памяти. А чтобы программа знала где это самое "где-то" находится существуют "указатели". В Бейсике указатели тоже существуют, но они "спрятаны под капотом". Единственный случай когда ты сталкиваешься с указателями в VB это когда объявляешь параметр функции ByRef. А в С и С++ указатели используются намного шире и любая работа со строками в С это на самом деле манипулирование указателем на массив символов. Объявляя char* name ты объявляешь не массив, а четыре байтика в памяти (для 32х битного приложения). В эти четыре байтика ты можешь записать реальный адрес в памяти где будет лежать настоящий массив. Например запись: char* UserName = ""; Объявляет массив размером в один байт (только один конечный нолик) и кладет этот массив в специальный сегмент памяти называемый сdata. Потом выделяет в сегменте памяти data четыре байтика (обзывает эти четыре байтика UserName) и записывает в них адрес одно-байтового массива. Если ты теперь в коде функции сделаешь: UserName="John"; то на самом деле, ты объявил в сегменте cdata массив из пяти байт и проинициализировал его четырьмя буквами и одним нулем, причем это произошло еще до старта программы. А во время выполнения функции ты перенаправляешь указатель UserName на этот пятибайтовый массив. При этом однобайтовый массив ты теряешь. Окончательно и бесповоротно. До того начального массива ты уже никогда-никогда не доберешься. Запись типа char* UserName = NULL; намного лучше. В данном случае ты создаешь указатель (те самые именованные четыре байтика), но вместо адреса реального массива ты пишешь туда "стандартное" значение. Потом его можно использовать для проверки задан UserName или нет. Например тебе надо вызывать функцию несколько раз, но проинициализировать только однажды: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. Теперь сколько бы раз ты ни вызывал init() операция присвоения UserName выполнится только однажды. Это не очень показательный пример, но если UserName читается не из другой переменной а например из базы данных, или из сети, или спрашивается у юзера, то подобный трюк с начальным NULL может здорово облегчить жизнь. Если же просто объявить char *UserName; То ты создашь в памяти переменную в которой будет какое-то случайное значение. И этот пример работать уже не будет. Ты можешь заметить что использованный в примере NULL можно запросто заменить на какой-нибудь UNDEFINED. И будешь прав. Но в этом случае ты сам должен будешь создать UNDEFINED, в то время как NULL обычно уже существует и все про него знают и показанные трюки считаются нормой жизни. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 01:40 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77Вот нафига мне этот IDispatch? Работать с IЧтонибудь из VB6 ой как нелегко, если только не через tlb-обертку. не путайте IDispatch и IЧтонибудь IDispatch - это бейсиковый Object с поздним связыванием, никакого tlb не требуется ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 02:11 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
White Owl, Код: plaintext 1. Я не понимаю какую ты ошибку пытаешься отловить в errno_t rc, 1) если будет length > nMaxCount-1 то будет crash без всякой ловли. 2) А любое значение между lenth и nMaxCount-1 к crash не приводит и дает корректный результат 3) Если считаешь что все-таки правильно инициализировать Код: plaintext 1. Сложно спорить с такими доводами, и не буду. Но если при вызове API там будет NULL то будет crash. Посему думаю чем отлавливать ошибки (до отлова которых дело не дойдет) проще руководствуясь здравым смыслом писать код чтоб их не было. Я переделал вот так и жду замечаний: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. Можно конечно заменить на Код: plaintext 1. 2. 3. 4. 5. 6. 7. но особого смысла в этом не вижу. Благодаря возврату "честной" длины я могу чуть модифицировать VB6 код и получать полную необрезанную строку максимум в 2 итерации: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. Ну, или довольствоваться обрезанной пользуясь предыдущим кодом Код: vbnet 1. 2. Т.е. левая часть длиной 540 от заполненного буфера [255]+\0 выдаст безошибочно строку длиной 255 (т.е. vb-шный код не ошибется). С Вами не соскучишься. Чувствую, если писать все на C++ то и программу не напишешь, и денег не заработаешь (такими то темпами). Но зато умным человеком станешь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 04:14 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77Благодаря возврату "честной" длины я могу чуть модифицировать VB6 код и получать полную необрезанную строку максимум в 2 итерации в традициях WINAPI при передаче NULL в качестве адреса буфера возвращается (через результат или выходной параметр) необходимый размер ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 08:10 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
Изопропилв традициях WINAPI при передаче NULL в качестве адреса буфера возвращается (через результат или выходной параметр) необходимый размер Не всегда. Извращаются как хотят. Например GetPrivateProfileString Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Return value The return value is the number of characters copied to the buffer, not including the terminating null character. If neither lpAppName nor lpKeyName is NULL and the supplied destination buffer is too small to hold the requested string, the string is truncated and followed by a null character, and the return value is equal to nSize minus one. If either lpAppName or lpKeyName is NULL and the supplied destination buffer is too small to hold all the strings, the last string is truncated and followed by two null characters. In this case, the return value is equal to nSize minus two. Поэтому здесь мой вариант VB6 кода с 2-мя итерациями уже не пройдет. Пользуюсь вот таким кодом: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. На практике обычно задается большой буфер (в предположении что места хватит) и никаких проверок не производится. Для моей ф-ции которую здесь мусолим такого варианта вполне достаточно. Но я несколько раз накалывался с этим, в частности с ini-файлом, поэтому (с учетом на будущее) все таки хочу написать подобную штуку "с запасом прочности". Кстати я в своем крайнем варианте еще не проверял что будет если nMaxCount=0 т.е. Код: plaintext 1. Скрашит небось. А с другой стороны если знаешь API изнутри, или есть нормальное описание в msdn или где-то там которое внимательно читаешь, то никогда не будешь вызывать API с недозволенными параметрами. А вариант безусловного применения Код: plaintext 1. как раз может скрашить 1) если UserName=NULL 2) если length > nMaxCount - 1 и этот краш определяется значением UserName, т.е. вызывающая сторона не виновата что какой-то идиот засунул в Username строку в 10000 символов например. И вот это уже не есть гуд. Я неправ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 16:17 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77White Owl, Код: plaintext 1. Я не понимаю какую ты ошибку пытаешься отловить в errno_t rc, http://msdn.microsoft.com/en-us/library/5dae5d43(v=vs.80).aspx Читай внимательно описание функции. Все что ты делаешь сравнивая length и nMaxCount - не нужно. Это все уже встроено внуть strncpy_s. Читай документацию. Дмитрий771) если будет length > nMaxCount-1 то будет crash без всякой ловли.не будет. Читай документацию. Дмитрий772) А любое значение между lenth и nMaxCount-1 к crash не приводит и дает корректный результатНет. Читай документацию. Дмитрий773) Если считаешь что все-таки правильно инициализировать Код: plaintext 1. Сложно спорить с такими доводами, и не буду. Но если при вызове API там будет NULL то будет crash.Нет, не будет. Читай документацию. Дмитрий77Посему думаю чем отлавливать ошибки (до отлова которых дело не дойдет) проще руководствуясь здравым смыслом писать код чтоб их не было.Да, конечно, лучше писать чтобы их не было. И я тебе уже показал как должен выглядеть код использующий функцию strncpy_s(). Дмитрий77Я переделал вот так и жду замечаний:Плохо. Все плохо. У тебя 90% кода - бессмысленная работа. А обработки ошибок нет вообще. Дмитрий77С Вами не соскучишься. Чувствую, если писать все на C++ то и программу не напишешь, и денег не заработаешь (такими то темпами). Но зато умным человеком станешь.А если ты наконец решишься прочитать любой учебник по С (я советую K&R) и поймешь работу с указателями, а потом не будешь лениться читать документацию на используемые функции то все будет легко и замечательно. А до тех пор будешь писать фигню. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 21:25 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
White OwlДмитрий771) если будет length > nMaxCount-1 то будет crash без всякой ловли.не будет. Читай документацию. Дмитрий772) А любое значение между lenth и nMaxCount-1 к crash не приводит и дает корректный результатНет. Читай документацию. Дмитрий773) Если считаешь что все-таки правильно инициализировать Код: plaintext 1. Сложно спорить с такими доводами, и не буду. Но если при вызове API там будет NULL то будет crash.Нет, не будет. Читай документацию. Вот ты говоришь не будет (Should NOT согласно документации). А я говорю что крашит (ИЗЪ ЕСМЬ что вижу то и докладываю). Почему тогда у меня твой код (с обработкой ошибок) генерит crash при вызове в указанных случаях? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 21:38 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77Почему тогда у меня твой код (с обработкой ошибок) генерит crash при вызове в указанных случаях? Так мы ж не видим код, который вы запускаете. Может у вас там проблема в других местах. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 21:44 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77White Owlпропущено... не будет. Читай документацию. пропущено... Нет. Читай документацию. пропущено... Нет, не будет. Читай документацию. Вот ты говоришь не будет (Should NOT согласно документации). А я говорю что крашит (ИЗЪ ЕСМЬ что вижу то и докладываю). Почему тогда у меня твой код (с обработкой ошибок) генерит crash при вызове в указанных случаях? Если согласно документации should not, а в реальность is - значит одно из двух: либо документация врет, либо ты делаешь неправильно. Проверяется это очень просто: Отложи в сторону свой существующий супер-проект. Сделай новый примитивный проект в котором попытайся повторить проблему. Если проблему повторить на микро-проекте удастся - опубликуй его здесь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 21:58 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
White OwlСделай новый примитивный проект в котором попытайся повторить проблему. Так это и есть микропроект. На стороне C одна функция (ну пусть 2-3 аналогичных, но дергаю то одну) На стороне VB6 декларация ф-ции + код одной кнопки. Anatoly MoskovskyТак мы ж не видим код, который вы запускаете. Значит плохо смотрите, если не видите: 14513598 Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Для получения crash с кодом предложенным White Owl выполнить этот код вполне достаточно для указанных двух случаев: 1) NULL 2) lenth > nMaxCount- 1 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 22:09 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
А в "свой существующий супер-проект" я пока что вставил код из второго поста: 14502889 который у меня сомнений в надежности не вызывает. И кстати, как люди говорят, 14518605 , ZVIПравильно было сделано в начале, во 2-м сообщении, с возвратом 2-байтного указателя на начало строки. ...А память там освобождать и не нужно было, потому что исходная С-ная строка не модифицируется, а создается копия строки в VB, и возвращаемый указатель там используется только для копирования С-шной строки в другую VB-строку. Единственное, почему я так прицепился к последнему варианту, потому что он "стандартизирован" и не предполагает побайтное рытье памяти на стороне VB6, что очень нестандартно хотя и работает железно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 22:21 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77, почему не вернуть без фокусов BSTR или VARIANT? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 23:24 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
ИзопропилДмитрий77, почему не вернуть без фокусов BSTR или VARIANT? Да ради бога. Ты предлагал: Код: plaintext 1. 2. 3. 4. 5. По сути это ничем не отличается от возврата char *. Кроме пристрастий и сомнительных споров про память (лично я окончательно судить не берусь, но человек - цитата чуть выше -говорит что все там с памятью нормально) А так напишешь? Код: plaintext 1. 2. Или даже так? Код: plaintext 1. 2. Ну, ты понимаешь к чему я клоню. К стандартизированному методу вызова. Чтоб скопировать результат в буфер длиной nMaxCount и вернуть lenth. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 23:40 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77, в случае возврата BSTR нет никакой нужды в передаче длины строки и прочих танцев с бубном с буфером ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 23:48 |
|
||
|
Как мне написать API-ф-цию чтоб возвращала строку.
|
|||
|---|---|---|---|
|
#18+
Всем -привет! Давненько я не брал в руки C-шашек! Обычно механизм возврата строки из С в VB такой: Код С-dll Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. Код VB: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Приложил cpp, dll и VB проектик ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 23:52 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=38319763&tid=2020106]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
53ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
56ms |
get tp. blocked users: |
2ms |
| others: | 13ms |
| total: | 165ms |

| 0 / 0 |
