Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Передать параметром функции указатель на слот

Пытаюсь сделать такое извращение, чтобы упростить создание меню
Код C++ (QT)
1
2
3
4
5
6
7
QAction *Window::newAction(QString name, QString file, QMenu *menu, void (*slot)(), QString shcut) {
    QAction *action = new QAction(QIcon(file), name, menu);
    connect(action, &QAction::triggered, this, slot);
    action->setShortcut(shcut);
    menu->addAction(action);
    return action;
}
В коде вызываю так
Код C++ (QT)
1
QAction *actionNewFile = newAction("New..", ":/img/ico/newFile.png", menuFile, &Window::addNewFile, "Ctrl+N");
Как правильно передать указатель на слот я не нагуглил, а ошибка именно в этом
Код Code
1
error: no matching function for call to 'Window::newAction(const char [6], const char [17], QMenu*&, void (Window::*)(), const char [7])'
Подскажите, пожалуйста, как исправить.

Добавлено через 4 часа 4 минуты
Код C++ (QT)
1
2
3
4
5
6
7
void *Window::f(void (*f_p)()) {
    f_p();
}
 
void Window::foo() {
    qDebug() << "why";
}
Код C++ (QT)
1
f(&foo);
Код Code
1
2
3
error: no matching function for call to 'Window::f(void (Window::*)())'
     f(&foo);
           ^
Объясните, чому я iнвалiд?
Ответ: А зачем вам конект внутри функции newAction, если вы свежесозданное действие передаете наружу.
Может проще законектить там, откуда вы вызываете эту функцию?

Есть 2 типа указателей на функции: обычные и функции-члены. Путать эти типа указателей нельзя.
Указатель на обычную функцию
Код C++ (QT)
1
2
3
<тип результата> (*f_p)(<аргументы>)
f_p = &func;
f_p(...);
и на функцию-член
Код C++ (QT)
1
2
3
4
<тип результата> (<ClassName>::*f_p)(<аргументы>)
f_p = &<ClassName>::func;
<ClassName> a;
(a.*f_p)(...)
В вашем случае идет как раз смешивания разных типов указателей
Вопрос: Перечисление как параметр функции

Приветствую всех. Есть перечисление, которое используется как параметр функции. При этом в функцию можно передать такое значение, которого в самом перечислении нет. Почему компилятор не ругает за это?
C++
1
2
3
4
5
6
7
8
enum Numbers { One, Two };
Numbers GetNum(Numbers n) { return n; }
 
Numbers a = GetNum(One); // Все хорошо, вопросов нет
a = GetNum(5); // Тут только предупреждение компилятора
a = GetNum(Numbers(5)); // Тут со стороны компилятора вообще тишина
 
// Как сделать, чтобы функция могла принимать только значения One или Two?
Ответ: Ясно. А то засело в голове, что для указания параметра функции можно применить подобие комбобокса, то есть выбор значения из заданных и ничего больше.
Разрешите тогда еще вопрос, связанный с перечислениями. Режим функции будет задаваемый перечислением. В функции это значение перечисления будет проверяться на допустимость. Далее, в соответствии режимом, необходимо использовать определенную константу. Как это лучше всего осуществить? Пока планирую использовать значение перечисления в качестве индекса массива, хранящего необходимые константы.
Вопрос: Возможно ли передать в функцию номер строки кода где она вызвана?

Возможно ли передать в функцию номер строки в коде, где вызвана функция? Что бы передавалось по умолсчанию
Например SomeFunction (var AdoQ:TADOQuery; LogPath: string = 'C:\logFromQuery.txt');
И в теле функции файлу добавлять номер строки.
Ответ:
Михаил11111
Возможно ли передать в функцию номер строки в коде, где вызвана функция? Что бы передавалось по умолсчанию
Например SomeFunction (var AdoQ:TADOQuery; LogPath: string = 'C:\logFromQuery.txt');
И в теле функции файлу добавлять номер строки.


Читать внимательно:

Вопрос: Запуск приложения через CreateProcess(), передать параметры запуска, указать тот же каталог

Здравствуйте, помогите побороться с CreateProcess()
Есть рабочая программа, которая должна запустить независимый процесс. Запуск нужно сделать из той-же папки в которой лежит программа родитель. В этот процесс необходимо передать параметр указанный в переменной string родителя.

