Delphi Const Array

Please help! I need this conversion to write wrapper for some C headers for Delphi.

As an example:

How can I convert 'array of const' to 'varargs'?

The last airbender 2 confirmed. Potential release date. In reality, there are many who have said that they do not believe that the Last Airbender 2 should be released. The original struggled and many believe that the damage has been done. Despite this, M. Night Shyamalan has stated that he does have plans to make the film but he wants to release one of his other ideas first. Initially, Paramount representatives set the release date of «The Last Airbender 2» for May 2012; however it wasn’t released due to some budgetary concerns. According to several Internet resources, Warner Bros. Company is to finance the second part provided Night Shyamalan, who has exhausted his potential, won’t be responsible for production.

edit: function PushString is actually inside the record (I gave a simplified example), and I do not have direct access to pushfstring. Direct call is excluded.

edit 2:I write the units for LUA library for Delphi and the case is quite important for me.

Specifying and providing all the details of the matter - I have this function in C:

In Delphi I have something like this:

LuaLibrary.pas

dtxLua.pas

and in other units like Lua.pas i use only TLuaState from dtxLua.pas (because LuaLibrary is bulky, dtxLua is my wrapper), for many useful and cool things..

HNB
HNBHNB

4 Answers

I'm guessing that the prototype for pushfstring is somewhat like this:

If it isn't, and is instead:

.. then I should have you covered also.

In C, if you have to pass on a call from one variadic function to another, you should use va_list, va_start and va_end, and call the v version of the function. So, if you were implementing printf yourself, you might use vsprintf to format the string - you can't call sprintf directly and pass along the variadic argument list. You need to use va_list and friends.

It's pretty awkward to handle C's va_list from Delphi, and technically it shouldn't be done - the implementation of va_list is specific to the C compiler vendor's runtime.

However, we can try. Suppose we have a little class - though I made it a record for ease of use:

Using this record, we can manually construct the call frame expected for various C calls. C's calling convention on x86 is to pass arguments from right to left on the stack, with the caller cleaning up. Here's the skeleton of a generic C calling routine:

Taking printf as an example:

Calling the va_list version is slightly more involved, as the va_list argument's location needs to be placed carefully where it is expected:

Notes:

  • The above expects x86 on Windows. Microsoft C, bcc32 (Embarcadero C++) and gcc all pass va_list in the same way (a pointer to the first variadic argument on the stack), according to my experiments, so it should work for you; but as soon as the x86 on Windows assumption is broken, expect this to possibly break too.

  • The stack is swapped to ease with its construction. This can be avoided with more work, but passing va_list also becomes trickier, as it needs to point at the arguments as if they were passed on the stack. As a consequence, the code needs to make an assumption about how much stack the called routine uses; this example assumes 8K, but this may be too small. Increase if necessary.

Barry KellyBarry Kelly

The wrapper you are trying to write is possible in Free Pascal, since Free Pascal supports 2 equvalent declarations for varargs external functions:

so instead of

you should write

Update: I have tried the same trick in Delphi, but it does not work:

kludgkludg

An 'array of const' is actually an array of TVarRec, which is a special variant type. It's not compatible with varargs, and you really should be able to call the varargs function directly without a wrapper around it.

Mason WheelerMason Wheeler

Barry Kelly inspired me to seeking a solution without replacing the stack.. Here is the solution (probably could also use the Invoke from the rtti unit, instead RealCall_CDecl).

HNBHNB

Not the answer you're looking for? Browse other questions tagged delphiarraysvariadic-functions or ask your own question.

Is there a way in Delphi declaring an array of strings such as following one?

nonenone

4 Answers

RRUZRRUZ

In XE7 you can declare a dynamic array constant like this:

LU RDLU RD

You can use dynamic arrays and try this:

While this does do a run-time initialization of a dynamic array on the heap, it also shows that Delphi supports a 'pseudo-constructor' on dynamic arrays that allow in-place initialization. (NOTE: the above code isn't thread-safe).

Now all you need to do to find out the length of the array, is use the Length() standard function, or to find the allowed index range, use the Low() and High() standard functions.

If you're using an older version of Delphi, replace the TArray with your own dynamic-array string type such as:

Allen BauerAllen Bauer

You can do this in a indirect way. Create a function like:

and call this function like:

where:

user1919497user1919497

Not the answer you're looking for? Browse other questions tagged arraysdelphiconst or ask your own question.