Программирование, На каком языке кодим, делимся опытом... |
Здравствуйте, гость ( Вход | Регистрация )
Программирование, На каком языке кодим, делимся опытом... |
Командор Норрингтон |
Dec 5 2006, 20:48
Сообщение
#1
|
Madman Группа: форумчанин Сообщений: 477 Регистрация: 28-August 06 Из: Planet Earth Пользователь №: 4,052 |
Я на VB6, и Delphi...
А вы на чём? |
Warship |
Jun 21 2010, 13:30
Сообщение
#61
|
Гроза морей Группа: бета-тестер Сообщений: 441 Регистрация: 29-April 07 Из: Прим. край г. Находка Пользователь №: 9,103 |
С# нормальный язык, но для своей области. Хотя она и большая в общем. С++ тоже не для всего хорош... Отличный язык, и естесственно для своей области - милое дело что-то делать на нем под WinWorms С++ просто "по-умолчанию" более низкоуровневый и компилируемый, да и пора новое изучать Ща попробую накидать твою прогу... посмотрим что получится. Спасибо На деле у меня все решилось с помощью объявления переменной retData в Dll с ключевым словом "static". Но с удовольствием посмотрю на другое решение. Сейчас уже морочусь с динамическим выделением памяти для возвращаемого массива - он же у меня динамический получается. И естесственно, хочется все это сделать без СТЛового вектора. |
navy |
Jun 22 2010, 06:58
Сообщение
#62
|
Hagane no Renkinjutsushi Группа: Seaward.Ru Team Сообщений: 5,970 Регистрация: 15-March 05 Из: Волгоград Пользователь №: 578 |
DLL
Код extern "C" __declspec(dllexport) CHAR * GetHello(); __declspec(dllexport) CHAR * GetHello() { CHAR* str = "Hellow World"; return str; } ЕХЕ Код typedef CHAR* (WINAPI *hHellowFunc)(VOID); int _tmain(int argc, _TCHAR* argv[]) { CHAR* str; hHellowFunc hHello=NULL; HINSTANCE hUserDLL=NULL; hUserDLL=LoadLibrary(_T("WinAPIDLL.dll")); if (hUserDLL==NULL) { printf("Error Load WinAPIDLL"); return FALSE; } hHello=(hHellowFunc)GetProcAddress(hUserDLL,"GetHello"); if (hHello==NULL) { printf("Error Load hHellow"); return FALSE; } str = (*hHello)(); printf("Result: %s.\n", str); ::FreeLibrary(hUserDLL); return 0; } Ну а изучать новое, я вот например хочу MVC 2.0 ща поизучать и SilverLight Ну может PHP заодно... в веб хочу немного уклониться. |
Warship |
Jun 22 2010, 09:07
Сообщение
#63
|
Гроза морей Группа: бета-тестер Сообщений: 441 Регистрация: 29-April 07 Из: Прим. край г. Находка Пользователь №: 9,103 |
Нави, спасибо.
Благодаря твоему примеру разобрался и в своем коде. Оказывается, моя запись Код EXPORT char* SomeTestFunc(const char* _data) { char* retDataPtr; char retData[] = "1234567890"; retDataPtr = &retData[0]; return retDataPtr; } В которой объявлялся массив retData (4 строка), неверная сама по себе. Он почему-то да EXE просто не доживает, хотя вроде и все правильно должен возвращать (указатель на первый элемент) Нужно было объявлять указателем, как у тебя: Код EXPORT char* SomeTestFunc(const char* _data) { char* retDataPtr; char* retData = "1234567890"; retDataPtr = &retData[0]; return retDataPtr; } Что интересно, если не использовать второй указатель (retDataPtr), то оба варианта работают одинакого хорошо, как этот: Код EXPORT char* SomeTestFunc(const char* _data) { char retData[] = "1234567890"; return retData; } Так и этот: Код EXPORT char* SomeTestFunc(const char* _data) { char* retData = "1234567890"; return retData; } С массивом только лезет предупреждение "warning: address of local variable 'retData' returned". Логику этого момента я так и не понял. Не мог бы ты мне пояснить, из-за чего собственно в моем первом варианте (массив + указатель на первый элемент массива) оно не работает? Вроде-бы записи же эквивалентные. |
navy |
Jun 22 2010, 11:58
Сообщение
#64
|
Hagane no Renkinjutsushi Группа: Seaward.Ru Team Сообщений: 5,970 Регистрация: 15-March 05 Из: Волгоград Пользователь №: 578 |
Цитата "warning: address of local variable 'retData' returned". этот ворнинг показывает, что произошло неявное преобразование типов char[] в char*. Т,е. просто был передан указатель на массив (компилер правильно разобрался) Чтобы понять почему твой код неверен, неплохо бы его прогнать в дебаггере, типа IDA, для наглядности Скорее всего проблема в том, что это разные данные с точки зрения компилера... и поэтому он их размещает в разных участках памяти.. char retData[] = "1234567890" это наверно в стек а это CHAR* str = "Hellow World"; в ресурс или наоборот ПОэтому у тебя указатель и показывает в пустоту.. т.к. относительно ДЛЛ и ЕХЕ это разные адреса Хотя, по идее, твой вариант должен работать как надо... я дома поднима куски длл-ки для шторма, там похоже было, гляну че и как |
Warship |
Jun 23 2010, 13:11
Сообщение
#65
|
Гроза морей Группа: бета-тестер Сообщений: 441 Регистрация: 29-April 07 Из: Прим. край г. Находка Пользователь №: 9,103 |
Хотя, по идее, твой вариант должен работать как надо... я дома поднима куски длл-ки для шторма, там похоже было, гляну че и как Ок, спасиб По ходу дела появились еще вопросы: Например, мне нужно запихнуть определенный байт в буфер (void*, указатель на область памяти; я его юзаю вместо C-шарпового массива байт ). Я делал так (не факт, что это вообще правильно; тут еще и сам буфер усекается до этой позиции) Код void* arrayPtr = NULL; arrayPtr = BufferSet(arrayPtr, 0x01, 0); arrayPtr = BufferSet(arrayPtr, 0xA0, 1); // ... /// Функция записывает в буфер указанный байт на указанную позицию. void* BufferSet(void* _buff, unsigned char _byte, unsigned long _pos) { _buff = realloc(_buff, _pos + 2); ((unsigned char*) (_buff))[_pos] = _byte; ((unsigned char*) (_buff))[_pos + 1] = '\0'; return _buff; } И здесь появляется непонятный мне момент - если не записывать завершающий нуль, то в буфере в конце оказывается какой-то мусор - откуда он? Второй вопрос: как сделать, чтобы функция не возвращала указатель, а записывала все это дело в свой первый параметр? Т.е. по типу ref/out параметров в C#. P.S. Спец. литературы по C++ мне сейчас читать особо не хочется, ибо пока-что освоение языка идет очень неспешно и больше с оглядкой на C#. Когда возьмусь более серьезно, наверное, буду укуриваться Бьерном Страуструпом и его книгой "Язык программирования C++" - судя по отзывам в инете, она лучшая. |
navy |
Jun 23 2010, 18:02
Сообщение
#66
|
Hagane no Renkinjutsushi Группа: Seaward.Ru Team Сообщений: 5,970 Регистрация: 15-March 05 Из: Волгоград Пользователь №: 578 |
Цитата тут еще и сам буфер усекается до этой позиции естественно ты же его релокейтишь как Цитата realloc(_buff, _pos + 2) т.е. до размера pos+2 Цитата если не записывать завершающий нуль, то в буфере в конце оказывается какой-то мусор - откуда он? ты скорее всего неправильно указываешь размер буфера, т.е. делаешь его слишком большим, а следовательно хвост у тебя остается тем, что было в памяти уже до того, как ты сказал, что это будет массивом. Это если я правильно помню все |
Warship |
Jun 24 2010, 00:17
Сообщение
#67
|
Гроза морей Группа: бета-тестер Сообщений: 441 Регистрация: 29-April 07 Из: Прим. край г. Находка Пользователь №: 9,103 |
естественно ты же его релокейтишь как Ну да, это понятно. Это у меня скорее такое рассуждение было ты скорее всего неправильно указываешь размер буфера, т.е. делаешь его слишком большим, а следовательно хвост у тебя остается тем, что было в памяти уже до того, как ты сказал, что это будет массивом. Да нет, размер я вроде указывал верный. Было вот так, пример: Код arrayPtr = NULL; arrayPtr = BufferSet(arrayPtr, 0x01, 0); arrayPtr = BufferSet(arrayPtr, 0xA0, 1); printf("arrayPtr: %s.\n", (char*) arrayPtr); // Вывод - два мои байта + левый хвост из 10-12 /// Функция записывает в буфер указанный байт на указанную позицию. void* BufferSet(void* _buff, unsigned char _byte, unsigned long _pos) { _buff = realloc(_buff, _pos + 1); ((unsigned char*) (_buff))[_pos] = _byte; return _buff; } Т.е. при первом вызове буфер резайзится до 1 байта и туда кладется 0x01, при втором вызове - 2 байта и 0xA0. Вродеб, все верно, но хвост есть. |
navy |
Jun 24 2010, 11:59
Сообщение
#68
|
Hagane no Renkinjutsushi Группа: Seaward.Ru Team Сообщений: 5,970 Регистрация: 15-March 05 Из: Волгоград Пользователь №: 578 |
В общем, ты лучше озвучивай конкретный пример, потому как абстрактно думать трудно байт в массив запихнуть можно значительно проще
|
Warship |
Jun 24 2010, 12:42
Сообщение
#69
|
Гроза морей Группа: бета-тестер Сообщений: 441 Регистрация: 29-April 07 Из: Прим. край г. Находка Пользователь №: 9,103 |
У меня глобальных задач не было Для того, чтобы опробовать свои силы, захотелось перетащить реализацию алгоритма кодирования длин серий (RLE ) с C# на C++ в ДЛЛку. Ну вот и упражняюсь Если интересно, что получилось: ДЛЛка: Заголовок: Код #ifndef COMPRESS_H #define COMPRESS_H #define EXPORT extern "C" __declspec (dllexport) EXPORT void* RLEEncode(const void* _data, const unsigned long _length); EXPORT void* RLEDecode(const void* _data, const unsigned long _length); void* BufferSet(void* _buff, unsigned char _byte, unsigned long _pos); #endif Реализация: Код #include <windows.h> #include "Compress.h" /// Точка входа в DLL. bool APIENTRY DllMain(HINSTANCE _instance, DWORD _reason, LPVOID _reserved) { return true; } /// Функция производит сжатие указанных данных на основе алгоритма кодирования повторов. EXPORT void* RLEEncode(const void* _data, const unsigned long _length) { unsigned long curDataPos; unsigned long bufPos = 0; unsigned char count = 1; unsigned char curByte; unsigned char nextByte; void* retData = NULL; for(curDataPos = 0; curDataPos < _length; curDataPos++) { curByte = ((unsigned char*) _data)[curDataPos]; nextByte = (curDataPos == _length - 1 ? ((unsigned char*) _data)[curDataPos - 1] : ((unsigned char*) _data)[curDataPos + 1]); // Если уже на границе массива, сравниваем с предыдущим if(curByte == nextByte && count < 255 && curDataPos < _length - 1) { count++; } else { retData = BufferSet(retData, count, bufPos++); // Длина повтора retData = BufferSet(retData, curByte, bufPos++); // Байт повтора count = 1; } } return retData; } /// Функция производит восстановление данных, сжатых на основе алгоритма кодирования повторов. EXPORT void* RLEDecode(const void* _data, const unsigned long _length) { unsigned long curDataPos; unsigned long bufPos = 0; unsigned char count; unsigned char curByte; void* retData = NULL; for(curDataPos = 0; curDataPos < _length; curDataPos += 2) { count = ((unsigned char*) _data)[curDataPos]; curByte = ((unsigned char*) _data)[curDataPos + 1]; while(count-- > 0) { retData = BufferSet(retData, curByte, bufPos++); } } return retData; } /// Функция записывает в буфер указанный байт на указанную позицию. void* BufferSet(void* _buff, unsigned char _byte, unsigned long _pos) { _buff = realloc(_buff, _pos + 2); //if(_buff != NULL) //{ ((unsigned char*) (_buff))[_pos] = _byte; ((unsigned char*) (_buff))[_pos + 1] = '\0'; //} return _buff; } Приложение: Реализация: Код #include <stdio.h> #include <windows.h> typedef void* (*RLEEncode)(const void* _data, const unsigned long _length); typedef void* (*RLEDecode)(const void* _data, const unsigned long _length); /// Точка входа в приложение. int main(int argc, char* argv[]) { char* sTextToEncode = "AAABBCC"; void* buffer; RLEEncode Encode; RLEDecode Decode; HINSTANCE compressDll = LoadLibrary("Compress.dll"); if(compressDll == NULL) { printf("ERROR: unable to load DLL!\n"); system("pause"); return 1; } Encode = (RLEEncode) GetProcAddress(compressDll, "RLEEncode"); Decode = (RLEDecode) GetProcAddress(compressDll, "RLEDecode"); if(Encode == NULL || Decode == NULL) { printf("ERROR: unable to find DLL functions!\n"); system("pause"); return 1; } buffer = Encode(sTextToEncode, 7); printf("Encoded data: %s\n", (char*) buffer); buffer = Decode(buffer, 6); printf("Decoded data: %s\n", (char*) buffer); free(buffer); delete[] sTextToEncode; FreeLibrary(compressDll); system("pause"); return 0; } Вот сейчас хочется переделать фукнции в ДЛЛке, чтобы они сразу писали в указанный буфер, а не возвращали указатель на новый, ибо память утекает при вызове buffer = Encode(buffer, ...); - указатель на прежний ведь теряется А как тут будет проще байт запихнуть-то? Можно, конечно, юзать STL класс vector (или stack ), но хотелось сделать это максимально "ручками" Собственно, тут есть еще одна проблема: Как можно определить размер этого буффера? Сейчас у меня размер, который передается в функции кодирования, захардкоден, но этож не дело |
navy |
Jun 25 2010, 06:53
Сообщение
#70
|
Hagane no Renkinjutsushi Группа: Seaward.Ru Team Сообщений: 5,970 Регистрация: 15-March 05 Из: Волгоград Пользователь №: 578 |
Вообще использование стандартных классов это нормально, и даже правильно ты же используешь например cout , вместо того, чтобы писать в консоль напрямую
длина массива определяется как _msize(), в байтах. Для того, чтобы память не утекала можно использовать новый указатель, а старый освобождать. |
Warship |
Jun 25 2010, 08:54
Сообщение
#71
|
Гроза морей Группа: бета-тестер Сообщений: 441 Регистрация: 29-April 07 Из: Прим. край г. Находка Пользователь №: 9,103 |
Вообще использование стандартных классов это нормально, и даже правильно ты же используешь например cout , вместо того, чтобы писать в консоль напрямую Оно-то правильно, но это будет чуть позже Сейчас хочется именно прочувствовать принципы работы, пусть даже и в стандартный поток вывода писать напрямую. У меня же тут вообще фактически велосипед получается Т.е. дело вовсе не в результате, а в процессе - узнаю новое. А вот что не получается, то спрашиваю За _msize() спасиб, то, что нужно |
navy |
Jun 25 2010, 19:15
Сообщение
#72
|
Hagane no Renkinjutsushi Группа: Seaward.Ru Team Сообщений: 5,970 Регистрация: 15-March 05 Из: Волгоград Пользователь №: 578 |
Вообще, лучший способ изучить язык, это написать на нем что-то конкретное. Т.е. ставишь задачу, написать такую вот программу... и пишешь ее. Я так же изучал С#. Написал простую игру для тренировки памяти Она конечно ужасна!! Но это мне сильно помогло
|
Диман |
Sep 19 2010, 15:38
Сообщение
#73
|
боцман Группа: форумчанин Сообщений: 212 Регистрация: 3-January 06 Пользователь №: 2,113 |
Может посоветуйте книжку хорошую по C++. Желательно с уклоном в ООП.
Собственно только щас решил изучить С++, до этого работал со скриптами php javascript. Просмотрел большое количество книг по C++ наиболее приглянулась - Джес Либерти освой C++ за 24 часа. обучение хорошее, но как дошло до конструктора в классах потерялся. Да и компилятор не всё выполняет , что в книге написано. Есть ли книга, с пошаговым объяснением принципов ООП? И есть ли книга, где обучение строится на создании одной какой нибудь программы, а не простых примерах? Когда изучал php, обучение строилось в написании полноценного сайта, мне такой стиль удобней, чем обучение на мелких программках типа вычисли температуру в цельсиях или рассчитай возраст. |
Warship |
Sep 20 2010, 04:11
Сообщение
#74
|
Гроза морей Группа: бета-тестер Сообщений: 441 Регистрация: 29-April 07 Из: Прим. край г. Находка Пользователь №: 9,103 |
Можно попробовать курнуть книжку Бьерна Страуструпа "Язык программирования C++" (писал где-то выше), точнее, ее вторую часть "Механизмы абстракции". Там около 200 листов, ООП вроде неплохо расписано.
Но в общем и целом мне эта книга не очень понравилась, хотя и она хороша. Много воды в ней, что-ли, да и просто объемная. Вообще, принципы ООП везде ведь одни и теже - что в PHP, что в C++. Реализация только синтаксически отличается. Ну а задачу... Ее можно и самому себе поставить, а не взять из книги И так даже лучше будет, ИМХО, а потом уже, по ходу дела, в процессе реализации этой глобальной задачи искать ответы на более мелкие Я себе вообще отыскал книжку "C++ Cookbook", от О'Рейли Она вот крута |
ALexusB |
Sep 20 2010, 11:22
Сообщение
#75
|
Разработчик ВМЛ-КВЛ Группа: Admin Сообщений: 16,333 Регистрация: 2-November 04 Пользователь №: 3 |
Книга "Совершенный код" С. Макконнелл - как настольная книга, к которой возвращаться и перечитывать - пофиг на каком языке - это просто, чтоб уметь программировать качественно, а не быть
Книги издательства О"рейли - отличная подборка. Бери подходящие под себя (для начала, для потом, для оттачивания мастерства). |
Диман |
Sep 20 2010, 15:16
Сообщение
#76
|
боцман Группа: форумчанин Сообщений: 212 Регистрация: 3-January 06 Пользователь №: 2,113 |
O'Reilly ни в ozon ни на торрентах не нашел, про C++ и C.
Есть подборки книг штук по 300, но все на английском. Совершенный код - рановата еще. Страуструпа попробую почитать. И еще интересно, от компилятора многое зависит? Щас использую visual C++ 10, еще есть Dev-C++. Пока большой разницы не заметил, кроме отсутствия поддержки переменных на русском в Dev-C++. Не получится так, что сменив компилятор, придется переучиваться под него? |
ALexusB |
Sep 20 2010, 15:25
Сообщение
#77
|
Разработчик ВМЛ-КВЛ Группа: Admin Сообщений: 16,333 Регистрация: 2-November 04 Пользователь №: 3 |
Книжку "Совершенный код" никогда не бывает читать РАНО. Ее бывает читать ПОЗДНО (когда уже стиль не исправить).
Ее можно (и нужно) читать не всю, а как справочник по идеям, стилям и подходам. И перечитывать (дочитывать) через несколько лет. Первые 2-3 главы там вообще нужно читать всем НЕкодерам, а кто им ТЗ ставит или работает в командах по изготовлению ПО. Забавная недословная цитата из ДТФ постмортема одной игры "А потом ведущий разработчик дочитал книжку Совершенный код, написал с нуля прототип за неделю и было принято решение выкинуть все, что делали до того целый год и начать заново в правильной архитектуре, что в итоге и привело к релизу и удобному редактору контента" Сам я эту книжку прочел поздно (недавно только), но к счастью своему делал и без книжки все почти так же, то есть подтверждаю слова автора - это хорошие практики. Просто без опыта им сложно верить и выбрать свои (мне не все нужны), а все примерять на себе на практики просто сложно. |
Диман |
Sep 20 2010, 20:20
Сообщение
#78
|
боцман Группа: форумчанин Сообщений: 212 Регистрация: 3-January 06 Пользователь №: 2,113 |
Книжку "Совершенный код" никогда не бывает читать РАНО. Ее бывает читать ПОЗДНО (когда уже стиль не исправить). Ее можно (и нужно) читать не всю, а как справочник по идеям, стилям и подходам. И перечитывать (дочитывать) через несколько лет. Первые 2-3 главы там вообще нужно читать всем НЕкодерам, а кто им ТЗ ставит или работает в командах по изготовлению ПО. Я только несколько дней назад, начал изучать компилируемый язык, до этого тока интерпритируемые. Поэтому хочется сейчас просто "въехать", и не терятся. У меня пока практики вообще нету, следовательно я даже о стиле представления не имею. И в самой книжке например на стр 231 идет тест на знание типов данных, посмотрел знаю только 9-12 из 29. хотя о других типах имею представление, но никогда их не использовал. И автор сам пишет, мол поучись еще, а потом снова приходи. |
navy |
Sep 21 2010, 06:41
Сообщение
#79
|
Hagane no Renkinjutsushi Группа: Seaward.Ru Team Сообщений: 5,970 Регистрация: 15-March 05 Из: Волгоград Пользователь №: 578 |
Разницы на каком языке писать нет вообще. На языках пишут кодеры, программисты пишут на любом, потому как программирование это не написание кода, а описание модели.
По поводу с++ берешь ЛЮБУЮ книжку... и начинаешь изучать... базовое, что ты из этого вынесешь как минимум знание типов и синтаксиса. А по ООП можно найти отдельную книжку. И вообще, задач поставлена слишком абстрактно. Ты скажи что ты хочешь от С++ конкретно. Вот мы с Варшипом как-то поговорили на эту тему Абстрактное знание тут невозможно. Ставь конкретные задачи, получишь конкретные ответы. |
Warship |
Sep 21 2010, 08:39
Сообщение
#80
|
Гроза морей Группа: бета-тестер Сообщений: 441 Регистрация: 29-April 07 Из: Прим. край г. Находка Пользователь №: 9,103 |
На деле кстати да, книга и не нужна вообще по конкретному языку Понимание синтаксиса и типов (это ладна, можно из книги ) + наличие описания стандартной библиотеки (STL, для Visual C++ там будет еще ересь вроде MFC, для Борланда - VLC) + понимание программирования как процесса - это вот все вместе и позволит создавать любые по сложности системы.
Я так в свое время постигал AS 3.0. Была книжка от О'Рейли "CookBook" (с примерами, как готовить ) + описание библиотеки + примеры готового (и, конечно, хороший учитель ). |
Текстовая версия | Сейчас: 9th June 2024 - 11:03 |