Код постарался максимально снабдить комментариями чтобы было понятно в чем именно я не могу получить результат

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// Структура с переменными передаваемыми в поток
typedef struct
{
    std::string EmailStr;
} MsParams_t;
 
 
//Дочерний поток, запускает независимый процесс
unsigned __stdcall Potok(void* data)
{
    MsParams_t * ptr = (MsParams_t *)data;
 
    //  Передаем Email
    std::string EmailStrP = ptr->EmailStr;
 
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
 
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));
    
 
       //Тут в идеале я бы хотел получить каталог из которого запускается основная функция,
       //не знаю как это сделать, на MSDM информация крайне скудна, 
       //Application::StartupPath Property я так и не понял как это работает. 
       //И не нашел ни одного примера на с++
       //с# вдоволь, но перестроиться под плюсы не могу (((
 
        std::string catal = "H:/Android/C++/VisualStudio/Server/Server/Debug/MyApp.exe ";
      
       // следующей строчкой пытаюсь передать аргумент для запуска, т.е. передать мыло 
       // MyApp.exe получает его и понимает как argv[1];
   
 
    catal += EmailStrP.c_str();
 
       //строю строку для запуска   
       const char * runExePath = catal.c_str();
       
        printf(runExePath);
    printf("\n");
 
        //В консоль выводится нормальная строка, которую я и ожидаю увидеть
       // типа "H:\Android\C++\VisualStudio\Server\Server\Debug [email]mymail@mail.com[/email]"
 
        // На радостях пытаюсь передать строку в функцию запуска, и на выходе получаю ошибку 2
 
    // Start the child process. 
    if (!CreateProcess(
                runExePath,   // No module name (use command line)
        NULL,       // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        FALSE,          // Set handle inheritance to FALSE
        0,                 // No creation flags
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &si,              // Pointer to STARTUPINFO structure
        &pi)             // Pointer to PROCESS_INFORMATION structure
        )
    {
        printf("CreateProcess failed (%d).\n", GetLastError());
        return 0;
    }
 
    // Wait until child process exits.
    WaitForSingleObject(pi.hProcess, INFINITE);
 
    // Close process and thread handles. 
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
 
    return 0;
}
 
 
 
int main()
{
 
std::string Email = "mymail@mail.com";
 
 
                        //Заполняем структуру для передачи в поток
            static MsParams_t params;
            params.EmailStr = Email;
 
                        //Запускаем поток и отпускаем его в свободное плавание
            std::thread tt = std::thread(&Potok, (void*)&params);
            tt.detach();
 
system("pause");
return 0;
}
Еще раз вопросы:
1 Пожалуйста, в моем коде, если возможно, подскажите как правильно получить каталог запуска и передать его в параметры, я хочу запускать дочернюю программу и той же папки где лежит родитель, и не прописывать в коде каждый раз каталог, если я поменяю расположение программы родителя.
2 Пожалуйста подскажите как вообще запустить все это дело, как передать Email, почему у меня выпадает постоянно ошибка 2, если я не указываю Email, то программа отрабатывает нормально, в смысле запускается дочерний процесс, но разумеется никакие параметры в него не передаются.
Гугление подсказало что нужно заполнить вторую строку - NULL, // Command line
Но, оно не помогло мне найти доступный вариант переделки STRING to LPTSTR, вариант STRING.c_str() - не работает, функция не принимает его.

3 Если в Вашем арсенале есть вариант запуска процессов через UINT WinExec() пожалуйста покажите как реализовать его, но таким образом, чтобы также явно закрыть хендлы, и не беспокоиться об утечках памяти.

Спасибо.

Добавлено через 30 минут
Пока что на второй свой вопрос нашел ответ в гугле, ужасно уродливый, может быть подскажите что-то более изящное.
Т.е. в принципе я запуститься смог, создал LPTSTR, но решение мне не кажется нормальным.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    std::string temp = catal + EmailStrP;
        
    std::string str = temp;
    TCHAR *param = new TCHAR[str.size() + 1];
    param[str.size()] = 0;
    std::copy(str.begin(), str.end(), param);
    
    LPTSTR cmdArgs = param;
 
 
    printf(runExePath);
    printf("\n");
 
    // Start the child process. 
    if (!CreateProcess(
                runExePath,   // No module name (use command line)
        cmdArgs,        // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        FALSE,         // Set handle inheritance to FALSE
        0,                // No creation flags
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &si,            // Pointer to STARTUPINFO structure
        &pi)           // Pointer to PROCESS_INFORMATION structure
        )
    {
        printf("CreateProcess failed (%d).\n", GetLastError());
        return 0;
    }
