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
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

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…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
Suggested Courses

719 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