MFC C++ で libssh ライブラリ、具体的には SFTP ラッパーを使用しています。スレッドを使用していないときにコードが機能していますが、AfxBeginThread を使用してユーザー アクションを続行できるようにしたいと考えています。
スレッドを使用しているかどうかに関係なく、まったく同じファイル名とターゲット保存パスを渡していることを確認しました-保存するファイルと保存先をBeginDownload()で直接ハードコーディングすることでこれをテストしました。
スレッド内でダウンロードを実行するために、libssh の SFTP ラッパーを使用する必要がある特定の方法はありますか? ユーザーが ssh オブジェクトの同じインスタンスから同時に複数のファイルをダウンロードできるようにし、ファイルをダウンロードする必要があるたびに新しいスレッドを起動できるようにしたいと考えています。
これが実際のダウンロードに使用しているものです。m_sftp_session は、ログイン時に作成された私の sftp_session オブジェクトです。
bool CSFtpManager::BeginDownload(CString filename, CString savefilename)
{
sftp_dir dir = sftp_opendir(m_sftp_session, "../../../directory");
sftp_attributes attrs = sftp_readdir(m_sftp_session, dir);
int access_type = O_RDONLY;
sftp_file file;
file = sftp_open(m_sftp_session, "../../../directory/myfile.zip", access_type, 0);
const char* x2 = ssh_get_error(m_ssh_session);
if(file == NULL)
{
int a;
}
int nbytes;
char buffer[1024];
FILE * pFile;
pFile = fopen(CStringA(savefilename), "wb");
nbytes = sftp_read(file, buffer, sizeof(buffer)); //this is crashing inside a thread
while(nbytes > 0)
{
fwrite(buffer, sizeof(char), sizeof(buffer), pFile);
nbytes = sftp_read(file, buffer, sizeof(buffer));
}
fclose(pFile);
sftp_close(file);
return true;
}
これは、私の libssh オブジェクトが後で使用するためにメンバー変数に設定されている私のログイン方法です。含まれているのは、BeginDownload を呼び出すコメント行です。スレッドの外で呼び出す (つまり、ログイン ボタンをクリックする) ことはできます。
bool CSFtpManager::login()
{
int verbosity = SSH_LOG_PROTOCOL;
m_ssh_session = ssh_new();
ssh_options_set(m_ssh_session, SSH_OPTIONS_HOST, "ftp3 host..");
//setting username and password...
ssh_options_set(m_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
ssh_options_set(m_ssh_session, SSH_OPTIONS_PORT, &m_iPort);
int x = ssh_connect(m_ssh_session);
const char* x2 = ssh_get_error(m_ssh_session);
if(rc != SSH_AUTH_SUCCESS)
{
return false;
}
m_sftp_session;
m_sftp_session = sftp_new(m_ssh_session);
//Calling BeginDownload here does work
//BeginDownload(L"file.txt", L"T:\\file.txt");
... }
これは、スレッドを介してまったく同じ関数を呼び出すために使用しているものです
CWinThread* pThread2 = AfxBeginThread(BeginSFTPDownload, bundle);
そして、上記を介して実行されるメソッド:
UINT CMainFrame::BeginSFTPDownload( LPVOID pParam)
{
pSft->BeginDownload(L"test.txt", L"T:\\test.txt");
return 0;
}