Также я все еще прошу, пожалуйста помогите получить каталог запускаемого приложения через

Application::StartupPath Property, или
Ну или другим способом, который обычно используете сами.
Ответ: Итак, ребята кому нужно берите код, нагуглил вариант использования GetModuleFileName
может быть кому-то будет полезно без углубления в мануалы с++...
Все еще остался вопрос Уродства преобразования в LPTSTR, на мой взгляд криво, если есть более изящный вариант,
я буду рад его увидеть. Но и в таком виде код работает, все параметры передаются, пожалуйста пользуйтесь на здоровье.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Структура с переменными передаваемыми в поток
typedef struct
{
    std::string EmailStr;
} MsParams_t;
 
//Получаем строку каталога
 std::string ExePath()
{
    char buffer[MAX_PATH];
    GetModuleFileName(NULL, buffer, MAX_PATH);
    std::string::size_type pos = std::string(buffer).find_last_of("\\/");
    return std::string(buffer).substr(0,pos);
}
 
 
//Дочерний поток, запускает независимый процесс
unsigned __stdcall Potok(void* data)
{
    MsParams_t * ptr = (MsParams_t *)data;
 
    //  Передаем Email
    std::string EmailStrP = ptr->EmailStr;
 
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
 
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));
    
 
        //Получаем каталог из которого запускаем основное приложение
        std::string catal = ExePath()+"\\MyApp.exe ";
        
       //строю строку для запуска   
       const char * runExePath = catal.c_str();
       
        // Передаю строку в функцию
        std::string temp = catal + EmailStrP;
    
    std::string str = temp;
    TCHAR *param = new TCHAR[str.size() + 1];
    param[str.size()] = 0;
    std::copy(str.begin(), str.end(), param);
    
    LPTSTR cmdArgs = param;
 
    printf(runExePath);
    printf("\n");
 
    // Start the child process. 
    if (!CreateProcess(
                runExePath,   // No module name (use command line)
        cmdArgs,        // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        FALSE,         // Set handle inheritance to FALSE
        0,                // No creation flags
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &si,            // Pointer to STARTUPINFO structure
        &pi)           // Pointer to PROCESS_INFORMATION structure
        )
    {
        printf("CreateProcess failed (%d).\n", GetLastError());
        return 0;
    }
 
    // Wait until child process exits.
    WaitForSingleObject(pi.hProcess, INFINITE);
 
    // Close process and thread handles. 
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
 
    return 0;
}
 
 
 
int main()
{
 
std::string Email = "mymail@mail.com";
 
 
                        //Заполняем структуру для передачи в поток
            static MsParams_t params;
            params.EmailStr = Email;
 
                        //Запускаем поток и отпускаем его в свободное плавание
            std::thread tt = std::thread(&Potok, (void*)&params);
            tt.detach();
 
system("pause");
return 0;
}
PS ребята, подскажите пожалуйста на сколько правильно/неправильно использовать отсоединение потока от основной программы в данном случае,
будет ли поток закрыт нормально, не будет ли утечек, если дочерний процесс выглядит именно так.
Вроде бы, как мне видится, проблем нет, может быть более опытные посоветуете что-нибудь.
Вопрос не стоит в том, почему я в основном потоке не ожидаю окончания дочернего и не закрываю его через Join,
приложение которое запускается отрабатывается ОЧЕНЬ длительно, я не могу позволить себе ждать его окончания в основном потоке и тормозить работу.
Вопрос: Как в текущем скрипте из javascript передать параметр в php

Проблема следующая

1. Сначала с помощью PHP формируется список доступных баз данных - в элемент <select>
2. При выборе нужной базы пользователем срабатывает обработчик onchange который вызывает javascript процедуру.
3. далее нужно подключиться к нужной базе с помощью PHP

Но тут возникает проблема - как передать выбранную базу из javascript в PHP код.

В интернете куча информации как передать параметры во внешний скрипт, но как передать параметры в PHP код текущего скрипта не нашел.

Подскажите кто знает как это реализовать.
Ответ:
shurik_7866 пишет:
нужно выполнить сразу после функции fjs_to_php()?

