1

I am looking to return an array of all current running process ID's from a function using C++.

I am enumerating the list with the following function:

DWORD* xEnumProcs(){
    PROCESSENTRY32 pe32;
    HANDLE snapshot = NULL;
    DWORD pid[1024];
    DWORD* pointer;
    pointer = pid;
    int I = 0;

    snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (snapshot != INVALID_HANDLE_VALUE) {
        pe32.dwSize = sizeof(PROCESSENTRY32);
        if (Process32First(snapshot, &pe32)) {
            do {
                pid[I] = pe32.th32ProcessID;
                I++;
            } while (Process32Next(snapshot, &pe32));
        }

        CloseHandle(snapshot);

    }

    return pointer;

}

I am unsure if this is done properly. I am trying to utilize this array inside of another function like so:

void HandleProcs(){
    DWORD* xNewProcs = xEnumProcs;
}

And this is the error I am receiving on the one line in the body of the last function:

'initializing' : cannot convert from 'DWORD *(__cdecl *)(void)' to 'DWORD *'
1>          There is no context in which this conversion is possible
Josh Line
  • 625
  • 3
  • 13
  • 27
  • 1
    Use `std::vector` and return that. Also, you're not calling the function. – chris Dec 21 '12 at 05:47
  • 1
    There are other problems, but the compiler error is that you are trying to assing a function pointer to a `DWORD*`. Use the `()` operator. `DWORD* xNewProcs = xEnumProcs();` – imreal Dec 21 '12 at 05:48
  • @chris Wow, forgot the "()"... Post that as an asnwer, Lol. I will choose it. – Josh Line Dec 21 '12 at 05:49
  • 2
    Are you learning C++ (coming from VB I'm guessing?) at the same time you're learning the Windows API? Because the result you're getting is a generic C++ problem, not directly related to the Windows API. – user541686 Dec 21 '12 at 05:49
  • 1
    @Mehrdad Yes, I am learning C++. I am actually coming from delphi. I learned VB quite some time ago, yet never really messed around with C#. – Josh Line Dec 21 '12 at 05:51
  • 1
    @JoshLine, The best advice I can give is to go through the topics of C++ and learn the language before doing the winapi with it. It's a deathtrap *with* knowing the language, let alone without. – chris Dec 21 '12 at 05:54
  • @chris Thanks for the tips. I actually ordered some books from Amazon on C & C++ hoping to get the basics down solid in order to build a nice foundation. We have not yet gotten to C or C++ in school yet, but i am eager to learn, lol. – Josh Line Dec 21 '12 at 05:57
  • @JoshLine, If it helps, take a look at this: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – chris Dec 21 '12 at 06:03
  • 1
    JoshLine: @chris is completely right. A piece of advice: *Either* learn C++ *well* first, *or* learn C well. I would recommend C, because the Windows API interfaces well with it. Do *not* attempt to get the "best of both worlds" simultaneously because, frankly, attempting to write C-like programs in C++ (which is inevitably what will happen if you try to learn both at the same time) is only going to backfire. Learn C++ after you're comfortable with C and the Windows API (be able to write window procedures in pure C before learning C++). (This is from my first-hand experience.) Best of luck. – user541686 Dec 21 '12 at 06:09
  • 1
    I definitely agree. I only ever did C++ in school, not C, but I see the code abominations that result of that pop up every day on this site. It's also a bit annoying to write winapi code with C++ practices as well, and that's where really knowing C++'s nooks and crannies can help. It's something that you get better at as you get more experience doing individual tasks using the API. – chris Dec 21 '12 at 06:11
  • 1
    Just as an example: two of the very first problems you encounter when attempting to write robust programs are (1) explicit memory management, and (2) exception handling. (1) is already bad enough in C (it's so hard it'll make you want to use stack-based or static buffers for everything, even when you start coding in C++, leading to all kinds of headaches), but at least C code doesn't need to really worry about exceptions. But if you try to combine it with C++ then worrying about exception safety with manual memory management will make things 10x harder than they would be individually. – user541686 Dec 21 '12 at 06:15
  • 1
    @Mehrdad, I've wished so many times that the core API be rewritten for C++ (not 3rd party wrappers). That would make my day. I guess that's what C# is for, and I really like it for the reason that it's a lot more like C++ than the API meant for C. – chris Dec 21 '12 at 06:17
  • @chris: Have you seen [WTL (an extension of ATL)](https://sourceforge.net/projects/wtl/)? It's by no means complete (or even close!), but it goes a long way toward making things C++-friendly. – user541686 Dec 21 '12 at 06:18
  • @Mehrdad, Yeah, some of those are really good. I know I'll always have an ambition to make my own. I must say it does get better and better each time I redo things. It's a good winapi and C++ experience. Sometimes you have to live with ugly code interfacing the API in order to get clean, idiomatic code when using the wrapper. – chris Dec 21 '12 at 06:22
  • 1
    @JoshLine, Oh, and the biggest tip I can give for learning the language (maybe not as much the API) is to stick around here once you've gone through a book and monitor new questions in the tag of the language and pick out the ones that pique your interest. If I had never done that, I would still be using multitudes of bad practices and have no idea about a lot of idiomatic styles of C++. The comments and answers on the site drill those in, so by hanging around and being active - at least observing - you will learn most of them fairly quickly. I still usually learn something new every day here. – chris Dec 21 '12 at 06:28
  • 2
    Yup, definitely learn the "idioms" (RAII, at the very least) if you go the C++ route. At first the "idioms" seem just plain silly (they look like they're just training wheels you can ignore)... but once you learn why they were invented, you'll appreciate them and realize why they are *necessary* to writing good code. – user541686 Dec 21 '12 at 06:39

1 Answers1

2

I think you already got your answer, but for the sake of learning, compare the C version here:

#include <stdio.h>  // printf
#include <Windows.h>
#include <Tlhelp32.h>

DWORD *EnumProcs(size_t *n)
{
    DWORD *pids = NULL;
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    *n = 0;
    if (snapshot != INVALID_HANDLE_VALUE)
    {
        PROCESSENTRY32 pe32 = { sizeof(pe32) };
        if (Process32First(snapshot, &pe32))
        {
            do { ++*n; } while (Process32Next(snapshot, &pe32));
            pids = calloc(*n, sizeof(pe32.th32ProcessID));
            *n = 0;
            Process32First(snapshot, &pe32);  // Maybe check return value
            do { pids[(*n)++] = pe32.th32ProcessID; }
            while (Process32Next(snapshot, &pe32));
        }
        CloseHandle(snapshot);
    }
    return pids;
}
int main()
{
    size_t i, n;
    DWORD *pids = EnumProcs(&n);
    for (i = 0; i < n; i++)
    { printf("%u\n", pids[i]); }
    free(pids);
}

with the C++ version:

#include <iostream>  // std::cout
#include <vector>  // std::vector, like List<T> in C# (or ArrayList<T> in Java)
#include <Windows.h>
#include <Tlhelp32.h>

std::vector<DWORD> EnumProcs()
{
    std::vector<DWORD> pids;
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (snapshot != INVALID_HANDLE_VALUE)
    {
        PROCESSENTRY32 pe32 = { sizeof(PROCESSENTRY32) };
        if (Process32First(snapshot, &pe32))
        {
            do
            {
                pids.push_back(pe32.th32ProcessID);
            } while (Process32Next(snapshot, &pe32));
        }
        CloseHandle(snapshot);
    }
    return pids;
}
int main()
{
    std::vector<DWORD> pids = EnumProcs();
    for (size_t i = 0; i < pids.size(); i++)
    { std::cout << pids[i] << std::endl; }
}

Notice how the C++ version is completely different -- and doesn't use pointers.

Try to learn one of the two languages well before moving on to the other one.

user541686
  • 205,094
  • 128
  • 528
  • 886