Ru-MaNGOS

Ru-MaNGOS (http://mangos.ytdb.ru/index.php)
-   Языки программирования (http://mangos.ytdb.ru/forumdisplay.php?f=34)
-   -   Функции в С++ (http://mangos.ytdb.ru/showthread.php?t=5256)

partizanes 12.03.2012 12:42

Функции в С++
 
Вложений: 1
(если у вас предвзятое отношение к плохому коду не читайте дальше :ireful2:)
Подскажите как правильно должно быть оформлен вызов функции.
Да и оформление программы ,что должно быть в *.h что в *.cpp

допустим есть в файле form1.h событие




Код:

if ((this->textBox_login->Text) == "10" && (this->textBox_password->Text) == "10")
вот тут мне нужно вместо чисел 10 вызвать функцию запроса в бд и проверку на правильность.сама функция находиться в файле *.cpp

как все правильно это оформить?

если кому интересно проект во вложении.(это на самом деле первый опыт изучения с++ с нуля,куча ошибок в оформлении ,слабонервным не смотреть)

Во вложенном файле простейшая форма авторизации ,которую я пытаюсь подключить к mysql)))

Sid 12.03.2012 13:08

.h нужен для того что подключать написаные тобой классы, функкии к другим файлам.

.cpp содержит определения.

В .h
Код:

void foo();
В .cpp
Код:

void foo()
{
    printf("Hello");
}


partizanes 12.03.2012 13:28

пишем в *.h

PHP код:

else if ((this->textBox_login->Text) != "" && (this->textBox_password->Text) != "")
                 {
                 
void msg();
                 } 

в *.сpp

PHP код:

void msg()
{
Windows::Forms::MessageBox::Show("hello");


сообщение не выводиться ,Break в *.cpp не срабатывает

Sid 12.03.2012 15:28

Цитата:

Сообщение от partizanes (Сообщение 26587)
пишем в *.h

PHP код:

else if ((this->textBox_login->Text) != "" && (this->textBox_password->Text) != "")
                 {
                 
void msg();
                 } 

в *.сpp

PHP код:

void msg()
{
Windows::Forms::MessageBox::Show("hello");


сообщение не выводиться ,Break в *.cpp не срабатывает


нет, вот так

.h

PHP код:

void msg();

...

else if ((
this->textBox_login->Text) != "" && (this->textBox_password->Text) != "")
                 {
                 
msg();
                 } 

в .cpp все верно.

PS у вас слишком массивная функция в .h может лучше вот так ее тоже сделать?

.h
PHP код:

System::Void button1_Click(System::Object^  senderSystem::EventArgs^  e); 

.cpp
PHP код:

private: System::Void button1_Click(System::Object^  senderSystem::EventArgs^  e) {
             {

                 if ((
this->textBox_login->Text) == "")
                 {
                     if ((
this->textBox_password->Text) == "")
                     {
                         
Windows::Forms::MessageBox::Show("Введите Имя Пользователя и Пароль");
                         return;
                     }
                     
Windows::Forms::MessageBox::Show("Введите Имя Пользователя");             
                     return;
                 }
                 else if ((
this->textBox_password->Text) == "")
                 {
                     
Windows::Forms::MessageBox::Show("Введите Ваш Пароль");             
                     return;
                 }
             if ((
this->textBox_login->Text) == "10" && (this->textBox_password->Text) == "10")
             {
                
login_form->Hide();
                
menuStrip1->Visible true ;
                
panel1->Visible true ;
             } 
                
             else 
                {
                 
Windows::Forms::MessageBox::Show("Неправильное Имя Пользователя или Пароль");
                }
             } 
            } 

Я конечно не шарю в WinAPI но раз у вас есть private: макрос, то функция в классе. Тогда в .cpp перед ней еще имя класса укажите.

partizanes 12.03.2012 18:32

я так понимаю что бы начать понимать api , mfc и т.д нужно досконально изучить разработку консольных приложений?

partizanes 12.03.2012 22:23

а если так в *.h
Код:

int msg(int a);
...
private: System::Void quitToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e) {
                          int a = 5; //равно 5
                        msg(a); 
                                          //по идеи тут должно быть 15 ,а реально 5
                        this->Close();
                }

а в *.cpp
Код:

int msg (int a)
{
        a = a+10 ; //равно 15
        return(a); //вернуть значение в вызывавшую функцию
};

Почему в данном случае функция не возвращает значение?

Den 12.03.2012 22:41

Потомучто что, переменная а локальная, там и там.

TOM_RUS 12.03.2012 23:13

Что-то больше похоже на С++/CLI чем на С++...

partizanes 12.03.2012 23:23

Цитата:

Сообщение от TOM_RUS (Сообщение 26598)
Что-то больше похоже на С++/CLI чем на С++...

а я думаю что вы правы :yes3:

Просто я еще сам до конца не понял )


