Тут размещают свои топики новички в С/С++.

Тема в разделе "LANGS.C", создана пользователем nitrotoluol, 4 мар 2007.

  1. Aspire

    Aspire New Member

    Публикаций:
    0
    Регистрация:
    19 май 2007
    Сообщения:
    1.028
    AndreyMust19
    Вот, во втором проекте, ты из PE_work.cpp вызываешь функцию OpenPEfile, прототип которой, ты описываешь в заинклюденном файле PEcore.h (include "PEcore.h"), но сама функция у тебя описана в файле PEcore.cpp, который ты никуда не инклудишь. Ессно это не работает. В предыдущем проекте, у тебя все фунции прописаны в головном файле, а их прототипы - в хидере. Поэтому это и работает.
     
  2. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Aspire
    Что-то мне подсказывает, что не в этом дело.
     
  3. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    AndreyMust19
    Убери в PE_work.cpp
    #define UNICODE
    #define _UNICODE

    Думаю у тебя PEcore.cpp собирается в мультибайтовой версии, а PE_work.cpp в юникоде.
     
  4. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    Здраствуйте.
    Booster, ты прав, дело в:
    Код (Text):
    1. #define UNICODE
    2. #define _UNICODE
    Убираю их - все строится и линкуется (ну еще у строки L"D:\\PEfile.txt" букву 'L' убрать надо). Но почему? Unicode-функции мне нужны позарез (я собираю программу с Unicode-функциями, а не Ascii). Ведь данные дефайны влияют только на WinAPI-функции, но не на используемые типы LPCTSTR и HANDLE!
    Добавил:
    Да, похоже UNICODE влияет и на типы. Если добавить вышеперечисленные дефайны в PEcore.cpp (а, те, что в PE_work.cpp - оставить) , все линкуется! Но остается вопрос - почему эти дефайны так влияют на типы (ведь там и там LPCTSTR == unsigned short const *, а HANDLE = void *).
     
  5. Aspire

    Aspire New Member

    Публикаций:
    0
    Регистрация:
    19 май 2007
    Сообщения:
    1.028
    #Как переопределить тип переменной?

    Допустим, у нас есть переменная тип long-DWORD или просто указатель на куда-нибудь...
    После того, как я попользовал этот указатель в одних целях и он мне больше не треба, я хочу его поюзать для других, причем, как указатель.
    Например:
    Код (Text):
    1. void MyFunc(){
    2. long param;
    3. // где-то здесь юзаем param как long
    4. *(SYSTEM_INFORMATION**)&param = (SYSTEM_INFORMATION*)VirtualAlloc(bla-bla-bla);
    5. // дальше, мне нужно получить значение элемента структуры, например ->Base
    6. // и я хочу это сделать не объявляя дополнительной переменной, как если бы можно было написать
    7. *(SYSTEM_INFORMATION**)&param->Base = ... // но, компилятор не понимает ))
     
  6. meduza

    meduza New Member

    Публикаций:
    0
    Регистрация:
    15 авг 2008
    Сообщения:
    212
    Aspire
    Это плохой подход. Нужна переменная - объявляй и используй. Нужна еще одна - тоже. Иначе будут ошибки, код станет тредночитаем итп. Если уж очень надо использовать одну переменную как представителя двух или более типов, используй union.
    По поводу кода:
    1. Я не знаю, что такое SYSTEM_INFORMATION, поэтому не совсем понял, что ты хочешь, могу только предполагать. Если можно, приведи пример максимально отвлеченный от winapi и др., чтобы остался только С(++).
    2. "->" имеет более высокий приоритет, чем приведение к типу и разыменовывание. Может ты хотел написать что-то типа (*(SYSTEM_INFORMATION**)param)->Base.
    3. Арперсанд в &param не нужен, скорее всего.
     
  7. Aspire

    Aspire New Member

    Публикаций:
    0
    Регистрация:
    19 май 2007
    Сообщения:
    1.028
    Это все понятно, но хочется более оптимального кода. Причем, я не пишу супермегатребовательноекбыстротекодаиразмеруприложение. Посто коробит от лишнего кода под отладчиком. Обсуждать это не нужно, это не лечится.
    Вот за это спасибо. Не подумал о таком подходе.
    В остальном, скажу, что SYSTEM_INFORMATION это просто структура, можешь представить вместо нее любую другую. Все ты понял правильно.
    К сожалению не могу проверить сейчас твой вариант с поправкой на приоритеты, проверю вечером.
    Спасибо за подсказку.

    ЗЫ. амперсанд нужен.
     
  8. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    AndreyMust19
    Имхо эти дифайны там совсем не нужны. Гораздо проще и грамотнее указать это в свойствах проекта - configuration properties/Character Set или добавить в С/С++/Preprocessor/Preprocessor Definition - "UNICODE". А так получилось, что у тебя половина проекта юзает юникод, а половина мультбайт.

    Код (Text):
    1. #ifdef UNICODE
    2. typedef WCHAR TCHAR;
    3. #else
    4. typedef char TCHAR;
    5. #endif
    6. typedef const TCHAR FAR * LPCTSTR;
    Как видишь LPCTSTR в юникод версии отличается. Потому и ошибка, что собралась одна функция, а пытаешься вызвать другую.
     
  9. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228
    Aspire

    reinterpret_cast<SYSTEM_INFORMATION*>(param)->Base =

    нужен здесь *(SYSTEM_INFORMATION**)&param = (SYSTEM_INFORMATION*)VirtualAlloc(bla-bla-bla);

    и не нужен здесь *(SYSTEM_INFORMATION**)&param->Base =

    пойдет просто ((SYSTEM_INFORMATION*) param)->Base =
     
  10. meduza

    meduza New Member

    Публикаций:
    0
    Регистрация:
    15 авг 2008
    Сообщения:
    212
    Aspire
    Не гоняйся за вымышленной оптимизацией.

    Насколько я понял ты хочешь этого:
    Код (Text):
    1. void MyFunc(){
    2.     long param;
    3.     param = (long)VirtualAlloc(bla-bla-bla);
    4.     ((SYSTEM_INFORMATION*)param)->Base = ...
    Лучше так:
    Код (Text):
    1. void MyFunc(){
    2.     union { long as_long; SYSTEM_INFORMATION* as_ptr; } param;
    3.     param.as_ptr = (SYSTEM_INFORMATION*)VirtualAlloc(bla-bla-bla);
    4.     (param.as_ptr)->Base = ... /* скобки обязательны, приоритетет "->" выше "." */
    Но я не одобряю оба способа. Я бы сделал 2 переменные: типа long и SYSTEM_INFORMATION* и не занимался ерундой.
     
  11. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Aspire
    Это не человеческий подход. Таким образом экономить на стековых переменных совершенно бредово. Отмазки, что я с собой ничего не могу поделать не принимаются. Такая оптимизация нужна только в случае крайней необходимости.
     
  12. Aspire

    Aspire New Member

    Публикаций:
    0
    Регистрация:
    19 май 2007
    Сообщения:
    1.028
    Booster
    Какой смысл мне выделять новую переменную, если этот код присутсвует единожды, а остальные переменные уже отработали свое?

    letopisec, meduza, Booster, забыл сказать, спасибо!
     
  13. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Aspire
    Экономия от этого мизерная, а код становится более человеческим, более сопровождаемым. Если так хочется освободить переменную (особенно если она сложного типа), то лучше её поместить в отдельный блок, примерно так:

    Код (Text):
    1. {
    2. long param;
    3. // где-то здесь юзаем param как long
    4. }
    5. //Здесь переменная param будет уже уничтожена.
    З.Ы Правда это актуально только для С++. В С стековые переменные выделяются заранее, и такой фокус не проходит.
     
  14. verelex

    verelex New Member

    Публикаций:
    0
    Регистрация:
    15 ноя 2006
    Сообщения:
    90
    Здравствуйте, у меня вопрос:
    Код (Text):
    1. class CChildFrame : public CMDIChildWnd
    2. {
    3.     DECLARE_DYNCREATE(CChildFrame)
    4. public:
    5.     CChildFrame();
    6.  
    7. private:
    8.  
    9. // Attributes
    10. public:
    11.     static int NewFilesCount;
    12. ..................
    13.  
    14. CChildFrame::CChildFrame()
    15. {
    16.     NewFilesCount = 0;
    17. }
    ChildFrm.obj : error LNK2001: unresolved external symbol "public: static int CChildFrame::NewFilesCount" (?NewFilesCount@CChildFrame@@2HA)
    Как исправить?
     
  15. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    verelex
    В cpp файле написать:
    Код (Text):
    1. int CChildFrame::NewFilesCount = 0;
     
  16. verelex

    verelex New Member

    Публикаций:
    0
    Регистрация:
    15 ноя 2006
    Сообщения:
    90
    Booster, спасибо.
     
  17. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Все ли эти явные приведения типов эквивалентны?
    Можете ли пояснить механизм работы и разницу /если имеется/ в деталях? В каких ситуациях надо отдавать предопочтение какому из механизмов? Почему?
    [upd]
    Рассматривается поведение на 32/64 битн. платформах.
     
  18. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    asmfan
    Это - аналогично:
    Это тоже самое что:
    a = (b)+2;
    a = (b)+(2);
    a = b+(2);
     
  19. meduza

    meduza New Member

    Публикаций:
    0
    Регистрация:
    15 авг 2008
    Сообщения:
    212
    asmfan
    в С++ да, в Си нельзя делать int(a), ну и конечно всяких *_cast'ов тоже нет.
    Страуструп настоятельно рекомендует в С++ юзать *_cast'ы, причин много, они описаны в "Дизайн и Эволюция С++" и др. Он даже хотел совсем убрать Сишный способ приведения, но ему не "разрешили". Короче, в плюсах - *_cast'ы, в сях - (type)x.
     
  20. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Вопрос открыт теперь и для такого вида кода
    Код (Text):
    1. int a;
    2. size_t b = (size_t)a;
    3. size_t b = (size_t)(a);
    4. size_t b = size_t(a);
    5. size_t b = static_cast<size_t>(a);
    в каком-либо из случаев будет задействовано какое-либо промежуточное преобразование, т.н. implicit в int, например? Тот же вопрос к предыдущему моему посту.