Hello, Mark. 
You wrote in <mid:[EMAIL PROTECTED]>

MW> Here's some plugin sample code that should serve as a starting point
MW> for coding in C++. It's working now in Visual C++, Borland C++ Builder
MW> 6.0, and Metrowerks Codewarrior 8.0. The compiler-specific parts are
MW> at the beginnings of both files. There are two source files in the zip
MW> file here, a .h header file and a .cpp stub file. I've also included a
MW> project file for C++ Builder.

Unfortunately you made the same error I made when translate tbtest...
(see <mid:[EMAIL PROTECTED]>)

,----- [ from header file ]
| #if defined(interface)
| interface DECLSPEC_UUID("9DD91B89-A551-4180-8A81-2CCF584CD4BF") ITBPDataProvider
| #else
| class ITBPDataProvider
| #endif
| {
| public:
`-----

Are you REALLY tested it on VC? Yes, it will be compiled, but it will not work
properly! The main bug here is that DELPHI word "interface" is simplified
construction from C++. And it must be translated into CPP as interface inherited
from IUnknown, else you'll got the wrong VMT (virtual method's table) in the
final code, so the wrong functions will be called! I've checked it by
disassembling compiled code - one's compiled on DELPHI, and the C++ translation.
For example, here is the working example of calling GetDataByID (this is
common disassembling from DELPHI compiled tbtest and also from C++ using my header):

,----- [ how it must be to work properly ]
|  mov     eax, [ebp+ITBPDataProvider]     //eax = ITBPDataProvider**
|  mov     edx, [eax]                      //edx = ITBPDataProfider*
|  ...
|  push    eax
|  call    dword ptr [edx+10h]             // VMT: 4 bytes per func -> calling
|                                          // 4-th function of ITBPDataProvider
|                                          // (GetDataById)
`-----

And here is the code from the same source, but with using your header instead:

,----- [ what is happens in your case ]
|  mov     eax, [ebp+ITBPDataProvider]     //eax = ITBPDataProvider**
|  mov     edx, [eax]                      //edx = ITBPDataProfider*
|  ...
|  push    eax
|  call    dword ptr [edx]                 // VMT: 4 bytes per func -> calling
|                                          // 1-th function of ITBPDataProvider
|                                          // (GetDataById)
`-----

You write "GetDataById", but hidden QueryInteface is actually called...


So, for the working code you MUST write something like:

interface DECLSPEC_UUID("9DD91B89-A551-4180-8A81-2CCF584CD4BF") ITBPDataProvider : 
public IUnknown

or (without inheritance):

class ITBPDataProvider
{
public:
       HRESULT QueryInterface (REFIID riid, void **ppvObject);
       ULONG AddRef (void);
       ULONG Release (void);
       ... // your methods
       ...

This is main and critically serious error. Please, refer to other variants of API 
(which I
referred on the top of the letter) and work more... I warn you about it because
giving the wrong headers from the beginning can prefer many from writing such
plugins.

There are also some cosmetic bugs:

1. Strictly speaking, the interface is defined as struct. (there is line in the
header: #define interface struct. So, I would change your code by using word
"struct" if "interface" is undefined, and also "public:" is not necessary in
this case. But, repeat, this is only cosmetic.

2. If you write on CPP, why are you using malloc and free? Let use new and
delete instead! CPP is not C, and although malloc and free still works, they are
deprecated in CPP. Of course, this is also just cosmetic, and somebody who will
use it will change it, but anywhere...

-- 
Sincerely,
 Alexey.
Using TB 2.0b2 on WinXP Pro SP1 (2600), spelling by ORFO2002 (CSAPI) 
..with Kaspersky Antivirus Plugin (ver 3.5 Gold) & antispam filter BayesIt! 0.3b

   mailto:[EMAIL PROTECTED]


________________________________________________
http://www.silverstones.com/thebat/TBUDLInfo.html

Reply via email to