Цитата:

Сообщение от Den (Сообщение 26595)
Потомучто что, переменная а локальная, там и там.

ушел перечитывать главу про глобальные и локальные переменные :mda:

partizanes 20.03.2012 00:13

Вложений: 2
Не получается разобраться,подскажите может кто сталкивался.

Код:

mysql_init(&mysql);  // Инициализация
        mysql_real_connect(&mysql, host, user, passwd, db, port, NULL, CLIENT_FOUND_ROWS); // соединение

        if (mysql_query(&mysql, query) > 0) // запорс. Если ошибок нет, то продолжаем работу
        {

                // Если была ошибка, ...(Здесь ошибку не выводит)
                Windows::Forms::MessageBox::Show(ToUCS2(mysql_error(&mysql)));  // ... вывдем ее
                return; // и завершим работу
        }
        res = mysql_use_result(&mysql); // Берем результат,
        if(res == NULL)
        {
                Windows::Forms::MessageBox::Show(ToUCS2(mysql_error(&mysql)));
// (выводит только тут)(mysql server has gone away)
                mysql_ping(&mysql);
                mysql_query(&mysql, query);
                res = mysql_store_result(&mysql);
        }

       
        int num_fields = mysql_num_fields(res); // количество полей
        my_ulonglong num_rows = mysql_num_rows(res); // и количество строк.

отваливается на int num_fields = mysql_num_fields(res);
так как по дебагу
Код:

res        <undefined value>        st_mysql_res*
Код:

A first chance exception of type 'System.AccessViolationException' occurred in Trade.exe
An unhandled exception of type 'System.AccessViolationException' occurred in Trade.exe

Additional information: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.

дописал кусочек(синий код) после чего хоть что начало писать
итог "mysql server has gone away "

сам запрос
Код:

void auth()
{
        mysql("SELECT * FROM users"); // Запрос
}

http://ru-mangos.ru/attachment.php?a...1&d=1332191038

http://ru-mangos.ru/attachment.php?a...1&d=1332191038


Проверенно на 3 разных серверах mysql с разной конфигурацией

Deamon 20.03.2012 01:40

Я возможно отстал от жизни, но где в этом коде вызов mysql_select_db?

Evgeniy 20.03.2012 09:27

Цитата:

Сообщение от Deamon (Сообщение 26642)
Я возможно отстал от жизни, но где в этом коде вызов mysql_select_db?

наверное тут...
Код:

mysql_real_connect(&mysql, host, user, passwd, db, port, NULL, CLIENT_FOUND_ROWS);
на скриншотах видно, что и дб выбирается и пароли)))
возможно поможет :pardon:, так как сам разве что с sqlite работал
Код:

When using mysql_use_result(), you must execute mysql_fetch_row() until a NULL value is returned, otherwise, the unfetched rows are returned as part of the result set for your next query

partizanes 20.03.2012 10:05

в первом случае используется
Код:

res = mysql_use_result(&mysql); // Берем результат,
а вот после того уже если ничего нету
Код:

if(res == NULL)
на всякий случай делаем проверку на соединение
Код:

mysql_ping(&mysql);
делаем повторный запрос
Код:

