Delphi/C 中更快的参数传递

发布于 2024-12-06 14:15:59 字数 580 浏览 1 评论 0原文

我有 2 个部分的应用程序,Delphi 和 C,我有 2 个问题 1.向Delphi传递参数最快的方式是什么?

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. 我想在c中通过指针传递参数,我有一个字符数组和一个函数,我不想传递整个数组,剪切它的第一部分并传递其余部分

    void testfunction(char **Data)
    {
        printf("数据 = %d\n", *数据);
        返回;
    }
    
    int main()
    {
        char Data[] = "测试函数";
        测试函数(&&数据[4]); // 错误
        返回0;
    }
    

谢谢

i have 2 parts application, Delphi and C, and i have 2 questions
1. what is the fastest way to pass parameters to Delphi?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

海未深 2024-12-13 14:15:59

Delphi 字符串驻留在堆上并且始终通过指针传递。您的第一个按值传递的示例是不正确的。按值传递的字符串不会被复制。仅复制参考。这对于字符串来说是可能的,因为它们具有神奇的写时复制行为。复制按值传递的动态数组。

传递字符串时使用 const 具有最佳性能,因为编译器可以优化引用计数代码。

你的C代码有点混乱。您不需要 char**,而是需要 char*。请记住,C 字符串(char*)只是指向以 null 结尾的内存块的指针。您不需要获取指向 C 字符串的指针,因为它已经是一个指针。

你指的是 %s 而不是 %d 。要传递从第 5 个字符开始的 C 字符串,请编写 Data+4

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

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

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;
}
谁对谁错谁最难过 2024-12-13 14:15:59

没有人强调这一众所周知的事实,即自 Delphi 2009 以来,string = UnicodeString 因此将导出为 PWideChar / LPCWSTR 而不是 PChar / LPCSTR。值得注意的是,恕我直言,因为如果您的头脑不够清晰,并且希望您的代码适用于所有版本的 Delphi,则可能会感到困惑。

如果您想修改 C 库中的字符串内容,您也许应该使用WideString Delphi 类型而不是stringWideString 由 Windows 分配和处理(这是 COM / Ole 字符串),因此您手头有所有相应的 C API 来处理这些 OLESTR 指针。而且这个 WideString 不会受到 Delphi 2009 Unicode 中断的影响(它一直是 Unicode)。

当然,WideStringstring 慢(出于多种原因,主要原因是 WideString 的堆分配速度慢得多 - 自 Vista 以来变得更好),但恕我直言,这是一种安全的跨语言方式,可以将一些文本数据导出到 Delphi 应用程序和库(在 Windows 世界中)或从 Delphi 应用程序和库(在 Windows 世界中)导出一些文本数据。例如,.Net 世界喜欢封送那些 OLESTR 类型的变量。

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.

南风起 2024-12-13 14:15:59

我想该代码有点误导。它打算只打印“FUNCTION”吗?如果是这样:

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

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

这会将字符串从数组中的索引 4(包括索引 4)传递到该函数到其余部分。
通过传递 char* 您不会复制该函数的本地堆栈中的字符串。只是指向该内存开头的指针。

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.

北座城市 2024-12-13 14:15:59

我只能回答delphi部分(我的C现在有点生疏,当我当前是最新的时,C指针/数组引用让我头疼)

字符串是指针并且总是被传递引用,因此在传递 -EVER 时不会复制数据。

然而,在传递指针S的情况下

procedure test(s:String);

,如果您在过程测试中修改S,则会生成一个唯一的字符串,并将新的指针分配给S,而不是原始传递的变量。您可以传递字符串文字和字符串表达式/动态修改 (s+'bla bla bla')

procedure test(var s: String);

传递指针 S 的地址,

传递指针 S,如果您在过程测试中修改 S,则会得到一个唯一的字符串生成(如果需要),并将新指针分配给 S,以及原始传递的变量。您永远不能动态传递字符串文字和字符串表达式/修改 (s+'bla bla bla')

procedure test(const s: string);

指针 S 被传递,并且您不能在过程测试期间修改 S。 (好吧,你可以搞砸并愚弄编译器,但这很丑陋且很难做到,并且通常需要大量类型转换)

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)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文