I am converting a C header file for a video encoder DLL to Delphi Pascal.
I've run into some issues with access violations with the following function and need help resolving this:
h264venc_tt * MC_EXPORT_API h264OutVideoNew(
void * (MC_EXPORT_API * get_rc)(const char* name),
const struct h264_v_settings * set,
int32_t options,
int32_t CPU,
int32_t frame0,
int32_t nframes);
Note: MC_EXPORT_API = cdecl
The get_rc is declared as follows:
// resource functions dispatcher
void * MC_EXPORT_API get_rc(const char* name)
{
if (!strcmp(name, "err_printf"))
return (void*) error_printf;
else if (!strcmp(name, "prg_printf"))
return (void*) progress_printf;
else if (!strcmp(name, "wrn_printf"))
return (void*) warn_printf;
else if (!strcmp(name, "inf_printf"))
return (void*) info_printf;
return NULL;
}
This function returns a pointer to another function that has a Variable Argument list. One of these is declared as this:
void error_printf(const char * fmt, ...)
{
char lst[256];
va_list marker;
va_start(marker,fmt);
vsprintf(lst,fmt,marker);
va_end(marker);
printf("%s\n", lst);
}
I've translated this the function call and the get_rc to this Delphi Pascal code:
PErrorMessageHandler = function (const Name: String): Pointer; cdecl varargs;
function h264OutVideoNew(
get_rc: PErrorMessageHandler;
settings: Ph264_v_settings;
options: int32;
CPU: int32;
frame0: int32;
nFrames: int32
): Pointer; cdecl; external 'mc_enc_avc.dll' index 4;
Unfortunately, I have no idea how to implement the C-style method error_printf shown above.
Can anyone help to point me in the right direction? I am also curious if I have implemented the other functions correctly as I am getting access violations when I try to call the h264OutVideoNew()
function.
PS! I've not included the packed record Th264_v_settings
/P_h264_v_settings
in this post as this is very long and not really the problem.
A C parameter of type char*
is a pointer to a null-terminated array of 8 bit characters. In Delphi the equivalent type is PAnsiChar
. You cannot use string
since that is a managed Delphi type that has no equivalent in C.
In addition, the error function prototype has void return value. You are returning a pointer and that's an error.
The bigger problem that you have is that you cannot readily implement a C style function that receives a variable number of arguments in Delphi. You can declare and call such a function, but you cannot implement one. This means that such a function, with variable arguments, has to be an external function.
Now, you could write your own assembler routine to full off the variable arguments. However, that's not the route I would take. I would write the function in C and then compile it to a .obj file that can be linked into your Delphi program with $LINK
.
If you don't actually need to read off the variable arguments, you can ignore them like this:
TErrorMessageHandler = procedure(Name: PAnsiChar); cdecl;
Note that I have made the following changes:
T
which is standard.Name
parameter.varargs
which we cannot implement in Delphi and thus ignore the additional parameters.Then your imported function would look like this:
function h264OutVideoNew(
get_rc: TErrorMessageHandler;
settings: Ph264_v_settings;
options: int32;
CPU: int32;
frame0: int32;
nFrames: int32
): Pointer; cdecl; external 'mc_enc_avc.dll' index 4;
And then you can implement the error callback function like this:
procedure error_printf(Name: PAnsiChar); cdecl;
begin
// do stuff here
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With