Emit 编译指示

emit 编译指示可以直接影响编译器代码生成器的输出。这样一来,代码将无法移植到其他代码生成器/后端,非常不鼓励使用这种方法。然而,它对于实现与 C++ 或 Objective C 代码的接口非常有用。

示例:

  1. {.emit: """
  2. static int cvariable = 420;
  3. """.}
  4. {.push stackTrace:off.}
  5. proc embedsC() =
  6. var nimVar = 89
  7. # 在 emit 内、字符串字面值以外访问 Nim 符号
  8. {.emit: ["""fprintf(stdout, "%d\n", cvariable + (int)""", nimVar, ");"].}
  9. {.pop.}
  10. embedsC()

nimbase.h 定义了 NIM_EXTERNC C 宏,用于 extern “C” 代码,与 nim c 和 nim cpp 兼容,例如:

  1. proc foobar() {.importc:"$1".}
  2. {.emit: """
  3. #include <stdio.h>
  4. NIM_EXTERNC
  5. void fun(){}
  6. """.}

Note: 为了向后兼容,如果 emit 语句的参数是单一的字符串字面值,可以通过反引号引用 Nim 标识符。但这种用法已经废弃。

顶层 emit 语句所输出的代码混杂在所生成的 C/C++ 文件中,其位置可通过前缀 /*TYPESECTION*/:c:、/*VARSECTION*/ 或 /*INCLUDESECTION*/ 加以影响:

  1. {.emit: """/*TYPESECTION*/
  2. struct Vector3 {
  3. public:
  4. Vector3(): x(5) {}
  5. Vector3(float x_): x(x_) {}
  6. float x;
  7. };
  8. """.}
  9. type Vector3 {.importcpp: "Vector3", nodecl} = object
  10. x: cfloat
  11. proc constructVector3(a: cfloat): Vector3 {.importcpp: "Vector3(@)", nodecl}