В данном случае признаком того, что выполнилась эта функция будет наличие параметра "mes" в URL.
Если параметра нет, следовательно - функция в предыдущей инкарнации страницы, отображенной пользователю не выполнилась, либо это подготовка первого отображения страницы...
Вопрос: Классы, как передать параметры

Ребят всем привет, с++ начал изучать всего 5 дней назад так что извините если вопрос будет глупым или как то непонятно изложен,

суть темы, пишу небольшую програмку через визуал студио тип проэкта windows forms, так вот, допустим мне нужно передать параметр из функции в главном cpp файле в файл формы Form1.h , где нужно поменять текст на лейбле "label5" параметр у лейбла стоит публичный
C++ (QT)
1
public: System::Windows::Forms::Label^  label5;
,
в функции пишу

C++ (QT)
1
2
Form1 frm;
frm.label5->Text = "test";
но при выполнении ничего не происходит, ошибок при компиляции тоже нету, что не так ребят, подскажите пожалуйста, заранее спс))
Ответ: чтобы не запутывать я примером покажу,

эта функция в файле main.cpp
C++ (QT)
1
2
3
4
    void rasch_gl() {
Form1 frm;
frm.label5->Text = "test";
}
это часть кода Form1.h
C++ (QT)
1
2
3
4
5
6
7
8
9
10
11
12
....
public: System::Windows::Forms::Label^  label5;
...
 
            this->label5->AutoSize = true;
            this->label5->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 8.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point, 
                static_cast<System::Byte>(204)));
            this->label5->Location = System::Drawing::Point(432, 308);
            this->label5->Name = L"label5";
            this->label5->Size = System::Drawing::Size(41, 13);
            this->label5->TabIndex = 18;
            this->label5->Text = L"label5";
эта функция тоже находится в файле Form1.h, она запускает туфункцию которая находится в main.cpp

C++ (QT)
1
2
3
    public: System::Void rasch(System::Object^  sender,  System::EventArgs^ e) {
                rasch_gl();
}
Добавлено через 2 минуты
да задача абсурдна, но это просто пример, мне надо понять как запускать функции из другово места

Добавлено через 21 минуту
Вот новый проэкт сделал чтобы можно было всё показать, на прошлом просто кода много, вот тут по кнопке "button1" на лейбле должна отрисоватся надпист "test", но этого не происходит, почему?

файл maine.cpp

C++ (QT)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// maine.cpp: главный файл проекта.
 
#include "stdafx.h"
#include "Form1.h"
 
using namespace maine;
 
[STAThreadAttribute]
 
int main(array<System::String ^> ^args)
{
    // Включение визуальных эффектов Windows XP до создания каких-либо элементов управления
    Application::EnableVisualStyles();
    Application::SetCompatibleTextRenderingDefault(false); 
 
    // Создание главного окна и его запуск
    Application::Run(gcnew Form1());
    return 0;
}
 
void test() {
Form1 frm;
frm.label1->Text = "test";
 
}

а это Form1.h

C++ (QT)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#pragma once
 
void test();
namespace maine {
 
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
 