mysql_query(&mysql, query);
пытаемся повторно извлечь результат
Код:

res = mysql_store_result(&mysql);
если поставить еще раз выводить ошибку
Код:

Windows::Forms::MessageBox::Show(ToUCS2(mysql_error(&mysql)));
получаем mysql server has gone away

tempura 20.03.2012 10:06

Цитата:

Сообщение от partizanes (Сообщение 26641)
итог "mysql server has gone away"

слишком тяжелый запрос для МуСКЛ. Попробовать сократить выборку.

partizanes 20.03.2012 10:12

Цитата:

Сообщение от tempura (Сообщение 26645)
слишком тяжелый запрос для МуСКЛ. Попробовать сократить выборку.

так в той таблице 2 значения и 2 колонки.
и эта ошибка не всегда связанна с тяжестью запроса

Код:

http://www.mysql.ru/docs/man/Gone_away.html

Evgeniy 20.03.2012 11:32

работает...черт меня побери
Код:

#include        <windows.h>
#include        <stdio.h>
#include        <mysql.h>

int main(int argc, char* argv[])
{
  MYSQL *conn;
  MYSQL_RES *result;
  MYSQL_ROW row;
  int num_fields;
  int i;

  conn = mysql_init(NULL);
  mysql_real_connect(conn, "localhost", "root", "passwd", "realmd", 0, NULL, CLIENT_FOUND_ROWS);

  mysql_query(conn, "SELECT * FROM account");
  result = mysql_use_result(conn);

  num_fields = mysql_num_fields(result);

  while ((row = mysql_fetch_row(result)))
  {
      for(i = 0; i < num_fields; i++)
      {
          printf("%s ", row[i] ? row[i] : "NULL");
      }
      printf("\n");
  }

  mysql_free_result(result);
  mysql_close(conn);
}


partizanes 20.03.2012 12:09

Код:

printf("\n");
С выводом в консоль я делал раньше ,там как то без проблем.

а вот перенести на С++/CLI не выходит

Evgeniy 20.03.2012 13:13

Цитата:

Сообщение от partizanes (Сообщение 26648)
Код:

printf("\n");
С выводом в консоль я делал раньше ,там как то без проблем.

а вот перенести на С++/CLI не выходит

mysql_options(conn, MYSQL_OPT_RECONNECT, "1");
может добавить?

partizanes 20.03.2012 13:31

по документации получается что если MYSQL_OPT_RECONNECT 0
Цитата:

Checks whether the connection to the server is working. If the connection has gone down and auto-reconnect is enabled an attempt to reconnect is made. If the connection is down and auto-reconnect is disabled, mysql_ping() returns an error.
то mysql_ping() реконектится не будет,а только вернет ошибку,кхм я думал что будет .
проверю вечером как приду с работы .

все равно почему пропадает соединение

по все той же документации получается что пропасть может если max_allowed_packet маленький или запрос не правильный.
но вроде все правильно.а ответа нету.

partizanes 20.03.2012 19:21

я думаю что нашел ответ на свой вопрос )
подключил лог к mysql

Цитата:

120320 19:13:55 4 Connect Client does not support authentication protocol requested by server; consider upgrading MySQL client
4 Connect root@localhost on trade

partizanes 20.03.2012 21:55

Вложений: 1
Не могу понять как указать в trade.cpp на dataGridView1 в Form1.h(public ref class Form1 : public System::Windows::Forms::Form)

Код:

DataGridView^ dataGridView1;
?



ловлю
Цитата:

A first chance exception of type 'System.NullReferenceException' occurred in System.Windows.Forms.dll
An unhandled exception of type 'System.NullReferenceException' occurred in System.Windows.Forms.dll

Additional information: Ссылка на объект не указывает на экземпляр объекта.
наверно вот так

Цитата:

DataGridView^ dataGridView1 = gcnew DataGridView;
Проект во вложении

и еще вопрос ,можно ли делать так (какое оформление правильное)

было

Код:

