代码之家  ›  专栏  ›  技术社区  ›  Greg Nisbet

用字符串调用C函数printf

  •  0
  • Greg Nisbet  · 技术社区  · 6 年前

    printf 用一个 S" ..." 字符串,我命中一个无效的内存地址。正确的方法是将指向在第四方创建的以null结尾的字符串的指针传递给C。

    这里有两个版本的hello world in gforth ,一个使用专用语法写出一个文本字符串,另一个使用 type 将字符串存储为值(尽管很普通)

    这是 helloworld.fs

    #! /usr/bin/env gforth
    .( Hello, world!)
    CR
    bye
    

    helloworld2.fs

    #! /usr/bin/env gforth
    S" Hello, world!" type
    CR
    bye
    

    S" Hello, world" 在Forth运行时内部的某个全局区域中创建一个新字符串,并将指向该字符串的指针推送到堆栈上。它也可能是一个更丰富的对象,我不知道Forth是否使用以null结尾的字符串。

    格沃斯 暴露一些用于调用C函数的单词,在这里 hello_world_c.fs

    #! /usr/bin/env gforth
    \c #include <stdio.h>
    c-function printf- printf a -- n
    
    S" hello" printf-
    CR
    
    bye
    

    hello 然后在跑步时换行。函数的原型 印刷品 a -- n ... 意思是它接受一个地址并返回与 int . 单个格式字符串绝对是可接受的参数集合 印刷品 .

    但是,它会产生错误:

    $ ./hello_world_c.fs
    ar: `u' modifier ignored since `D' is the default (see `U')
    
    in file included from *OS command line*:-1
    hello_world_c.fs:5: Invalid memory address
    S" hello" >>>printf-<<<
    Backtrace:
    $7F3A14D65018 call-c
    $763A14D64F50 execute
    

    S" hello" 不是真正的指针,但实际上是其他东西。是否有方法将其转换为指针以便调用 印刷品 会指向正确的东西吗?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Greg Nisbet    6 年前

    事实证明 S" 不创建以null结尾的字符串,也不会将地址独占地推送到堆栈上。

    S“ 创建一个临时位置(至少在下次调用 S“ )并将长度和地址推送到堆栈中。

    之后 S“ 称为长度在栈顶,这个顺序很重要。

    下面是一个交互式会话的示例 gforth 和一个提示( > )为了清晰起见插入。

    $ gforth
    > S" a"                  ( define a new string, push length and addr )
    > .s                     ( display size of stack and contents of stack )
    <2> 22565888 1
    > .                      ( print and drop top item of stack ) 
    1
    > .s                     ( display size and contents of stack again )
    <1> 22565888
    bye 
    

    世界 s\" 就像 ,只不过它支持C风格的字符串转义。它劫持“读者”的方式与 S“ 是的,但执行一些翻译。

    记住所有这些,下面是一个脚本的实现,它调用 printf- 正确地。

    #! /usr/bin/env gforth
    
    \c #include <stdio.h>
    c-function printf- printf a -- n
    
    ( synonym for drop for documentation purposes.
      remove the initial length of a length, bytes pair created by
      S" or s\" )
    : drop-cstr-length drop ;
    
    s\" hello world\n\0" drop-cstr-length
    printf-
    
    bye
    

    哪个指纹 hello world 然后正常退出。