Другое С/С++ Вопрос - Ответ

Vintik

Через тернии к звёздам
Проверенный
1,544
1,017
Всем здравствуйте. Надеюсь, эксперты помогут мне в решении проблемы. Суть в том, что хочу как-то использовать встоенные в GTA SA функции (пример: написать белый текст снизу экрана) своей программой. У DarkP1xel`я заметил следующее:
DarkP1xel написал(а):
((void(__cdecl *)(PCHAR, UINT, USHORT, bool))0x69F1E0)

Но это для DLL библиотеки, я же хочу для стандартного "консольного приложения".
 

SR_team

like pancake
BH Team
4,805
6,479
Всем здравствуйте. Надеюсь, эксперты помогут мне в решении проблемы. Суть в том, что хочу как-то использовать встоенные в GTA SA функции (пример: написать белый текст снизу экрана) своей программой. У DarkP1xel`я заметил следующее:


Но это для DLL библиотеки, я же хочу для стандартного "консольного приложения".
Google: CreateRemoteThread
 

Cake_

Потрачен
Проверенный
263
313
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Как получить коорды объекта / модели? Попытался сам написать, что-то не то вообщем
C++:
float pos[3];

    for (int i = 0; i < SAMP_MAX_OBJECTS; i++)
    {
        if (SF->getSAMP()->getInfo()->pPools->pObject->iIsListed[i] != 1)
            continue;
        if (SF->getSAMP()->getInfo()->pPools->pObject->object[i] == NULL)
            continue;
        if (SF->getSAMP()->getInfo()->pPools->pObject->object[i]->pGTAEntity == NULL)
            continue;

        pos[0] = SF->getSAMP()->getInfo()->pPools->pObject->object[i]->fPos[0];
        pos[1] = SF->getSAMP()->getInfo()->pPools->pObject->object[i]->fPos[1];
        pos[2] = SF->getSAMP()->getInfo()->pPools->pObject->object[i]->fPos[2];
 

SiTrak

Известный
192
253
Как получить коорды объекта / модели? Попытался сам написать, что-то не то вообщем
C++:
float pos[3];

    for (int i = 0; i < SAMP_MAX_OBJECTS; i++)
    {
        if (SF->getSAMP()->getInfo()->pPools->pObject->iIsListed[i] != 1)
            continue;
        if (SF->getSAMP()->getInfo()->pPools->pObject->object[i] == NULL)
            continue;
        if (SF->getSAMP()->getInfo()->pPools->pObject->object[i]->pGTAEntity == NULL)
            continue;

        pos[0] = SF->getSAMP()->getInfo()->pPools->pObject->object[i]->fPos[0];
        pos[1] = SF->getSAMP()->getInfo()->pPools->pObject->object[i]->fPos[1];
        pos[2] = SF->getSAMP()->getInfo()->pPools->pObject->object[i]->fPos[2];
C++:
                        if (pObj->iModel == objes[4])
                        {
                            memcpy(pos, &SF->getSAMP()->getInfo()->pPools->pObject->object[i]->pGTAEntity->base.matrix[12], sizeof(float)* 3);
                            //    uint16_t    model_id = SF->getSAMP()->getInfo()->pPools->pObject->object[i]->pGTAEntity->base.model_alt_id;


                            SF->getGame()->convert3DCoordsToScreen(position[0], position[1], position[2], &obmypos[0], &obmypos[1]);

                            SF->getGame()->convert3DCoordsToScreen(pos[0], pos[1], pos[2], &obsreen[0], &obsreen[1]);
                            if (IsOnScreen(i))
                            {
                                SF->getRender()->DrawLine(obmypos[0], obmypos[1], obsreen[0], obsreen[1], sizelin[4], 0xFF00FF00);
                            }
                        }
 
  • Нравится
Реакции: Cake_

index

Известный
125
82
Небольшая абстрактная задачка: имеется объект Cell, полем которого является указатель на объект (pMan) одного из возможных других классов с разным поведением и полями (virtual не предлагать :) ). Когда указатель на Cell передадут в какую-либо функцию (в приведенном примере все происходит в main) эта функция должна будет вызывать конкретный метод объекта класса, на который указывает pMan, но в зависимости от того, на какой класс там вообще идет указание.
Код (не цепляйтесь к тому, что все паблик, суть вопроса в самой концепции):
C++:
#include <iostream>
using namespace std;

class Man1 {
public:
    void do1() {
        cout << "Man1" << endl;
    }
};

class Man2 {
public:
    void do2() {
        cout << "Man2" << endl;
    }
};

class Cell {
public:
    enum class Type {
        man1, man2
    }; // Всевозможные типы

    Type type;
    void *pMan; // Указатель на Man1 или Man2, в зависимости от того, что находится в type

    Cell(Type x, void *px) : type(x), pMan(px) {}
};

int main(void)
{
    Cell *cell = new Cell(Cell::Type::man2, new Man2);

    if(cell->type == Cell::Type::man1)       // false
        static_cast<Man1*>(cell->pMan)->do1();
    else if (cell->type == Cell::Type::man2) // true
        static_cast<Man2*>(cell->pMan)->do2(); // выведет Man2
    return 0;
}

И сам вопрос: как реализовать подобную вещь более адекватно и канонично? В приведенном примере конструктор Cell может схавать
C++:
Cell(Cell::Type::man1, new Man2);
и в дальнейшем получить неопределенное поведение. Хотелось бы видеть подобные ошибки на этапе компиляции.
 
Последнее редактирование:
464
827
Как из данной строки получить "97.1445.1541.67" ?
Код:
{"as":"AS21127 JSC \"Zap-Sib TransTeleCom\", FFFFFFF","city":"FFFFFFF","country":"SSSSSS","countryCode":"RU","isp":"JSC \"Zap-Sib TransTeleCom\"","lat":12.1234,"lon":23.34,"org":"JSC Zap-Sib TransTeleCom","query":"97.1445.1541.67","region":"WER","regionName":"QWERTY","status":"success","timezone":"Asia/ESFFF","zip":"653008"}
 

imring

Ride the Lightning
Всефорумный модератор
2,361
2,546
Как из данной строки получить "97.1445.1541.67" ?
Код:
{"as":"AS21127 JSC \"Zap-Sib TransTeleCom\", FFFFFFF","city":"FFFFFFF","country":"SSSSSS","countryCode":"RU","isp":"JSC \"Zap-Sib TransTeleCom\"","lat":12.1234,"lon":23.34,"org":"JSC Zap-Sib TransTeleCom","query":"97.1445.1541.67","region":"WER","regionName":"QWERTY","status":"success","timezone":"Asia/ESFFF","zip":"653008"}
https://github.com/nlohmann/json
 

san0

Известный
Друг
411
268
Небольшая абстрактная задачка
Мне кажется, немножко детали упущены по поводу того, как это все должно использоваться. Это к тому, что, возможно, задачу можно будет свести к использованию обвертки с помощью std::bind или лямбда-выражения, либо же, всегда применить другую парадигму.

В любом случае, хотелось бы посоветовать либо использовать типобезопасный variant
C++:
#include <variant>
using Cell = std::variant<Man1*, Man2*>;

void usage_one(Cell cell) {
    if (auto man1 = std::get_if<Man1*>(&cell)) {
        (*man1)->do1();
    } else if (auto man2 = std::get_if<Man2*>(&cell)) {
        (*man2)->do2();
    }
}
Либо, если очень хочется написать обвертку, то что-то такое
C++:
#include <type_traits>

namespace std {
    template <class T, class... R>
    struct is_any : std::disjunction<std::is_same<T, R>...> {};
}

template <typename C>
class CellWrapper {
public:
    C* pMan;
 
    CellWrapper(C* ptr) : pMan(ptr) {
         // static_assert(std::is_class<C>::value);
         static_assert(std::is_any<C, Man1, Man2>::value,
             "CellWrapper could be created only with Man1 and Man2"
         );
    };
 
    C* operator->() {
        return this->pMan;
    }
};

template<typename C>
void usage_two(CellWrapper<C>* cell) {
    if constexpr (std::is_same<C, Man1>()) {
        (*cell)->do1();
    } else if constexpr (std::is_same<C, Man2>()) {
        (*cell)->do2();
    }
}

Использование
C++:
int main(void) {
    {
        auto cell = Cell(new Man1);
        usage_one(cell);
    }
    {
        auto cell = CellWrapper(new Man2);
        usage_two(&cell); // как и просилось, именно указатель
    }
}
Поправьте, если это не то, что требовалось.
P.S. В примерах выше по причине использования new была продемонстрирована утечка памяти
 
Последнее редактирование:
  • Нравится
Реакции: index

index

Известный
125
82
Мне кажется, немножко детали упущены по поводу того, как это все должно использоваться.
Есть массив (обертка не подойдет) объектов Cell. Из этого массива произвольным образом выбирается элемент, и, в зависимости от типа ассоциированного с ним объекта другого класса, выполняются определенные действия. По сути, полиморфизм времени выполнения. На псевдокоде это выглядит так:
Код:
// Cell type1 fileds: index, name, doSmth11(), doSmth12()
// Cell type2 fileds: cost, group, doSmth21(), doSmth22()

Cell cellArr[N];
fill(cellArr);
a = cellArr[random(0,N-1)];
if (a.type == type1)
{
  a.doSmth11();
  a.doSmth12();
}
else if (a.type == type2)
{
  a.doSmth21();
  a.doSmth22();
}
Пример больше подходит для языков с динамической типизацией, но хотелось бы увидеть реализацию подобного на c++.
P.S. Хотелось бы посоветовать не использовать new в современных проектах: начиная с C++20 new является deprecated. Даже в примерах выше по причине использования new была продемонстрирована утечка памяти
upd: На cppReference ничего об этом не сказано. Также безрезультатно гуглил в других сточниках. Можно поинтересоваться, откуда информация?
 
Последнее редактирование: