Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ошибки ddeml.h 
:(
    Опции темы
wallstreet
Дата 13.9.2011, 22:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



Спасибо за помощь, теперь все как надо.
Не понимаю почему появляются эти каракули, если при создании области памяти указывается размер буфера 

Цитата

sizeof(szDDEServerVersion)


кстати чем функция sizeof() более подходит чем lstrlen(), которая возвращает не кол-во символов в строке, а непосредственно длину без учета '\0'?
А еще по возможности прокомментируйте эту строку:
Цитата

*(LPSTR)(((LPBYTE)szBuf) + dwGetBytes) = '\0';

не понимаю как мы к массиву unsigned char прибавляем  unsigned long и присваиваем результату '\0'... Фактически замещая иероглифы?!?

Пользуясь случаем еще один вопрос хотел бы прояснить для себя. 
В чем разница между 0 и 0L, если говорим о типе DWORD?

Заранее благодарю!

Это сообщение отредактировал(а) wallstreet - 13.9.2011, 22:59
PM MAIL   Вверх
Estranged
Дата 14.9.2011, 01:09 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 30.8.2010

Репутация: нет
Всего: 3



Цитата(wallstreet @  13.9.2011,  22:41 Найти цитируемый пост)
Не понимаю почему появляются эти каракули, если при создании области памяти указывается размер буфера

Каракули появляются из-за неправильного указания размера буфера. DdeCreateDataHandle требует размер буфера в байтах, lstrlen же в данном случае требует UNICODE строку, коей szDDEServerVersion не является, поэтому надо использовать lstrlenA, но нет смысла это делать, потому что строка szDDEServerVersion не изменяется нигде, отчего можно использовать sizeof, который будет вычислен в процессе компиляции, а не во время работы программы. Конечно, если длина строки заранее неизвестна, то надо использовать lstrlenA (строка) + 1, в данном случае просто совпадение, что длина строки равна ее размеру в байтах, для UNICODE такой финт не проходит, поэтому универсальный способ - умножить размер строки на размер одного символа строки ((lstrlen () + 1) * sizeof (TCHAR)), для UNICODE это будет равносильно умножению на два, а для однобайтовых символов - на 1.

Цитата(wallstreet @  13.9.2011,  22:41 Найти цитируемый пост)
А еще по возможности прокомментируйте эту строку

Эта строка записывает нуль-терминатор после последнего актуального символа, полученного в функции DdeGetData, эта строка не нужна здесь, если есть учет нуль-терминатора в DdeCreateDataHandle.
И не замещает иероглифы, а устанавливает окончание строки. Все строки оканчиваются специальным непечатным символом - нуль-терминатором. Вообще-то, это арифметика указателей, просто найти адрес по смещению dwGetBytes байт от начала szBuf и вписать туда нуль-терминатор.

Цитата(wallstreet @  13.9.2011,  22:41 Найти цитируемый пост)
В чем разница между 0 и 0L, если говорим о типе DWORD?

DWORD - double word. Word - 16-битное число. В данном случае, это 32-битное беззнаковое целое число (unsigned long).
А посфикс L в числе - это просто указание, что данная константа типа long. Формально в этом проекте разницы нет никакой, т.к. в модели данных (компилятор MSVS C/C++) размеры в байтах типа int и long совпадают, разница есть тогда, когда long больше по размеру, чем int, такое тоже бывает.

Это сообщение отредактировал(а) Estranged - 14.9.2011, 01:11
PM MAIL   Вверх
GremlinProg
Дата 14.9.2011, 05:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: нет
Всего: 106



ужос  smile 

M
GremlinProg
еще немного, и тема перекочует в C++ для начинающих



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
GremlinProg
Дата 16.9.2011, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: нет
Всего: 106




M
GremlinProg
Тема перемещена из раздела C/C++: Системное программирование и WinAPI



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
wallstreet
Дата 22.9.2011, 20:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



Добрый день.
Решил сервер и клиент разбить на два разных приложения и не получается подсоединиться клиентом к серверу, хотя идентификаторы сервиса и топика у них одни и те же. Клиент подвисает на минуту, две и в результате не коннектится.
Чувствую, что в какой-то момент нужно приостановить работу сервера и каким-то образом ждать пока клиент не создаст коннект.Только как это сделать не могу понять. Точнее не могу понять на каком этапе и как сервер будет понимать, что к нему пытаются подконнектиться? Обычно это просходит когда колбек сервера возвращает XTYP_CONNECT в котором мы и сравниваем идентификаторы строк сервисов. Но в моем приложении колбек даже не вызывается клиентом.


Вобщем опять ай нид хелп.(
сервер и клиент прилагаю ниже:

сервер             клиент

Это сообщение отредактировал(а) wallstreet - 22.9.2011, 20:38
PM MAIL   Вверх
Estranged
Дата 23.9.2011, 23:56 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 30.8.2010

Репутация: нет
Всего: 3



Названия сервера не совпадает, топик и айтемом тоже не совпадает. Я бы удивился, если бы соединился клиент. smile 

Уберите приведение типа - все станет понятно:
Код

        hszService = DdeCreateStringHandle(idInst, (LPCWSTR)szService, CP_WINANSI);
        hszTopic = DdeCreateStringHandle(idInst, (LPCWSTR)szTopic, CP_WINANSI);
        hszItem = DdeCreateStringHandle(idInst, (LPCWSTR)szItem, CP_WINANSI);


Можно сделать вот так:
Код

        LPCWSTR lp = (LPCWSTR) szService;
// результат в lp ВНЕЗАПНО удивит, я гарантирую это.
        hszService = DdeCreateStringHandle(idInst, (LPCWSTR)szService, CP_WINANSI);
        hszTopic = DdeCreateStringHandle(idInst, (LPCWSTR)szTopic, CP_WINANSI);
        hszItem = DdeCreateStringHandle(idInst, (LPCWSTR)szItem, CP_WINANSI);


Я уже отвечал по поводу этого: http://forum.vingrad.ru/index.php?showtopi...t&p=2398575
Читать с слов "Второе: (LPCWSTR)"hInst" это такая хитрость обойти ошибку C2664 компилятора?"

Цитата(wallstreet @  22.9.2011,  20:35 Найти цитируемый пост)
Чувствую, что в какой-то момент нужно приостановить работу сервера и каким-то образом ждать пока клиент не создаст коннект.Только как это сделать не могу понять.

Сервер не отвечает, потому что он занят:
Код

cin >> ch;

Мы заблокировали работу программы.
Чтобы сервер нам ответил, мы должны предоставить свободу работы для сервера - не блокировать его:
В свойствах проекта сервера сменить тип системы на Windows (configuration properties - linker - system)
Выглядит вот так. Вместо main написать вот это, только предварительно разберитесь с приведениями типа к LPCWSTR в части с DdeCreateStringHandle:
Код

int APIENTRY WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR     lpCmdLine,
    int       nCmdShow)
{
    HINSTANCE hInst;
    MSG msg;

    hInst = GetModuleHandle(NULL);
    DDEServerOpen(hInst, TEXT ("Server"), TEXT ("Topic"), TEXT ("Item"));

    while (GetMessage(&msg, NULL, 0, 0)) 
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}


Среди минусов - невозможно остановить сервер - это приложение без окон.

PM MAIL   Вверх
wallstreet
Дата 25.10.2011, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



если открываю сервер так:
Код

DDEServerOpen(hInst, TEXT ("Server"), TEXT ("Topic"), TEXT ("Item"));


выдает ошибку невозможности приобразования const wchar_t[7] в LPSTR.
Не заню правильно или нет, но открывая сервер вот так:

Код

DDEServerOpen(hInst, "Server", "Topic", "Item");


при этом строки у меня типа LPSTR, насколько я понимаю это кодировка ASCI, которую в дальнейшем конвертирую
в LPWSTR

Код

BOOL DDEServerOpen(HINSTANCE hInst, LPSTR szService, LPSTR szTopic, LPSTR szItem)
{
    cout << " Opening DDE Server..." << endl;


    // создаем переходник для ф-ции обратного вызова
    lpDdeProc = MakeProcInstance((FARPROC)DdeServerCallback, hInst);

    // инициализируем сервер в библиотеке
    if(DdeInitialize((LPDWORD) &idInst, (PFNCALLBACK)lpDdeProc, APPCLASS_STANDARD, 0))
    {
        cout << " Initializing DDE Server..." << endl;
        return false;
    }
    // после удачной инициализации получаем идентификаторы строк для сервисе
    // раздела и элемента данных
    else
    {
        // создаем строки юникод
        LPWSTR wService;
        LPWSTR wTopic;
        LPWSTR wItem;
        int lenAszService = lstrlenA(szService);
        int lenAszTopic = lstrlenA(szTopic); 
        int lenAszItem = lstrlenA(szItem);
        int lenWszService, lenWszTopic, lenWszItem;

        lenWszService = ::MultiByteToWideChar(CP_ACP, 0, szService, lenAszService, 0, 0);
        lenWszTopic = ::MultiByteToWideChar(CP_ACP, 0, szTopic, lenAszTopic, 0, 0);
        lenWszItem = ::MultiByteToWideChar(CP_ACP, 0, szItem, lenAszItem, 0, 0);

        if(lenWszService > 0) // проверка на удачную конвертацию
        {
            wService = ::SysAllocStringLen(0, lenWszService);
            wTopic = ::SysAllocStringLen(0, lenWszTopic);
            wItem = ::SysAllocStringLen(0, lenWszItem);
            ::MultiByteToWideChar(CP_ACP, 0, szService, lenAszService, wService, lenWszService);
            ::MultiByteToWideChar(CP_ACP, 0, szTopic, lenAszTopic, wTopic, lenWszTopic);
            ::MultiByteToWideChar(CP_ACP, 0, szItem, lenAszItem, wItem, lenWszItem);
            
            hszService = DdeCreateStringHandle(idInst, wService, CP_WINANSI);
            hszTopic = DdeCreateStringHandle(idInst, wTopic, CP_WINANSI);
            hszItem = DdeCreateStringHandle(idInst, wItem, CP_WINANSI);
            cout << "hszServiceServ: " << hszService << endl;
            cout << "hszTopicServ: " << hszTopic << endl;
            cout << "hszItemServ: " << hszItem << endl;

            
        }
        // регистрируем сервис
        DdeNameService(idInst, hszService, (HSZ)NULL, DNS_REGISTER);
        cout << "idInstServ = " << idInst << endl;
        cout << "DdeNameServiceServ = " << DdeNameService << endl;
        return true;
    }
}


Вроде ошибок компилятор не выдает, но и консоль не грузится. И чувствую что что-то не так.
А так, если отклониться от темы, то купил недавно книгу по Win32 ("Технология программирования на с++ win32 API приложений" Н.А.Литвиненко) в надежде хоть чуток приобрести знаний по типам данных винды, ну и вообще. Вобщем облом, развернутой инфы нет, только вскользь на пол страницы про кодировки юникод и аски в отличии от описания различных функций.
Вот реально понимаю, что тема важная, надо знать.. Но как въехать в нее, с чего начать? Столько типов разных, как понимать какой из них применять именно в этом случае ну и вообще.. Вот к примеру в моем примере строки необходимо удалять функцией SysFreeString, однако она принимает только строки типа BSTR, а у меня то LPWSTR... уууу я схожу с ума)) 
Короче мне опять нужна ваша бесценная помощь.


Ссылка на проект

Это сообщение отредактировал(а) wallstreet - 25.10.2011, 23:03
PM MAIL   Вверх
wallstreet
Дата 17.11.2011, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



Господа, ларчик просто открывался))))

Код

    hszService = DdeCreateStringHandleA(idInst, szService, CP_WINANSI);
    hszTopic   = DdeCreateStringHandleA(idInst, szTopic, CP_WINANSI);
    hszItem    = DdeCreateStringHandleA(idInst, szItem, CP_WINANSI);


Это сообщение отредактировал(а) wallstreet - 17.11.2011, 15:31
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0790 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.