Spektre Spektre - 1 month ago 12
C++ Question

Including DShow.h breaks VCL AnsiString::sprintf() on BDS2006

Finally got some time to upgrade my video capture class and wanted to compare VFW (I used till now) and DirectShow. As expected DirectShow is faster but when I added info texts suddenly

AnsiString::sprintf
is no longer a member of
AnsiString
.

After some struggle I found a workaround as
printf
still works but I am curious how to fix this. May be some define from DShow.h and DString.h are conflicting or whatever. I cut down all the unnecessary code to show this problem:

//$$---- Form CPP ----
//---------------------------------------------------------------------------
#include <vcl.h>
#include <dshow.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
static int i=0;
Caption=AnsiString().sprintf("%i",i); // this does not work
AnsiString s; s.printf("%i",i); Caption=s; // this does work
i++;
}
//---------------------------------------------------------------------------


It is just simple Form App with single timer on it. The timer is incrementing its counter
i
and outputting as Form Caption. The DirectX libs are not even linked just headers included!

The Linker outputs error:

[C++ Error] Unit1.cpp(20): E2316 'sprintf_instead_use_StringCbPrintfA_or_StringCchPrintfA' is not a member of 'AnsiString'


If I swap the VCL.h and DShow.h includes then compiler stops in DString on this line:

AnsiString& __cdecl sprintf(const char* format, ...); // Returns *this


With message:

[C++ Error] dstring.h(59): E2040 Declaration terminated incorrectly


So there is clearly something conflicting (The
AnsiString
keyword is the problem). Putting DShow.h into
namespace
does not help either.

Does someone have any clues?


Q1. How to fix this?

Q2. What/where exactly is causing this?

The only solution that I think of and should work (but want to avoid it if I can) is to create OBJ (or DLL) file with the DShow stuff and then link that to standard VCL project without including DShow.h in it and of coarse the exports must be without any funny stuff.

Answer

I don't have this very version of dshow.h and dstring.h, so I cannot check it myself, but from the error messages you cite it seems that somewhere in dshow.h or its dependencies they declare an "sprintf" macro. You may look if you can find it.

In order to prevent that behaviour you need to delete this macro. Use

#undef sprintf

after the line that includes dshow.h.