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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> как правильно описать класс для использования? 
V
    Опции темы
Ksen
Дата 27.4.2011, 21:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Здравствуйте!
Помогите, пожалуйста, описать класс для  того чтобы его функции можно было использовать в другом файле...

FuncServ.h"

Код

#include <windows.h>
#include <windowsx.h>
#include "stdafx.h"

class FuncServ
{
public:
    LPBYTE ReceiveService();
}    


FuncServ.cpp

Код

#include "stdafx.h"
#include "FuncServ.h"

LPBYTE FuncServ::ReceiveService()
    {

        SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
        ENUM_SERVICE_STATUS_PROCESS Services[100] = { 0 };
        DWORD dwBytesNeeded = 0;
        DWORD dwServicesReturned = 0;
        DWORD dwResumeHandle = 0;
        BOOL bSuccess = FALSE;
        DWORD dwServicesCount = 0;

        EnumServicesStatusEx(hSCManager, SC_ENUM_PROCESS_INFO,
                   SERVICE_WIN32, SERVICE_STATE_ALL, LPBYTE(Services),
                   sizeof(Services), &dwBytesNeeded, &dwServicesReturned,
                   &dwResumeHandle, NULL);


        CloseServiceHandle(hSCManager);
        return LPBYTE(Services);
    }


Service.cpp

Код

// Service.cpp: главный файл проекта.

#include <windows.h>
#include <windowsx.h>
#include "stdafx.h"
#include "Form1.h"
#include "FuncServ.h"

using namespace Service;

