5,530
社区成员




extern __declspec (package) const GUID IID_IProgress;
interface DECLSPEC_UUID("{C23CF58D-3121-45D2-A0DB-B19F98350D52}") IProgress;
typedef TComInterface<IProgress, &IID_IProgress> IProgressPtr;
// *********************************************************************//
// Interface: IProgress
// Flags: (4352) OleAutomation Dispatchable
// GUID: {C23CF58D-3121-45D2-A0DB-B19F98350D52}
// *********************************************************************//
interface IProgress : public IDispatch
{
public:
HRESULT STDMETHODCALLTYPE ProgressCallback(double Progress/*[in]*/); // [201]
};
// *********************************************************************//
// DispIntf: IProgress
// Flags: (4352) OleAutomation Dispatchable
// GUID: {C23CF58D-3121-45D2-A0DB-B19F98350D52}
// *********************************************************************//
template<class T>
class IProgressDispT : public TAutoDriver<IProgress>
{
public:
IProgressDispT(){}
IProgressDispT(IProgress *pintf)
{
TAutoDriver<IProgress>::Bind(pintf, false);
}
IProgressDispT(IProgressPtr pintf)
{
TAutoDriver<IProgress>::Bind(pintf, true);
}
IProgressDispT& operator=(IProgress *pintf)
{
TAutoDriver<IProgress>::Bind(pintf, false);
return *this;
}
IProgressDispT& operator=(IProgressPtr pintf)
{
TAutoDriver<IProgress>::Bind(pintf, true);
return *this;
}
HRESULT __fastcall ProgressCallback(double Progress/*[in]*/);
};
typedef IProgressDispT<IProgress> IProgressDisp;
class B;
class A:public B,public IProgress
{
public:
HRESULT STDMETHODCALLTYPE ProgressCallback(double Progress)
{
//do something();
return 0;
}
}
A a;
IProgress *p=&a;
//编译没有问题,运行没有问题
a.ProgressCallback(1);
//编译没有问题,运行到这里直接报错:pure virtual function called
//为什么要这么调用,因为有个函数的参数,类型是“IProgress *”,这个函数也是com里面的函数
p->ProgressCallback(1);
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, BASSEncoder_TLB, Vcl.ComCtrls;
type
TForm1 = class(TForm, IProgress)
ProgressBar1: TProgressBar;
Button7: TButton;
procedure Button7Click(Sender: TObject);
private
{ Private declarations }
function ProgressCallback(Progress: Double): HResult; stdcall;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
Uses
//BASSEncoderLibrary,
ComObj;
procedure TForm1.Button7Click(Sender: TObject);
var
BASSEncodeFileMP3: IBASSEncodeFile;
Error: HResult;
begin
//* Acquire the class
BASSEncodeFileMP3 := CreateComObject(CLASS_TBASSEncodeFileMP3) as IBASSEncodeFile;
//* Generate MP3, CBR 320 kbps, 44100 Hz, 2 channels (stereo)
Error := BASSEncodeFileMP3.EncodeFile(EditInputFileName.Text, EditOutputFileName.Text, '-b 320', 44100, 2, 0, 0, 0, Self);
if Error <> 0 then begin
Showmessage('Error: ' + IntToStr(Error));
end;
end;
function TForm1.ProgressCallback(Progress: Double): HResult; stdcall;
begin
ProgressBar1.Position := Round(Progress);
Result := S_OK;
end;
end.
虽然语言是Delphi,相信大家都看得明白,我的C++代码就是直接把这个delphi代码进行了翻译,给出关键部分,节约大家时间:
class TMainForm:public TForm,public IProgress
{
//....
private:
HRESULT STDMETHODCALLTYPE ProgressCallback(double Progress);
}
HRESULT TMainForm::STDMETHODCALLTYPE ProgressCallback(double Progress)
{
return 0;
}
void __fastcall TFormMain::btn1Click(TObject *Sender)
{
IBASSEncodeFilePtr BASSEncodeFileMP3;
BASSEncodeFileMP3 = CreateComObject(CLSID_TBASSEncodeFileMP3);
BASSEncodeFileMP3->EncodeFile(L"C:\\11.wav", L"C:\\22.mp3", L"-b 320", 44100, 2, 0, 0, 0, this);
}
我这个C++代码,完全就是Delphi翻译过来的,唯一不同的就是,当我执行btn1Click的时候,会弹出错误:Pure virtual function called...
我现在的想法就是,delphi和C++在调用com的过程中,存在一些差别,才导致这个结果。。