Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium


API conversion questions

Posted on 2002-05-30
Medium Priority
Last Modified: 2011-04-14
I am having issues with some API conversions.  Probably the biggest problem is that I don't really know C all that well.

For the most part I manage to bumble my way through, but there's one thing that I just don't know how to translate - variable number of parameters.

When in the C declaration you get something like...

int somefunction(int param_count, ...)

...how does this translate into Delphi?
Question by:Hamlet081299
  • 5
  • 3
  • 2
  • +3
LVL 44

Expert Comment

ID: 7045948
Hi Hamlet it has been a while. How have you been doing?

Don't know it this help you any but I cheat and look in the Windows.pas file and look for the function I am trying to use and see how Delphi has it setup.

Like this one
function GetFileInformationByHandle(hFile: THandle; var lpFileInformation: TByHandleFileInformation): BOOL; stdcall;

Which in the SDK it is listed like this
BOOL GetFileInformationByHandle(

    HANDLE hFile,      // handle of file
    LPBY_HANDLE_FILE_INFORMATION lpFileInformation      // address of structure

A lot of times this helps me break it down faster and code it using Delphi Syntax

The Crazy One
LVL 44

Expert Comment

ID: 7045956
Somtimes the syntax is similar between the two but quite often they are not. So when I check the Windows.pas I can see what Delphi expects to be passed as the parameters.

Expert Comment

ID: 7046026
Hi Hamlet,

if your function in C is like,
int somefunction(int param, char *test, float &c);

the same function in delphi is:

function somefunction(var param: integer; test: string; c: real): integer;

I think is this,

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

LVL 14

Expert Comment

ID: 7046037
function somefunction(param_count: Integer): Integer;
LVL 14

Expert Comment

ID: 7046039
oops, everyone... sorry, didn't refresh the page :)

Author Comment

ID: 7046101
Hi.  Yeah, took some time out from the computer scene.
I too often look at windows API translations, but in the Windows API they avoid the variable number of parameters.

Thanks for the suggestions, but I know how to translate when the parameters are fixed.  In C though you can specify a function that has a variable number of parameters.  This is what the "..." indicates.

(n example of a C function that uses this is "printf", if that helps)
LVL 11

Expert Comment

ID: 7046171
... means variable argument count (what cdecl is for).
It is not directly convertible to Pascal.
You will often find a second function with a parameter of va_list type. That one is convertible with a glue function.
Have a look at the Java Native Interface conversion over at http://delphi-jedi.org/APILIBRARY

Author Comment

ID: 7046208
Thanks.  Unfortunately the person who wrote the dll did not consider this as the dll was only intended to be called from C.

I think my only option may be to use some embedded assembler to do the calling.  That way I can push all the necessary arguments one by one.

The other thing I tried was to translate ...
  int somefunction(int param_count, ...)
... as ...
  function somefunction(param_count: integer; p1, p2, p3, p4, p5, p6, p7, p8, p9, p10: pointer); cdecl;

... and then just pass nil for the unneeded parameters.  It actually seems to work okay, and I think because of the cdecl calling convention it is not doing anything nasty to the stack.

Author Comment

ID: 7046210
(slight improvement) I changed p1..p10 to have defaults of nil so I don't have to specify them
LVL 14

Expert Comment

ID: 7046298
you can also do

function somefunction(var somename): someresult;

and it will actually be passed as pointer.

As for the variable number of variables, nope, Pascal can't do it... you can, of course, get round it using arrays, if suitable... eg.

function GetLargestNumber(Numbers: array of Integer): Integer;
  i: Integer;
  if Length(Numbers) = 0 then
    raise Exception.Create('Cannot pass empty array!');
  Result := Numbers[Low(Numbers)];
  for i := Low(Numbers) to High(Numbers) do
    if Numbers[i] > Result then
      Result := Numbers[i];

and you call it as follows:

MyLargestNumber := GetLargestNumber([0, 1, 43, 65, 324, 76, 54]);

Author Comment

ID: 7049307
DragonSlayer - thanks, but the main point was to translate an existing API (from a dll written in C).  I've decided for now to stick with having the fixed number of defined parameters (which works), and may later try to wrap the API using some embedded assembly.

As sometimes happens I post a question here to try to get some ideas, but then largely solve the problem myself anyway (sigh).

If someone wants to give me a rough sample of asm code that'd push parameters from an "array of const" onto the stack and then call a stripped down version of the API then I'll award them the points.

Author Comment

ID: 7235005
Time for a tidy up.

I think the best answer to this question was what I came up with myself.

Passing a defined large number of parameters to the function seesm to behave correctly.  It's not ideal, but in the end I allowed up to 20 parameters all with "nil" defaults so I'm happy with that.

I'll get CS to close this question.  Thanks to those who took the time to respond.

Accepted Solution

modulo earned 0 total points
ID: 7689521
PAQ'd and 100 points refunded


Community Support Moderator
Experts Exchange

Featured Post

Become an Android App Developer

Ready to kick start your career in 2018? Learn how to build an Android app in January’s Course of the Month and open the door to new opportunities.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
Screencast - Getting to Know the Pipeline
Suggested Courses
Course of the Month14 days, 1 hour left to enroll

580 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question