    /// <summary>
    /// Сводка для Form1
    ///
    /// Внимание! При изменении имени этого класса необходимо также изменить
    ///          свойство имени файла ресурсов ("Resource File Name") для средства компиляции управляемого ресурса,
    ///          связанного со всеми файлами с расширением .resx, от которых зависит данный класс. В противном случае,
    ///          конструкторы не смогут правильно работать с локализованными
    ///          ресурсами, сопоставленными данной форме.
    /// </summary>
    public ref class Form1 : public System::Windows::Forms::Form
    {
    public:
        Form1(void)
        {
            InitializeComponent();
            //
            //TODO: добавьте код конструктора
            //
        }
 
    protected:
        /// <summary>
        /// Освободить все используемые ресурсы.
        /// </summary>
        ~Form1()
        {
            if (components)
            {
                delete components;
            }
        }
    private: System::Windows::Forms::Button^  button1;
    protected: 
    public: System::Windows::Forms::Label^  label1;
    private: 
 
    private:
        /// <summary>
        /// Требуется переменная конструктора.
        /// </summary>
        System::ComponentModel::Container ^components;
 
#pragma region Windows Form Designer generated code
        /// <summary>
        /// Обязательный метод для поддержки конструктора - не изменяйте
        /// содержимое данного метода при помощи редактора кода.
        /// </summary>
        void InitializeComponent(void)
        {
            this->button1 = (gcnew System::Windows::Forms::Button());
            this->label1 = (gcnew System::Windows::Forms::Label());
            this->SuspendLayout();
            // 
            // button1
            // 
            this->button1->Location = System::Drawing::Point(128, 62);
            this->button1->Name = L"button1";
            this->button1->Size = System::Drawing::Size(75, 23);
            this->button1->TabIndex = 0;
            this->button1->Text = L"button1";
            this->button1->UseVisualStyleBackColor = true;
            this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
            // 
            // label1
            // 
            this->label1->AutoSize = true;
            this->label1->Location = System::Drawing::Point(148, 129);
            this->label1->Name = L"label1";
            this->label1->Size = System::Drawing::Size(35, 13);
            this->label1->TabIndex = 1;
            this->label1->Text = L"label1";
            // 
            // Form1
            // 
            this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
            this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
            this->ClientSize = System::Drawing::Size(332, 274);
            this->Controls->Add(this->label1);
            this->Controls->Add(this->button1);
            this->Name = L"Form1";
            this->Text = L"Form1";
            this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
            this->ResumeLayout(false);
            this->PerformLayout();
 
        }
#pragma endregion
    private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
             }
    private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
                 test();
             }
    };
}
Вопрос: Передать параметру другому php

Есть два php скрипта.
Первый подключается к базе данных и получает из нее некие данные.
Потом в цикле нужно отправлять эти данные в виде параметров второму php,
который по принятым параметрам генерирует и возвращает результат.

Не могу понять как передать параметры второму php, дождаться от него ответа и продолжить работу первого.

Дайте совет и если не трудно с примером
Ответ:
Разобрался.
Проблема была в том что второй php был написан не мной, там куча функций и трогать его не хотелось дабы не накосячить и потом через месяц выяснить что что то работает не так.
Но все же пришлось
Обернул основной код в функцию из которой вызываются остальные и эту функцию уже вызываю из первого php.

(Отредактировано автором: 29 Октября, 2017 - 15:19:37)

Вопрос: Передача переменной пхп в параметр функции javascript

всем добрый час ! подскажите, как передать значение переменной php в параметр функции javascript.
имеется следующий код php:

инициализация php переменной
PHP
1
2
3
4
                $theDateIs=$sqldateendofevent;
                $theDateIs.=" ";
                $theDateIs.=$sqltimeendofevent;
                echo '<br />';
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
    echo '<td>'
                                    . '<a href=zajavki/rozigriw1.php?id='. $row['id'] .'>' 
                                    .'<span class=zagolovok>' .$row['header'] .'</span>' 
                                    . '<br />'
                                    . '<span class=id>' .'ID: ' .$row['id'] . '</span>' 
                                    .'<br />' 
                                    .'<img src=' . $row['linkonphoto'] . '>'. '</a>' 
                                    .'<br />' . '<br />' 
                                    . '<span class=timer>'
 
                                    //. '<script>get_timer('.$theDateIs.')</script>';
                                    . '<script type=text/javascript>get_timer('.$theDateIs.')</script>';
                                    ?>
в самом конце вызываю функцию javascript которая у меня находиться в отдельном файле и подключена в файле php(там где вызывается).

пробовал инициализировать переменную яваскрипт с последующей подстановкой вместо php переменной. ничего не сработало.
Javascript
1
2
3
<script type="text/javascript">
    var actTime = <?php echo $theDateIs; ?>;
