Zak Phoenix McKracken
Zak Phoenix McKracken

Reputation: 27

Convert C++ callback function to Delphi

I need help in translating this C++ header into Delphi.

It's a callback function prototype, and some inline functions (I have no clear idea why they are there, since it seems they are not used).

Source .h code:

// This file defines 'myStreamWriter_t' a function pointer type.
// The user of the C API need to specify a callback of above type which
// will be called on xxx_print(...) with the formatted data.
// For C++ API, a default callback is specified which writes data to
// the stream specified in xxx::print

typedef int(*myStreamWriter_t)(const char* p1,
                                     int p2,
                                     void *p3);

The above It's quite easy: it should translate, in Delphi, as follows:

type
   myStreamWriter_t = function(const p1:Pchar; 
                                     p2:integer;
                                     p3:pointer):integer;


Now, there are other things that I don't know how to translate:

Souce .h code:

#include <ostream>

namespace ns1 {
namespace ns2 {

inline int OstreamWriter(const char *p1, int p2, void *p3);

struct StreamProxyOstream {

static int writeToStream(const char* p1, int p2, void *p3);
    // Format, to the specified 'p3' stream, which must be a pointer to a
    // 'std::ostream', the specified 'p2' bytes length of the specified 'p1' data.
};


inline
int StreamProxyOstream::writeToStream(const char *p1,
                                      int         p2,
                                      void       *p3)
{
    reinterpret_cast<std::ostream*>(p3)->write(p1, p2);
    return 0;
}

inline
int OstreamWriter(const char *p1, int p2, void *p3)
{
    return StreamProxyOstream::writeToStream(p1, p2, p3);
}

}  // close namespace ns2
}  // close namespace ns1

...how to translate in Delphi the above??

Thank you very much!

Upvotes: 0

Views: 307

Answers (1)

Rudy Velthuis
Rudy Velthuis

Reputation: 28836

Your translation is not correct. It should probably be:

type
  myStreamWriter_t = function(p1: PAnsiChar; p2: Integer; p3: Pointer): Integer cdecl;

Note that there is no Delphi equivalent for const char *x (non-const pointer to const chars), so just use PAnsiChar. In any Delphi from 2009 on, PChar is PWideChar, and that is not the equivalent to char *.

const x: PAnsiChar is the equivalent of char * const x, meaning the pointer is const, not the char(s) it points to.

And it is very likely that your calling convention is wrong.

Similarly, you should translate the other functions. But note that a function (method) on a struct may be called differently, i.e. using a proprietary Microsoft convention for methods (__thiscall). There is no Delphi equivalent for it.

But probably you can't call such methods without getting into compatibility trouble anyway. You can mimic the behaviour of these classes/structs, but you will not be able to make them binary compatible in Delphi, unless you jump through several hoops and/or use assembler.

More info on my website:

If you want to mimic the behaviour, you can do something like:

 OstreamWriter(p1: AnsiChar; p2: Integer; p3: Pointer): Integer; // no need for binary compatibility, so you can omit cdecl
 begin
   TStream(p3).Write(p1^, StrLen(p1) + 1);
   TStream(p3).Write(p2, SizeOf(p2));
 end;

But you will have to rewrite the entire C++ code. This is not something simple, if you already have problems with the code above.

Upvotes: 1

Related Questions