Асинхронные события: уже определенная ошибка компоновщика [Windows Update API] - PullRequest
1 голос
/ 30 мая 2011

Хорошо, поэтому я возился с некоторыми API-интерфейсами Microsoft Windows Update и пытаюсь выполнить асинхронную загрузку. Класс класса API для ссылки обратного вызова для класса, который использует интерфейс IDownloadProgressChangedCallback Дополнительная информация об API находится здесь . То, что я сделал до сих пор, - это просто выстрел в темноте (я никогда не путался с обратными вызовами, асинхронным кодом или Microsoft API в этом отношении). У меня постоянно возникают проблемы с тем, что одни и те же методы «уже определены». Вот то, что я имею до сих пор:

Восстановить код в основном методе:

IDownloadJob *_DownloadJob = NULL;
tagVARIANT NodeValue ; \\>>PS<< HOW DO I SET THIS TO A DEFUALT VALUE?
hr = _UpdateDownloader->BeginDownload(new DownloadProgressChangedCallback  ,new DownloadCompletedCallback, NodeValue,&_DownloadJob);

DownloadProgressChange.h:

#include <Wuapi.h>
#pragma once
class DownloadProgressChangedCallback  : public IDownloadProgressChangedCallback 
{
public:
    HRESULT STDMETHODCALLTYPE Invoke( IDownloadJob *downloadJob,  IDownloadProgressChangedCallbackArgs *callbackArgs);
    HRESULT STDMETHODCALLTYPE QueryInterface(  REFIID riid,  __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject);
    ULONG STDMETHODCALLTYPE AddRef( void) ;
    ULONG STDMETHODCALLTYPE Release( void);
};

DownloadProgressChange.cpp:

#include "StdAfx.h"
#include "DownloadProgressChange.h"
HRESULT STDMETHODCALLTYPE Invoke( IDownloadJob *downloadJob,  IDownloadProgressChangedCallbackArgs *callbackArgs)
{
    return NULL;
}

HRESULT STDMETHODCALLTYPE QueryInterface(  REFIID riid,  __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject)
{
    return NULL;
}

ULONG STDMETHODCALLTYPE AddRef( void) 
{
    return NULL;
}

ULONG STDMETHODCALLTYPE Release( void)
{
    return NULL;
}

DownloadCompletedCallback.h

#include <Wuapi.h>
#pragma once
class DownloadCompletedCallback  : public IDownloadCompletedCallback 
{
public:
    HRESULT STDMETHODCALLTYPE Invoke( IDownloadJob *searchJob,  IDownloadCompletedCallbackArgs *callbackArgs);
    HRESULT STDMETHODCALLTYPE QueryInterface(  REFIID riid,  __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject);
    ULONG STDMETHODCALLTYPE AddRef( void) ;
    ULONG STDMETHODCALLTYPE Release( void);
};

DownloadCompletedCallback.cpp

#include "StdAfx.h"
#include "DownloadCompletedCallback.h"
HRESULT STDMETHODCALLTYPE Invoke( IDownloadJob *searchJob,  IDownloadCompletedCallbackArgs *callbackArgs)
{
    return NULL;
}

HRESULT STDMETHODCALLTYPE QueryInterface(  REFIID riid,  __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject)
{
    return NULL;
}

ULONG STDMETHODCALLTYPE AddRef( void) 
{
    return NULL;
}

ULONG STDMETHODCALLTYPE Release( void)
{
    return NULL;
}

А вот и ответ с выхода сборки:

1>------ Build started: Project: WinGet, Configuration: Debug Win32 ------
1>Build started 5/29/2011 10:29:15 PM.
1>InitializeBuildStatus:
1>  Touching "Debug\WinGet.unsuccessfulbuild".
1>ClCompile:
1>  All outputs are up-to-date.
1>  All outputs are up-to-date.
1>ManifestResourceCompile:
1>  All outputs are up-to-date.
1>DownloadProgressChange.obj : error LNK2005: "long __stdcall QueryInterface(struct _GUID const &,void * *)" (?QueryInterface@@YGJABU_GUID@@PAPAX@Z) already defined in DownloadCompletedCallback.obj
1>DownloadProgressChange.obj : error LNK2005: "unsigned long __stdcall AddRef(void)" (?AddRef@@YGKXZ) already defined in DownloadCompletedCallback.obj
1>DownloadProgressChange.obj : error LNK2005: "unsigned long __stdcall Release(void)" (?Release@@YGKXZ) already defined in DownloadCompletedCallback.obj
1>WinGet.obj : error LNK2001: unresolved external symbol "private: virtual long __stdcall DownloadCompletedCallback::QueryInterface(struct _GUID const &,void * *)" (?QueryInterface@DownloadCompletedCallback@@EAGJABU_GUID@@PAPAX@Z)
1>WinGet.obj : error LNK2001: unresolved external symbol "private: virtual unsigned long __stdcall DownloadCompletedCallback::AddRef(void)" (?AddRef@DownloadCompletedCallback@@EAGKXZ)
1>WinGet.obj : error LNK2001: unresolved external symbol "private: virtual unsigned long __stdcall DownloadCompletedCallback::Release(void)" (?Release@DownloadCompletedCallback@@EAGKXZ)
1>WinGet.obj : error LNK2001: unresolved external symbol "public: virtual long __stdcall DownloadCompletedCallback::Invoke(struct IDownloadJob *,struct IDownloadCompletedCallbackArgs *)" (?Invoke@DownloadCompletedCallback@@UAGJPAUIDownloadJob@@PAUIDownloadCompletedCallbackArgs@@@Z)
1>WinGet.obj : error LNK2001: unresolved external symbol "public: virtual long __stdcall DownloadProgressChangedCallback::QueryInterface(struct _GUID const &,void * *)" (?QueryInterface@DownloadProgressChangedCallback@@UAGJABU_GUID@@PAPAX@Z)
1>WinGet.obj : error LNK2001: unresolved external symbol "public: virtual unsigned long __stdcall DownloadProgressChangedCallback::AddRef(void)" (?AddRef@DownloadProgressChangedCallback@@UAGKXZ)
1>WinGet.obj : error LNK2001: unresolved external symbol "public: virtual unsigned long __stdcall DownloadProgressChangedCallback::Release(void)" (?Release@DownloadProgressChangedCallback@@UAGKXZ)
1>WinGet.obj : error LNK2001: unresolved external symbol "public: virtual long __stdcall DownloadProgressChangedCallback::Invoke(struct IDownloadJob *,struct IDownloadProgressChangedCallbackArgs *)" (?Invoke@DownloadProgressChangedCallback@@UAGJPAUIDownloadJob@@PAUIDownloadProgressChangedCallbackArgs@@@Z)
1>C:\Users\Nathan\Documents\Visual Studio 2010\Projects\WinGet\Debug\WinGet.exe : fatal error LNK1120: 8 unresolved externals
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:01.04
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 30 мая 2011

В ваших .cpp файлах вы забыли поместить область видимости класса в определения функций.Они должны быть:

HRESULT STDMETHODCALLTYPE 
    DownloadProgressChangedCallback::Invoke( // <==Note: class! DownloadProgressChangedCallback::
        IDownloadJob *downloadJob,  
        IDownloadProgressChangedCallbackArgs *callbackArgs)
{
    return NULL;
}  

и т. Д.(Все функции в обоих классах.)


Редактировать: добавив сюда комментарии, которые я добавил ниже, к ответу Немо об инициализации ВАРИАНТА:

Чтобы сэкономить некоторые усилия и сложностьМогу я порекомендовать вам использовать класс _variant_t.Это VARIANT-обертка, которая обрабатывает много вещей для вас, с которыми иначе неприятно иметь дело.Вот немного документации .

Чтобы ответить на ваш вопрос более прямо, вам нужно взглянуть на функцию VariantInit () здесь .

0 голосов
/ 30 мая 2011

В ваших файлах .cpp вам необходимо указать полное имя определяемой вами функции-члена:

HRESULT STDMETHODCALLTYPE DownloadProgressChangedCallback::Invoke( IDownloadJob *downloadJob,  IDownloadProgressChangedCallbackArgs *callbackArgs)

[и др.]

Без префикса DownloadProgressChangedCallback:: вы просто определяете глобальную функцию с именем «Invoke». Компоновщик жалуется, потому что (а) вы сделали это дважды и (б) вы не определили фактические функции-члены, которые вы объявили.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...