</script>
сама функция javascript
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
$(document).ready(function(){
    //код jQuery
    function get_timer(theDateIs){
 
        //дата от которой будет отталкиватся наш таймер.
        //var date_new = "Januar 28, 2017 13:01";
 
        //var date_new = "01/25/2017 10:00";
 
        var date_new = theDateIs;
        var date_t = new Date(date_new);
        var date = new Date();
 
        var timer = date_t - date;
 
        if(date_t > date){
            //логика таймера
            //вычисление дней.
            //узнаем сколько дней в переменной timer. сейчас там хранятся данные в виде милисекунд.
            //в одной секунде у нас 1000 милисекунд. то есть 60 * 1000 = получаем минуту. в часу у нас 60 минут, поэтому
            //умнажажаем ещё раз на 60. в дне у нас 24 часа, поэтому умножаем ещё раз на 24 часа.
            // var timer = делим на количество милисекунд содержащемся в одном дне.
            var day = parseInt(timer/(24*60*60*1000));
            if(day<10){
                day = '0' + day;
            }
 
            day = day.toString();
 
            //вычисление часов.
            var hour = parseInt(timer/(60*60*1000))%24;
            if(hour<10){
                hour = '0' + hour;
            }
 
            hour = hour.toString();
 
            //вычисляем минуты.
            var min = parseInt(timer/(60*1000))%60;
            if(min<10){
                min = '0' + min;
            }
 
            min = min.toString();
 
            //вычисляем секунды.
            var sec = parseInt(timer/(1000))%60;
            if(sec<10){
                sec = '0' + sec;
            }
 
            sec = sec.toString();
            //$("#clock").html("<span id='stop'>" + day + ":" + hour + ":" + min + ":" + sec +"</span>");
 
            //добовляю анимацию к таймеру.
            /*$("#sec1")
            .html(sec[1])
            .css({'marginTop':'-20px', 'opacity': '0'})
            .animate({'marginTop': '0px', 'opacity': '1'}); // к примеру если у нас 50 секунд, то мы обращаемся к 0 а не к 5. соответсвенно 0 будет меняться.
            */
 
 
 
 
 
            if(day[1] == 9 && hour[0] == 2 && hour[1] == 3 && min[0] == 5 && min[1] == 9 && sec[0] == 5 &&
             sec[1] == 9){
                animation($("#day0"), day[0]);
            }else{
                $("#day0").html(day[0]);
            }
 
            if(hour[0] == 2 && hour[1] == 3 & min[0] == 5 && min[1] == 9 && sec[0] == 5 && sec[1] == 9){
                animation($("#day1"), day[1]);
            }else{
                $("#day1").html(day[1]);
            }
 
 
            ///////////////////ЧАСЫ//////////////////////
            if(hour[1] == 3 & min[0] == 5 && min[1] == 9 && sec[0] == 5 && sec[1] == 9){
                animation($("#hour0"), hour[0]);
            }else{
                $("#hour0").html(hour[0]);
            }
 
            if(min[0] == 5 && min[1] == 9 && sec[0] == 5 && sec[1] == 9){
                animation($("#hour1"), hour[1]);
            }else{
                $("#hour1").html(hour[1]);
            }
 
 
            ///////////////////МИНУТЫ//////////////////////
            if(min[1] == 9 && sec[0] == 5 && sec[1] == 9){
                animation($("#min0"), min[0])
            }else{
                $("#min0").html(min[0]);
            }
            if(sec[0] == 5 && sec[1] == 9){
                animation($("#min1"), min[1]);
            }else{
                $("#min1").html(min[1]);
            }
            ///////////////////СЕКУНДЫ//////////////////////
            if(sec[1] == 9){
            //единицы секунд.
            animation($("#sec0"), sec[0]);
        }else{
            $("#sec0").html(sec[0]);
        }
            //единицы секунд.
            animation($("#sec1"), sec[1]);
 
            setTimeout(get_timer, 1000);
        }
        else{
            $("#clock").html("<span id='stop'>Отсчет закончен!</span>")
        }
 
    }
 
    function animation(vibor, param){
 
            vibor.html(param)
            .css({'marginTop':'-20px', 'opacity': '0'})
            .animate({'marginTop': '0px', 'opacity': '1'}); // к примеру если у нас 50 секунд, то мы обращаемся к 0 а не к 5. соответсвенно 0 будет меняться.
        }   //метод animate позволяет делать нам пользовательские анимации на основе правил css
 
    get_timer();
});
Ответ:
Сообщение от eluzor
так и не передается параметр в функцию.
С чего ты взял? У тебя ведь есть вызовы и без параметров.
Javascript
1
2
3
4
5
6
7
8
9
    function animation(vibor, param){
 
            vibor.html(param)
            .css({'marginTop':'-20px', 'opacity': '0'})
            .animate({'marginTop': '0px', 'opacity': '1'}); // к примеру если у нас 50 секунд, то мы обращаемся к 0 а не к 5. соответсвенно 0 будет меняться.
        }   //метод animate позволяет делать нам пользовательские анимации на основе правил css
 
    // !!!Без параметров!!!
    get_timer();
Вопрос: Параметр функции - функция-член структуры

