开发者

Faster Parameter Passing in Delphi/C

开发者 https://www.devze.com 2023-04-07 11:34 出处:网络
i have 2 parts application, Delphi and C, and i have 2 questions 1. what is the fastest way to pass parameters to Del开发者_开发问答phi?

i have 2 parts application, Delphi and C, and i have 2 questions 1. what is the fastest way to pass parameters to Del开发者_开发问答phi?

procedure name(Data: string); // Data is Copied to another location before passing so its slow
procedure name(var Data: string); // Data is Passed by pointer, Faster
procedure name(const Data: string); // unknown
  1. i wanna pass parameters by pointers in c, i have a char array and a function, i don't wanna pass the whole array, cut a first part of it and pass the rest

    void testfunction(char **Data)
    {
        printf("Data = %d\n", *Data);
        return;
    }
    
    int main()
    {
        char Data[] = "TEST FUNCTION";
        testfunction(&&Data[4]);        // Error
        return 0;
    }
    

thanks


Delphi strings reside on the heap and are always passed by pointer. Your first example of pass by value is incorrect. Strings passed by value are not copied. Only the reference is copied. This is possible for strings because they have magic copy-on-write behaviour. A dynamic array passed by value is copied.

Using const when passing a string has the best performance because the compiler can optimise out reference counting code.

Your C code is somewhat confused. You don't want char**, rather you want char*. Remember that a C string, a char*, is just a pointer to a null-terminated block of memory. You don't need to take a pointer to a C string since it is already a pointer.

And you mean %s rather than %d surely. To pass a C string starting at the 5th character write Data+4.

 void testfunction(char *Data) {
     printf("Data = %s\n", Data);
 }

int main() {
    char Data[] = "TEST FUNCTION";
    testfunction(Data+4);
    return 0;
}


No one did emphasize on the well-known fact that since Delphi 2009, string = UnicodeString so will be exported as PWideChar / LPCWSTR and not PChar / LPCSTR. Worth noting IMHO, because it may be confusing if it is not clear enough in your mind, and expect your code to work with all version of Delphi.

If you want to modify the string content from C library, you should perhaps use a WideString Delphi type instead of a string. WideString is allocated and handled by Windows (this is the COM / Ole string), so you have all the corresponding C API at hand to handle those OLESTR pointers. And this WideString do not suffer from the Delphi 2009 Unicode break (it has always been Unicode).

Of course, WideString is slower than string (for several reasons, the main one is the much slower heap allocation for WideString - getting better since Vista), but it's IMHO a safe a cross-language way of exporting some TEXT data to and from a Delphi application and library (in the Windows world). For instance, the .Net world will like marshaling those OLESTR kind of variable.


The code is a bit misleading I guess. Does it intend to print just " FUNCTION"? If so:

void testfunction(const char *Data)
{
    printf("Data = %s\n", Data);
    return;
}

int main()
{
    char Data[] = "TEST FUNCTION";
    testfunction(Data+4);
    return 0;
}

That will pass the string to that function from index 4 (including) in the array to the rest of it. By passing char* you are not copying the string in that function's local stack. Just the pointer to the beginning of that memory.


I can only answer the delphi part (my C is a little rusty just now and C pointer/array references make my head hurt when I am current and up to date)

Strings are pointer and are ALWAYS passed by reference, so the data is not copied on passing -EVER.

However, in the case of the

procedure test(s:String);

The pointer S is passed, and if you modify S inside the procedure test, a unique string is generated, and new pointer assigned to S, but not the original passed variable. You can pass string litterals and string expressions/modified on the fly (s+'bla bla bla')

procedure test(var s: String);

the address to the pointer S is passed,

The pointer S is passed, and if you modify S inside the procedure test, a unique string is generated (if required), and new pointer assigned to S, AND the original passed variable. You can NEVER pass string litterals and string expressions/modified on the fly (s+'bla bla bla')

procedure test(const s: string);

The pointer S is passed, and you can not modify S inside the procedure test period. (ok, you can screw around and fool the compiler but it is ugly and hard to do and usually requires a lot of type casting)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号