private: System::Windows::Forms::Button^  login_button;                                               
private: System::Windows::Forms::Button^  cancel_button;
private: System::Windows::Forms::GroupBox^  login_form;
private: System::Windows::Forms::TextBox^  textBox_password;
private: System::Windows::Forms::TextBox^  textBox_login;


делаем
Код:

private:
System::Windows::Forms::
                Button^  login_button;                                               
                Button^  cancel_button;                                       
               
                GroupBox^  login_form;
                TextBox^  textBox_password;
                TextBox^  textBox_login;


TOM_RUS 20.03.2012 23:53

Вложений: 1
А зачем использовать libmysql.lib, если есть сборка коннектора mysql под .NET?

http://www.mysql.com/downloads/connector/net/
http://www.mysql.com/downloads/mirror.php?id=406540

tempura 21.03.2012 10:07

ну тогда я вообще удивлен...
http://www.mysql.com/downloads/connector/cpp/
а вот эта штука для чего сделана?

TOM_RUS 21.03.2012 12:49

Цитата:

Сообщение от tempura (Сообщение 26654)
ну тогда я вообще удивлен...
http://www.mysql.com/downloads/connector/cpp/
а вот эта штука для чего сделана?

Возможно OOП альтернатива для libmysql.dll, там mysqlcppconn.dll вроде классы какие-то экспортирует...

partizanes 22.03.2012 21:58

Подскажите как преобразовать "System::String ^" в "cli::array<Type> ^"
прочитал много статей ,но увы не подошел ни один из результатов.


https://github.com/partizanes/trade/...e1b1436155a401



to TOM_RUS:
Код:

catch (Exception^ exc)
            {
                MessageBox::Show("Exception: " + exc->Message);
            }
            finally
            {
                if (reader != nullptr)
                    reader->Close();
            }
            return authok;

Вы использовали проверку на исключения ,а как можно проверить было ли исключение ?
(при появлении исключения , появляется MessageBox и с исключение и с не правильным паролем)

пытался что то типа

Код:

if (authok = false) && !(exc->Message)
{
Windows::Forms::MessageBox::Show("Неправильное Имя Пользователя или Пароль");
}

но как можно использовать указатель на (exc->Message) вне catch (Exception^ exc)


Спасибо вам за помощь в освоении конектора .

Konctantin 22.03.2012 22:56

Код:

array<Byte>^data = System::Text::Encoding::ASCII->GetBytes("hello world")

partizanes 22.03.2012 23:07

Спасибо ,именно этого кирпичика мне не хватало для получения md5

Evgeniy 22.03.2012 23:46

по аналогии с джава:
Код:

catch (IncorrectLoginException^ exc){
                MessageBox::Show("Exception input login: " + exc->Message);
}
catch (Exception^ exc){
                MessageBox::Show("Exception: " + exc->Message);
}finally{
  if (reader != nullptr)
                    reader->Close();
}

чем ниже спускаемся - тем более общий уровень Exception...ну а ловить желательно только свои ексепшены
Код:

if (authok = false)
Throw IncorrectLoginException


partizanes 23.03.2012 22:19

Цитата:

Сообщение от Evgeniy (Сообщение 26667)
по аналогии с джава:
Код:

if (authok = false)
Throw IncorrectLoginException


в том то и вся проблема что (authok = false) при неудачной авторизации по умолчанию ,не зависимо mysql отвалился или что то еще

Пока не удалось мне сделать исключение верно,видимо мне еще читать и читать про исключения до просветления ))) :pardon:

вопрос по md5 ,безопасно ли так хранить пароль?
// и насколько с точки зрения синтаксиса верна строка.


Создаю пользователя, пароль перегоняю в md5
Цитата:

cmd = gcnew MySqlCommand("INSERT INTO `users` VALUES (NULL,"+"'"+login+"'"+","+"'"+System::Text::Encodi ng::ASCII->GetString(MD5hash(System::Text::Encoding::ASCII->GetBytes(pass)))+"'"")",conn);
при авторизации проверяю
Цитата:

