views:

132

answers:

2

Trying to wrap this short example in C++. (and its been a while since I did this).

int main(int argc, char* argv[])
{       
    //Objects
    CFtpConnection* pConnect = NULL; //A pointer to a CFtpConnection object
    ftpClient UploadExe; //ftpClient object


    pConnect = UploadExe.Connect();    
    UploadExe.GetFiles(pConnect);

system("PAUSE");
    return 0;
}

.h -

class ftpClient
{
    public:    

    ftpClient();        
    CFtpConnection* Connect();
    void GetFiles(CFtpConnection* pConnect);    

};

.cpp -

//constructor
ftpClient::ftpClient()
{

}

CFtpConnection* ftpClient::Connect()
{
    // create a session object to initialize WININET library
    // Default parameters mean the access method in the registry
    // (that is, set by the "Internet" icon in the Control Panel)
    // will be used.

    CInternetSession sess(_T("FTP"));

    CFtpConnection* pConnect = NULL;

    try
    {
        // Request a connection to ftp.microsoft.com. Default
        // parameters mean that we'll try with username = ANONYMOUS
        // and password set to the machine name @ domain name
        pConnect = sess.GetFtpConnection("localhost", "sysadmin", "ftp", 21, FALSE );

    }
    catch (CInternetException* pEx)
    {
        TCHAR sz[1024];
        pEx->GetErrorMessage(sz, 1024);
        printf("ERROR!  %s\n", sz);
        pEx->Delete();
     }

    // if the connection is open, close it  MOVE INTO CLOSE FUNCTION
   // if (pConnect != NULL) 
   // {
   //     pConnect->Close();
   //     delete pConnect;
   // }


    return pConnect;

}

void ftpClient::GetFiles(CFtpConnection* pConnect)
{
        // use a file find object to enumerate files
        CFtpFileFind finder(pConnect);


if (pConnect != NULL) 
{
   printf("ftpClient::GetFiles - pConnect NOT NULL");
}


     // start looping
        BOOL bWorking = finder.FindFile("*"); //<---ASSERT ERROR

      //  while (bWorking)
      //  {
     //       bWorking = finder.FindNextFile();
     //       printf("%s\n", (LPCTSTR) finder.GetFileURL());
     //   }


}

So basically separated the connection and file manipulation into 2 functions. The findFile() function is throwing the assert. (Stepping into the findFile() and it is specifically at the first ASSERT_VALID(m_pConnection) in inet.cpp. )

How does the way I am passing the arround CFtpConnection* pConnect look?

EDIT - Looks like CObject vfptr is overwritten (0X00000000) in the GetFiles() function.

Any help is appreciated. Thanks.

+1  A: 

ANSWER:

This session object must be allocated in the Connection function, with a pointer
declared as a member function of the class. When creating the object within the function,
"CInternetSession sess(_T("MyProgram/1.0"));" the object/session will be terminated when the function exits, being thrown off the stack. When that happens, we can't use the pConnect pointer in other functions.

There is a hierarchy to WinInet objects, with session being the top. If session is gone nothing else can be used. Thus, we must use new to allocate the object in memory so that it sustains after this function exits.

Tommy
+1  A: 

I don't think there is any real value in having the ftpClient class return the CFTPConnection object out of Connect (unless i'm missing something that you intend?) - it should just have that as a Member variable, and GetFiles could use that member directly (Likewise you'd add the CInternetSession as a member of the class and avoid the problem you describe above when it goes out of scope.)

In that manner the ftpClient manages the lifetime of the CFTPConnection and can destroy it in its destructor.

Ruddy
Changed the CFTPConnection object as a Member variable.
Tommy