Потребовалось сделать вот такой фокус:
Код C++
1
2
3
4
5
6
7
8
9
10
11
12
struct ANYSTRUCT
{
  DWORD WINAPI Fu (void)
  {
    //.....
  };
 
  bool Fuu(...)
  {
    TrdHdl = CreateThread(NULL, 0, Fu, NULL, 0, &TrdId);
  }
}
Как правильно указать ссылку на Fu в параметрах функции CreateThread? Если такой фокус возможен в принципе.

Ну и тут же по теме... Все эти дела зашиты в либу. Прямого доступа к структурам из вне либы нет - только через "интерфейсные" функции, которые уже работают со структурами и их методами. Будут ли проблемы при работе с либой из-под Delphi например?

Среда: MSVC 6.0
Ответ:
Сообщение от Silvermatic
вот такой фокус
В чем тут фокус?
В CreateThread надо передавать или свободную функцию или статическую функцию-член.
В твоем случае Fu является нестатической функцией-членом, т.о. передать ее явно не получится, нужно делать обертку.
Вопрос: Динамически загружаемая библиотека Dll и класс TObject, как входной параметр функции

Имеется класс наследник от TObject, отвечающий за запись логов программы, и динамически загружаемая Dll. Чтобы логи писались не только из самой программы, но и в той части, которая реализована в Dll, пробую передавать ей класс в качестве входного параметра функции. Отрабатывает нормально, но при выгрузке библиотеки начинают сыпаться сообщения об утечках памяти, нарушениях доступа и прочая гадость. Если удалить переданный класс в теле самой библиотечной функции, ошибок не возникает, но мне-то этого совсем не нужно - после выгрузки библиотеки приложение продолжает работать и использовать класс.
unit Unit1;

interface
//...

type
  TLogWriter = class(TObject)
     //...
  end;

  TMyFunction = function(ALogWriter: TLogWriter): boolean;

var
  DllHandle: cardinal;
  DllPath: string;
  LogWriter: TLogWriter;
  MyFunction: TMyFunction;

procedure LoadLibrary_;
begin
  if DllHandle = 0 then begin
    LogWriter.Write('Загрузка библиотеки');
    DllHandle := LoadLibrary(PChar(DllPath));
  end;
  @MyFunction := GetProcAddress(DllHandle, 'MyFunction');
end;

procedure UnLoadLibrary_;
begin
  if DllHandle > 0 then begin
    LogWriter.Write('Выгрузка библиотеки');
    FreeLibrary(DllHandle); 
    DllHandle := 0;
  end;
end;

procedure MyProc;
var b: boolean;
begin
  LogWriter := TLogWriter.Create;
  DllPath := 'c:\MyDll.dll';
  DllHandle := 0;
  LoadLibrary_;
  b := MyFunction(LogWriter);
  UnloadLibrary;  //Здесь и начинаются проблемы
  FreeAndNil(LogWriter);
end;

end.


и сама dll
library MyDll;
uses Unit1;

function MyFunction(ALogWriter: TLogWriter); export;
begin
  ALogWriter.Write('Библиотечная функция');
end;

exports
  MyFunction name 'MyFunction';

begin

end.


В случае с TLogWriter вышел из положения созданием отдельного экземпляра класса внутри библиотеки - а это уже как минимум повторное задание полей, таких как, например, имя выходного файла. А в будущем хотелось бы использовать совместно и другие более сложные классы с большим количеством задаваемых извне полей.
Есть ли более красивые решения?
Ответ: A-MaR, проблема не столько в объекте, сколько в строках, которые ты в него передаёшь. В DLL ты пишешь ALogWriter.Write('Библиотечная функция'); Строка, передаваемая в Write, выделяется и управляется DLL (не важно, статическая она или динамическая). Как только DLL выгрузили - всё, этой строки больше нет. Все попытки обратится к ней приведут к AV. Кроме того, если DLL не выгружать, а удалить TLogWriter, то он отпустит строку и попытается её удалить. Запрос на удаление он отправит менеджеру памяти в EXE, а вовсе не менеджеру памяти в DLL - потому что про какой-то другой менеджер памяти TLogWriter вообще не в курсе. Соответственно, получаем Invalid Pointer Operation или Access Violation.

По вышеприведённым ссылкам - подробнее.

Чтобы сделать правильно - заменяем TLogWriter на ILogWriter, String - на WideString. Или DLL на BPL.