if(Auth(textBox_login->Text, System::Text::Encoding::ASCII->GetString(MD5hash(System::Text::Encoding::ASCII->GetBytes(textBox_password->Text)))))

Evgeniy 25.03.2012 13:33

хеш пароля генерировать с солью...тогда будет понадежнее

partizanes 25.03.2012 16:11

как то так? создаем переменную
Цитата:

String^ salt = System::Text::Encoding::ASCII->GetString(MD5hash(System::Text::Encoding::ASCII->GetBytes("135a")));
а потом приписываем при создании пароля и авторизации?
Цитата:

cmd = gcnew MySqlCommand("INSERT INTO `users` VALUES (NULL,"+"'"+login+"'"+","+"'"+salt+System::Text::E ncoding::ASCII->GetString(MD5hash(System::Text::Encoding::ASCII->GetBytes(pass)))+"'"+")",conn);
как я понял спасет только от "радужных таблиц" ?

Evgeniy 25.03.2012 16:27

  • hash = md5(salt + md5(pass))
  • hash = md5(md5(salt) + md5(pass))
  • hash = md5(md5(salt + pass))
так не будет видно соли =)))
я бы посоветывал использовать нативную mysql функцию MD5() приятнее для чтения..и лучше переписать на Prepared Statement ...а то мало ли что там в логин ляжет...

zergtmn 25.03.2012 17:39

C++/CLI - это язык для склеивания C++ native кода и .NET библиотек. Логику удобнее и быстрее реализовать либо в виде .net, либо С++ кода.

partizanes 19.06.2012 13:05

Возник вопрос как слинковать статистически MySql.Data.dll
(включить MySql.Data.dll в *.exe)

увы поиск как то не подсказывает(

zergtmn 19.06.2012 16:37

Цитата:

Сообщение от partizanes (Сообщение 27688)
Возник вопрос как слинковать статистически MySql.Data.dll
(включить MySql.Data.dll в *.exe)

увы поиск как то не подсказывает(

никак

TOM_RUS 19.06.2012 19:42

Качнуть сорцы можно и добавить в свой проэкт. Вроде можно и .NET сборку в exe как-то запихнуть :)
Зачем правда это я не понимаю.

Первые результаты поиска у гугле:
ILMerge
http://stackoverflow.com/questions/1...o-the-exe-file
http://stackoverflow.com/questions/2...other-assembly
http://stackoverflow.com/questions/1...led-executable

partizanes 19.06.2012 21:19

Все эти способы я видел,вопрос в том что они не стандартные ,кроме ILMerge.
(если честно я думал что это вообще делается 1 кликом мыши)
(поэтому поиск как бы не подсказывал простого решения)

по сути у меня получилось добавить в исполняемый файл длл с помощью vs, но сам ехе почему то его не видит.

на вопрос зачем,если конечно взять тот же framework то да смысл пихать огромное количество библиотек в ехе нет .
Когда же дело касается +256кб и не нужно человеку ставить коннектор ,мне кажется ответ очевиден.
В моем случае сам исполняемый файл спокойно скачивается на рабочий стол и там работает без лишних движений ,а вот зачем MySql.Data.dll еще рядом даже не знаю)

В любом случае спасибо за ответы и ваше мнение.

TOM_RUS 19.06.2012 21:49

Можно заинсталить сборку в GAC... Правда gacutil может не оказаться на клиентской машине...

И вообще проще заинсталить прогу куда нить в програм файлс, а на десктоп добавить ярлык...

partizanes 19.06.2012 22:08

Тогда уже как мне кажется
Код:

String^ path = (Environment::SystemDirectory)+"//MySql.Data.dll";
Код:

if (!File::Exists( path ) )       
{
      DownloadFile("http://www.site.com/MySql.Data.dll", ""+path);       
}

эххх ,а хотелось все так просто))

partizanes 23.06.2012 14:20

//deleted


Текущее время: 15:37. Часовой пояс GMT +3.

ru-mangos.ru - Русское сообщество MaNGOS