C ++ - 数组指针作为函数参数,填充数组并从UI线程访问它

时间:2010-12-10 16:15:30

标签: c++ arrays pointers parameters

我没有用C ++编写太多代码,因为HS和我很生锈/没有经验。

我想查找计算机上的所有正在运行的进程,并使用其名称填充列表框控件。我创建了一个C ++ win form应用程序,在表单加载事件处理程序中,我有以下代码 -

private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
             // Proccess monitor class
             ProcessMonitor oMonitor;
             // Array pointer
             string* processes = NULL;
             // Call method in process monitor class called get processes, 
             // pass int array pointer as parameter
             oMonitor.GetProcesses(processes);
             // Iterate through array
             for (int i = 0; i < sizeof(processes) / sizeof(string); i++)
             {

             }
         }
};

希望代码/评论足够直接。

这就是我的GetProcesses方法 -

void ProcessMonitor::GetProcesses(string processNames[])
{
    // Array to hold process ID's
    DWORD aProcesses[1024], cbNeeded, cProcesses;
    // Iterator
    unsigned int i;

    // If no running processes can be detected exit function
    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return;

    // Get number of running processes
    cProcesses = cbNeeded / sizeof(DWORD);
    // Instantiate array that was passed in
    // ***NOTE*** I think this is where my problem lies,
    // as I passed in a pointer to an array, not an actual array
    processNames = new string[cProcesses];
    // Iterate through array and initialize all indicies to an empty string
    for ( int j = 0; j < sizeof(processNames) / sizeof(string); i++)
    {
        processNames[i] = "";
    }

    // Enumerate through processes and fill array with process names
    for ( i = 0; i < cProcesses; i++ )
    {
        if( aProcesses[i] != 0 )
        {
            TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");

            HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i]);

            if (NULL != hProcess )
            {
                HMODULE hMod;
                DWORD cbNeeded;

                /*Given a handle to a process, this returns all the modules running within the process.
                The first module is the executable running the process,
                and subsequent handles describe DLLs loaded into the process.*/
                if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
                {
                    //This function returns the short name for a module,
                    //typically the file name portion of the EXE or DLL
                    GetModuleBaseName( hProcess, hMod, szProcessName,
                        sizeof(szProcessName)/sizeof(TCHAR) );
                    processNames[i] = szProcessName;
                }
            }
            CloseHandle( hProcess );
        }
    }
}

我相信我的代码的问题是我没有实例化我的数组,直到它已经在GetProcesses方法中。当代码返回到调用窗口窗体时,指向我传入的数组的指针为空。我猜我要做的是在将数组作为参数传递给函数之前实例化数组。问题是我不知道数组需要的大小,直到我确定机器上正在运行的进程数。

我意识到我可以将GetProcesses函数分解为两个调用,一个用于确定数组所需的大小,另一个用于填充数组。问题是如果你检查条件 -

if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return;

该条件下的调用将使用所有进程ID填充aProcesses数组。我不想两次这样做。

对于我做错的事,有没有人有任何想法?

如果我真的离开这里我会道歉,我暂时没有用C ++编写任何东西。

2 个答案:

答案 0 :(得分:1)

ProcessMonitor :: GetProcesses(string processNames [])

我认为你需要将指针传递给函数

不太确定语法

ProcessMonitor :: GetProcesses(string * processNames [])

,因为 processNames = new string [cProcesses]; 将在本地分配它,它将不会返回...

(哦,是的,我认为托管C ++是世界上最糟糕的。但这是我的看法。)

答案 1 :(得分:0)

字符串和向量是您在C ++中的朋友:)

#include <string>
#include <vector>

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


StringVector ProcessMonitor::GetProcesses()
{
StringVector ret;
// Array to hold process ID's
DWORD aProcesses[1024], cbNeeded, cProcesses;
// Iterator
unsigned int i;

// If no running processes can be detected exit function
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
    return;

// Enumerate through processes and fill array with process names
for ( i = 0; i < cProcesses; i++ )
{
    if( aProcesses[i] != 0 )
    {
        TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");

        HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i]);

        if (NULL != hProcess )
        {
            HMODULE hMod;
            DWORD cbNeeded;

            /*Given a handle to a process, this returns all the modules running within the process.
            The first module is the executable running the process,
            and subsequent handles describe DLLs loaded into the process.*/
            if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
            {
                //This function returns the short name for a module,
                //typically the file name portion of the EXE or DLL
                GetModuleBaseName( hProcess, hMod, szProcessName,
                    sizeof(szProcessName)/sizeof(TCHAR) );

                // CHANGE HERE!!!
                ret.push_back(szProcessName);
            }
        }
        CloseHandle( hProcess );
    }
}
return ret; // return vector back to caller.
}    

请致电:

StringVector ret = monitor.GetProcesses();