[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
    // Включение визуальных эффектов Windows XP до создания каких-либо элементов управления
    Application::EnableVisualStyles();
    Application::SetCompatibleTextRenderingDefault(false); 

    // Создание главного окна и его запуск
    Application::Run(gcnew Form1());

    FuncServ RS;
    LPBYTE* prs = RS.ReceiveService();

    return 0;


при построении вываливается куча ошибок линковки заголовочных файлов...
помогите привязать класс....пожалуйста
PM MAIL ICQ   Вверх
Ksen
Дата 27.4.2011, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



по разбиралась немного((( поправила некоторые неточности...в принципе почти всё осталось так же...но теперь мне выдаёт компилятор вот такие ошибки ужасные....

1>.\Service.cpp(6) : error C2471: невозможно обновить базу данных программы 'c:\documents and settings\admin\мои документы\visual studio 2008\projects\service\service\debug\vc90.pdb'
1>.\Service.cpp(27) : fatal error C1903: не удается восстановить после предыдущих ошибок; остановка компиляции
1>FuncServ.cpp
1>.\FuncServ.cpp(3) : error C2471: невозможно обновить базу данных программы 'c:\documents and settings\admin\мои документы\visual studio 2008\projects\service\service\debug\vc90.pdb'
1>.\FuncServ.cpp(40) : warning C4172: возвращение адреса локальной или временной переменной
1>.\FuncServ.cpp(43) : fatal error C1903: не удается восстановить после предыдущих ошибок; остановка компиляции

кто-нибудь знает что с этим делать? у меня такое чувства, что все проблемы из-за типа данных LPBYTE...компилятор видимо не может его передать корректно...
кто-нибудь может подсказать...как тут быть, как лучше возвращать значение в функции?
PM MAIL ICQ   Вверх
borisbn
Дата 28.4.2011, 00:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



Цитата(Ksen @  27.4.2011,  23:02 Найти цитируемый пост)
но теперь мне выдаёт компилятор вот такие ошибки ужасные....
1>.\Service.cpp(6) : error C2471: невозможно обновить базу данных программы 'c:\documents and settings\admin\мои документы\visual studio 2008\projects\service\service\debug\vc90.pdb'
1>.\Service.cpp(27) : fatal error C1903: не удается восстановить после предыдущих ошибок; остановка компиляции1>FuncServ.cpp
1>.\FuncServ.cpp(3) : error C2471: невозможно обновить базу данных программы 'c:\documents and settings\admin\мои документы\visual studio 2008\projects\service\service\debug\vc90.pdb'


с этим попроще: удали все файлы из папки Debug

Цитата(Ksen @  27.4.2011,  23:02 Найти цитируемый пост)
1>.\FuncServ.cpp(40) : warning C4172: возвращение адреса локальной или временной переменной

с этим посложнее. смотри - ты создаёшь переменную Services на стеке
Цитата(Ksen @  27.4.2011,  21:20 Найти цитируемый пост)
 ENUM_SERVICE_STATUS_PROCESS Services[100] = { 0 };

а затем возвращаешь адрес этой переменной (т.е. просто указатель на стек). 
Цитата(Ksen @  27.4.2011,  21:20 Найти цитируемый пост)
 return LPBYTE(Services);

А что происходит со стеком, когда функция завершается ? Правильно, он возвращается в первоначальное состояние, т.е. состояние до вызова функции. Другими словами - разрушается.
Возвращать указатель можно только на статическую память или на динамически выделенную память в heap'е.

и ещё. в чём смысл класса FuncServ ? Почему просто не объявить функцию
Код

#include <windows.h>
#include <windowsx.h>
#include "stdafx.h"

    LPBYTE ReceiveService();

не определить её в cpp-шнике
Код

#include "stdafx.h"
#include "FuncServ.h"

LPBYTE ReceiveService()
{

        SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
        ENUM_SERVICE_STATUS_PROCESS Services[100] = { 0 }; // <------------------ это неправильно !!!
        DWORD dwBytesNeeded = 0;
        DWORD dwServicesReturned = 0;
        DWORD dwResumeHandle = 0;
        BOOL bSuccess = FALSE;
        DWORD dwServicesCount = 0;

        EnumServicesStatusEx(hSCManager, SC_ENUM_PROCESS_INFO,
                   SERVICE_WIN32, SERVICE_STATE_ALL, LPBYTE(Services),
                   sizeof(Services), &dwBytesNeeded, &dwServicesReturned,
                   &dwResumeHandle, NULL);


        CloseServiceHandle(hSCManager);
        return LPBYTE(Services); // <------------------ вернее вот это
}

и просто её не вызвать
Код

#include "FuncServ.h"
...
LPBYTE* prs = ReceiveService();



--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Ksen
Дата 28.4.2011, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



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

FuncServ.h
Код

#include <windows.h>
#include <windowsx.h>
#include "stdafx.h"
//#include "FuncServ.h"

typedef struct
{
    LPWSTR DisplayName, ServiceName;
} Serv;

class FuncServ
{
public:
    Serv ReceiveService();
};
    


FuncServ.cpp
Код

#include <windows.h>
#include "stdafx.h"
#include "FuncServ.h"

Serv FuncServ::ReceiveService()
    {

        SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
        ENUM_SERVICE_STATUS_PROCESS Services[100] = { 0 };
        DWORD dwBytesNeeded = 0;
        DWORD dwServicesReturned = 0;
        DWORD dwResumeHandle = 0;
        BOOL bSuccess = FALSE;
        DWORD dwServicesCount = 0;

        EnumServicesStatusEx(hSCManager, SC_ENUM_PROCESS_INFO,
                SERVICE_WIN32, SERVICE_STATE_ALL, LPBYTE(Services),
               sizeof(Services), &dwBytesNeeded, &dwServicesReturned,
               &dwResumeHandle, NULL);

        Serv s[sizeof(Services)];
        Serv *ps = s;
        for (DWORD i = 0; i < dwServicesReturned; i++)
        {
            s[i].DisplayName = Services[i].lpDisplayName;
            s[i].ServiceName = Services[i].lpServiceName;
        }

        CloseServiceHandle(hSCManager);
        return *ps;
    }


и потом делаю в main вот так:
FuncServ RS;
Serv ps = RS.ReceiveService();

у меня теперь вываливается куча ошибок с которыми я не знаю что делать(((( Помогите разобраться...
1>FuncServ.obj : error LNK2028: ссылка на неразрешенную лексему (0A00000A) "extern "C" int __stdcall CloseServiceHandle(struct SC_HANDLE__ *)" (?CloseServiceHandle@@$$J14YGHPAUSC_HANDLE__@@@Z) в функции "public: struct Serv __clrcall FuncServ::ReceiveService(void)" (?ReceiveService@FuncServ@@$$FQAM?AUServ@@XZ)
1>FuncServ.obj : error LNK2028: ссылка на неразрешенную лексему (0A00000B) "extern "C" int __stdcall EnumServicesStatusExW(struct SC_HANDLE__ *,enum _SC_ENUM_TYPE,unsigned long,unsigned long,unsigned char *,unsigned long,unsigned long *,unsigned long *,unsigned long *,wchar_t const *)" (?EnumServicesStatusExW@@$$J240YGHPAUSC_HANDLE__@@W4_SC_ENUM_TYPE@@KKPAEKPAK33PB_W@Z) в функции "public: struct Serv __clrcall FuncServ::ReceiveService(void)" (?ReceiveService@FuncServ@@$$FQAM?AUServ@@XZ)
1>FuncServ.obj : error LNK2028: ссылка на неразрешенную лексему (0A00000C) "extern "C" struct SC_HANDLE__ * __stdcall OpenSCManagerW(wchar_t const *,wchar_t const *,unsigned long)" (?OpenSCManagerW@@$$J212YGPAUSC_HANDLE__@@PB_W0K@Z) в функции "public: struct Serv __clrcall FuncServ::ReceiveService(void)" (?ReceiveService@FuncServ@@$$FQAM?AUServ@@XZ)
1>FuncServ.obj : error LNK2019: ссылка на неразрешенный внешний символ "extern "C" int __stdcall CloseServiceHandle(struct SC_HANDLE__ *)" (?CloseServiceHandle@@$$J14YGHPAUSC_HANDLE__@@@Z) в функции "public: struct Serv __clrcall FuncServ::ReceiveService(void)" (?ReceiveService@FuncServ@@$$FQAM?AUServ@@XZ)
1>FuncServ.obj : error LNK2019: ссылка на неразрешенный внешний символ "extern "C" int __stdcall EnumServicesStatusExW(struct SC_HANDLE__ *,enum _SC_ENUM_TYPE,unsigned long,unsigned long,unsigned char *,unsigned long,unsigned long *,unsigned long *,unsigned long *,wchar_t const *)" (?EnumServicesStatusExW@@$$J240YGHPAUSC_HANDLE__@@W4_SC_ENUM_TYPE@@KKPAEKPAK33PB_W@Z) в функции "public: struct Serv __clrcall FuncServ::ReceiveService(void)" (?ReceiveService@FuncServ@@$$FQAM?AUServ@@XZ)
1>FuncServ.obj : error LNK2019: ссылка на неразрешенный внешний символ "extern "C" struct SC_HANDLE__ * __stdcall OpenSCManagerW(wchar_t const *,wchar_t const *,unsigned long)" (?OpenSCManagerW@@$$J212YGPAUSC_HANDLE__@@PB_W0K@Z) в функции "public: struct Serv __clrcall FuncServ::ReceiveService(void)" (?ReceiveService@FuncServ@@$$FQAM?AUServ@@XZ)
1>C:\Documents and Settings\Admin\Мои документы\Visual Studio 2008\Projects\Service\Debug\Service.exe : fatal error LNK1120: 6 неразрешенных внешних элементов
PM MAIL ICQ   Вверх
Ksen
Дата 28.4.2011, 19:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



оказывается надо было добавить 
#pragma comment(lib, "Advapi32.lib")
PM MAIL ICQ   Вверх
borisbn
Дата 28.4.2011, 23:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



Цитата(Ksen @  28.4.2011,  17:27 Найти цитируемый пост)
 
Serv s[sizeof(Services)];
Serv *ps = s;
...
return *ps;


Ты всё-таки упорно продолжаешь возвращать указатель на структуру (вернее на массив структур), созданную на стеке. Я уже объяснял тебе, что это приведёт к обращению к несуществующей памяти.

Ок, смотри, как должна выглядеть такая функция

Код

#include <windows.h>
#include <string>
#include <vector>
#include "stdafx.h"
#include "FuncServ.h"

typedef std::vector< std::wstring > StringVector;

void ReceiveService( StringVector & displayNames, StringVector & serviceNames )
{

        SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
        ENUM_SERVICE_STATUS_PROCESS Services[100] = { 0 };
        DWORD dwBytesNeeded = 0;
        DWORD dwServicesReturned = 0;
        DWORD dwResumeHandle = 0;
        BOOL bSuccess = FALSE;
        DWORD dwServicesCount = 0;

        EnumServicesStatusEx(hSCManager, SC_ENUM_PROCESS_INFO,
                SERVICE_WIN32, SERVICE_STATE_ALL, LPBYTE(Services),
               sizeof(Services), &dwBytesNeeded, &dwServicesReturned,
               &dwResumeHandle, NULL);

        for (DWORD i = 0; i < dwServicesReturned; i++)
        {
            displayNames.push_back( std::wstring( Services[i].lpDisplayName ) );
            serviceNames.push_back( std::wstring( Services[i].lpServiceName ) );
        }

        CloseServiceHandle(hSCManager);
}

и вызов
Код

StringVector displayNames;
StringVector serviceNames;
ReceiveService( displayNames, serviceNames );
int count = displayNames.size();
for ( int i = 0; i < count; i++ )
{
    std::wstring displayName = displayNames.at( i ); // displayName - i-я строка с displayName
    std::wstring serviceName = serviceNames.at( i ); // serviceName - i-я строка с serviceName
}


правильно ли она работает в плане доставания этих имён - не знаю (не смотрел описание), но в плане возврата списка строк - должно быть правильно.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

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

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

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

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


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

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


 




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


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

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