Token导航 LogoToken导航

Agent Skill · 前端设计

nim-c-interop(Nim C 互操作)

用于辅助前端页面、组件、样式和交互逻辑的开发与维护。它适合让 Agent 生成或审查 React、Next.js、Vue、Tailwind、CSS 等相关代码,整理组件结构,或定位布局和性能问题。使用时需要结合项目现有设计系统、路由和构建方式,避免只生成孤立片段;涉及页面改动时,应配合本地预览和构建检查确认视觉效果。

nim-c-interop 是前端设计类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证为 MIT,第三方扫描已通过,按安装量在前端设计类的 10,216 个 Skill 里排第 730。

总安装 12,984周安装 491GitHub Stars 142下载 3,646核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:nim-c-interop(Nim C 互操作)
来源仓库:https://github.com/thebushidocollective/han
仓库路径:skills/nim-c-interop
安装命令:
npx skills add https://github.com/thebushidocollective/han --skill 'Nim C Interop'
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/thebushidocollective/han --skill 'Nim C Interop'

这个 Skill 是做什么的

前端设计类 Skill 关注页面结构、视觉规范和组件写法,输出通常是可运行的界面代码。

用于辅助 Nim 语言与 C 代码的互操作开发,支持混合编程场景。适合在 Codex、Claude、Cursor、Gemini CLI 中生成绑定代码或审查接口。需结合项目构建系统和平台约束,避免脱离上下文输出片段。安装方式:通过 npx 从 GitHub 仓库添加,建议先确认编译器兼容性。

注意:涉及底层调用时应谨慎处理内存安全和类型转换。

来源仓库内路径:skills/nim-c-interop

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/thebushidocollective/han --skill 'Nim C Intero…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

nim-c-interop 怎么安装?

在终端执行 npx skills add https://github.com/thebushidocollective/han --skill 'Nim C Interop'。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

nim-c-interop 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

nim-c-interop 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

nim-c-interop 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

nim-c-interop 用的人多吗?

公开数据是累计安装 12,984 次,近一周安装 491 次,下载 3,646 次,GitHub 142 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

nim-c-interop 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 3 个目录同时收录,说明这个 Skill 流传比较广。
  • 许可证明确为 MIT,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理前端设计类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

前端设计类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
frontend-design

前端设计 · Codex、Claude

8,823,360126,072只读MIT通过
vercel-composition-patterns

Vercel 组合模式 · Codex、Claude

3,858,81625,893需要联网MIT通过
vercel-react-native-skills

Vercel React native skills 前端 · Codex、Claude

2,468,66425,878只读MIT通过
adapt

adapt 搜索 · Codex、Claude

2,027,04023,125操作浏览器未明确通过
bolder

bolder 分析 · Codex、Claude

2,004,28823,130只读未明确通过
nim-c-interop

Nim C 互操作 · 本页

12,984142需要联网MIT通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Nim C Interop

Introduction

Nim compiles to C, enabling seamless interoperability with C code and libraries. This bi-directional integration allows Nim developers to leverage decades of C libraries while exposing Nim code to C applications. Understanding C interop is essential for systems programming and library wrapping.

The interop mechanism uses pragmas like importc, exportc, and header to declare foreign functions and types. Nim's type system maps naturally to C, with explicit control over memory layout and calling conventions. This enables zero-overhead abstraction while maintaining C ABI compatibility.

This skill covers importing C functions and types, wrapping C libraries, header file generation, memory layout control, callback handling, and patterns for safe type-safe C interop in systems programming.

Importing C Functions

Import C functions using pragmas to make them callable from Nim code.

# Basic C function import
proc printf(format: cstring): cint {.importc, varargs, header: "<stdio.h>".}

proc main() =
  printf("Hello from C!\n")
  printf("Number: %d\n", 42)

# C function with explicit name
proc c_sqrt(x: cdouble): cdouble {.importc: "sqrt", header: "<math.h>".}

proc useSqrt() =
  let result = c_sqrt(16.0)
  echo result  # 4.0

# Multiple headers
proc malloc(size: csize_t): pointer {.importc, header: "<stdlib.h>".}
proc free(p: pointer) {.importc, header: "<stdlib.h>".}

proc manualAlloc() =
  var p = malloc(100)
  # Use memory
  free(p)

# C types mapping
proc strlen(s: cstring): csize_t {.importc, header: "<string.h>".}
proc strcpy(dest, src: cstring): cstring {.importc, header: "<string.h>".}

# Variadic C functions
proc snprintf(buf: cstring, size: csize_t, format: cstring): cint
  {.importc, varargs, header: "<stdio.h>".}

proc formatString(): string =
  var buffer: array[256, char]
  discard snprintf(cstring(addr buffer), 256, "Value: %d", 42)
  result = $cstring(addr buffer)

# C macros as inline procs
proc EXIT_SUCCESS(): cint {.importc: "EXIT_SUCCESS", header: "<stdlib.h>".}
proc EXIT_FAILURE(): cint {.importc: "EXIT_FAILURE", header: "<stdlib.h>".}

# Function pointers
type
  CompareFunc = proc (a, b: pointer): cint {.cdecl.}

proc qsort(base: pointer, nmemb, size: csize_t, compar: CompareFunc)
  {.importc, header: "<stdlib.h>".}

proc compareInts(a, b: pointer): cint {.cdecl.} =
  let x = cast[ptr cint](a)[]
  let y = cast[ptr cint](b)[]
  return x - y

proc sortArray() =
  var arr = [5, 2, 8, 1, 9]
  qsort(addr arr[0], arr.len, sizeof(cint), compareInts)

# C struct access
type
  TimeSpec {.importc: "struct timespec", header: "<time.h>".} = object
    tv_sec: int
    tv_nsec: int

proc clock_gettime(clk_id: cint, tp: ptr TimeSpec): cint
  {.importc, header: "<time.h>".}

# Calling conventions
proc win_api_func(): cint {.stdcall, importc, dynlib: "kernel32.dll".}

# C++ name mangling
proc cpp_function(x: cint): cint
  {.importcpp, header: "<myheader.hpp>".}

# C library linking
{.passL: "-lm".}  # Link math library
proc cos(x: cdouble): cdouble {.importc, header: "<math.h>".}

Import pragmas enable calling C code with full type safety from Nim.

Wrapping C Libraries

Create type-safe Nim wrappers around C libraries for idiomatic usage.

# Simple wrapper
type
  FileHandle = distinct cint

proc c_open(path: cstring, flags: cint): cint
  {.importc: "open", header: "<fcntl.h>".}

proc c_close(fd: cint): cint
  {.importc: "close", header: "<unistd.h>".}

proc openFile(path: string): FileHandle =
  let fd = c_open(cstring(path), 0)
  if fd < 0:
    raise newException(IOError, "Failed to open file")
  FileHandle(fd)

proc close(fh: FileHandle) =
  discard c_close(cint(fh))

# Wrapping libcurl
type
  Curl = distinct pointer

const CURLE_OK = 0

proc curl_easy_init(): Curl {.importc, header: "<curl/curl.h>".}
proc curl_easy_cleanup(curl: Curl) {.importc, header: "<curl/curl.h>".}
proc curl_easy_setopt(curl: Curl, option: cint, parameter: pointer): cint
  {.importc, varargs, header: "<curl/curl.h>".}

type
  CurlHandle = object
    handle: Curl

proc newCurl(): CurlHandle =
  result.handle = curl_easy_init()
  if result.handle.pointer == nil:
    raise newException(Exception, "Failed to initialize curl")

proc close(curl: CurlHandle) =
  curl_easy_cleanup(curl.handle)

proc setUrl(curl: CurlHandle, url: string) =
  discard curl_easy_setopt(curl.handle, 10002, cstring(url))

# RAII wrapper with destructor
type
  CurlSession = object
    curl: Curl

proc `=destroy`(session: var CurlSession) =
  if session.curl.pointer != nil:
    curl_easy_cleanup(session.curl)
    session.curl = Curl(nil)

proc newSession(): CurlSession =
  result.curl = curl_easy_init()

# Wrapping complex C API
type
  SqliteDb = distinct pointer
  SqliteStmt = distinct pointer

proc sqlite3_open(filename: cstring, db: ptr SqliteDb): cint
  {.importc, header: "<sqlite3.h>".}

proc sqlite3_close(db: SqliteDb): cint
  {.importc, header: "<sqlite3.h>".}

proc sqlite3_prepare_v2(
  db: SqliteDb, sql: cstring, nbyte: cint,
  stmt: ptr SqliteStmt, tail: ptr cstring
): cint {.importc, header: "<sqlite3.h>".}

type
  Database = object
    handle: SqliteDb

proc openDatabase(filename: string): Database =
  var db: SqliteDb
  let rc = sqlite3_open(cstring(filename), addr db)
  if rc != 0:
    raise newException(IOError, "Cannot open database")
  result.handle = db

proc `=destroy`(db: var Database) =
  if db.handle.pointer != nil:
    discard sqlite3_close(db.handle)

# C callback wrapping
type
  EventCallback = proc (data: pointer) {.cdecl.}

proc c_register_callback(cb: EventCallback, data: pointer)
  {.importc: "register_callback", header: "events.h".}

proc nimCallback(data: pointer) {.cdecl.} =
  echo "Callback triggered"

proc registerEvent() =
  c_register_callback(nimCallback, nil)

Wrappers provide Nim-idiomatic interfaces while preserving C library functionality.

Exporting to C

Export Nim functions to C using exportc pragma for library creation.

# Basic export
proc add(a, b: cint): cint {.exportc.} =
  a + b

# Export with specific name
proc multiply(a, b: cint): cint {.exportc: "nim_multiply".} =
  a * b

# Export with dynlib
proc divide(a, b: cint): cint {.exportc, dynlib.} =
  if b == 0: return 0
  a div b

# Export complex types
type
  Point {.exportc.} = object
    x: cint
    y: cint

proc createPoint(x, y: cint): Point {.exportc.} =
  Point(x: x, y: y)

proc pointDistance(p1, p2: Point): cdouble {.exportc.} =
  let dx = (p2.x - p1.x).float
  let dy = (p2.y - p1.y).float
  sqrt(dx * dx + dy * dy)

# Export string operations
proc processString(input: cstring): cstring {.exportc.} =
  let s = $input
  result = cstring(s.toUpperAscii())

# Generating header file
{.emit: """/*TYPESECTION*/
typedef struct {
  int x;
  int y;
} Point;
""".}

proc generateHeader() {.exportc: "lib_init".} =
  echo "Library initialized"

# Export callbacks
type
  Callback = proc (value: cint) {.cdecl.}

proc registerCallback(cb: Callback) {.exportc.} =
  cb(42)

# Building shared library
# Compile with: nim c --app:lib --noMain mylib.nim

# Library initialization
proc NimMain() {.importc.}

proc libInit() {.exportc: "lib_init".} =
  NimMain()
  echo "Nim library initialized"

# Export with error handling
proc safeOperation(value: cint): cint {.exportc.} =
  try:
    if value < 0:
      raise newException(ValueError, "Negative value")
    result = value * 2
  except:
    result = -1

Exportc enables creating C-compatible libraries from Nim code.

Memory Layout and Alignment

Control memory layout for C struct compatibility and performance.

# Packed structures
type
  PackedStruct {.packed.} = object
    a: uint8
    b: uint32
    c: uint8

echo sizeof(PackedStruct)  # 6 bytes (no padding)

# Aligned structures
type
  AlignedStruct {.align(16).} = object
    data: array[4, float32]

echo sizeof(AlignedStruct)  # Aligned to 16 bytes

# C struct layout
type
  CStruct {.importc, header: "myheader.h".} = object
    field1: cint
    field2: cdouble
    field3: cstring

# Union types
type
  Union {.union.} = object
    intValue: cint
    floatValue: cfloat
    bytes: array[4, uint8]

proc accessUnion() =
  var u: Union
  u.intValue = 0x12345678
  echo u.bytes[0].toHex

# Bit fields (via packed)
type
  BitField {.packed.} = object
    flag1: uint8  # Use 1 byte per field
    flag2: uint8
    value: uint16

# Padding control
type
  ControlledPadding = object
    a: uint8
    pad1 {.align(4).}: array[3, uint8]
    b: uint32

# Calculating offsets
proc fieldOffset() =
  type T = object
    a: int32
    b: int64

  echo offsetOf(T, a)  # 0
  echo offsetOf(T, b)  # 8 (with padding)

# C array mapping
type
  CArray = object
    data: ptr UncheckedArray[cint]
    len: csize_t

proc accessCArray(arr: CArray) =
  for i in 0..<arr.len:
    echo arr.data[i]

# Flexible array member
type
  FlexArray = object
    length: cint
    data: UncheckedArray[cint]

proc createFlexArray(size: int): ptr FlexArray =
  let totalSize = sizeof(cint) + size * sizeof(cint)
  result = cast[ptr FlexArray](alloc(totalSize))
  result.length = cint(size)

Memory layout control ensures C compatibility and optimal performance.

FFI Patterns and Safety

Common patterns for safe foreign function interface usage.

# Safe string conversion
proc safeToString(cs: cstring): string =
  if cs == nil:
    return ""
  result = $cs

# Handling C errors
type
  CError = object
    code: cint
    message: cstring

proc checkError(err: CError) =
  if err.code != 0:
    raise newException(Exception, $err.message)

# Resource management
type
  Resource = object
    handle: pointer

proc acquire(): Resource =
  result.handle = malloc(1024)

proc `=destroy`(r: var Resource) =
  if r.handle != nil:
    free(r.handle)
    r.handle = nil

# Callback with closure
type
  ClosureCallback = object
    fn: proc (data: pointer) {.cdecl.}
    data: pointer

var globalClosure: ref tuple[callback: proc()]

proc wrapCallback(callback: proc()) =
  globalClosure = new(tuple[callback: proc()])
  globalClosure.callback = callback

  proc cCallback(data: pointer) {.cdecl.} =
    globalClosure.callback()

  # Register cCallback with C library

# Opaque types
type
  OpaqueHandle {.importc, header: "lib.h".} = object

proc createHandle(): ptr OpaqueHandle
  {.importc, header: "lib.h".}

proc destroyHandle(h: ptr OpaqueHandle)
  {.importc, header: "lib.h".}

# Version checking
when sizeof(clong) == 8:
  type CLong = int64
else:
  type CLong = int32

# Platform-specific code
when defined(windows):
  proc windowsFunc() {.importc, dynlib: "kernel32.dll".}
elif defined(posix):
  proc posixFunc() {.importc, header: "<unistd.h>".}

Safe FFI patterns prevent common C interop errors and resource leaks.

Best Practices

  1. Use distinct types for C handles to prevent mixing different handle types
  2. Implement destructors for wrapped resources to ensure cleanup
  3. Check for nil when receiving pointers from C code
  4. Use cstring carefully as Nim strings and C strings have different lifetimes
  5. Wrap C APIs with Nim-idiomatic interfaces rather than exposing C directly
  6. Test interop code thoroughly as type mismatches cause runtime errors
  7. Use const for read-only C parameters to prevent accidental modification
  8. Generate headers when exporting to make C integration easier
  9. Handle C errors explicitly and convert to Nim exceptions
  10. Document memory ownership for functions passing pointers between Nim and C

Common Pitfalls

  1. Not preserving string lifetime when passing Nim strings to C causes corruption
  2. Forgetting to link C libraries with passL causes undefined symbol errors
  3. Mismatching calling conventions (cdecl vs stdcall) causes stack corruption
  4. Not handling nil pointers from C causes segmentation faults
  5. Incorrect memory layout for C structs causes data corruption
  6. Using GC types in C callbacks causes crashes as GC may move objects
  7. Not checking C return values misses error conditions
  8. Mixing Nim and C memory management causes double-free or leaks
  9. Assuming C struct padding matches Nim without packed pragma
  10. Not testing on target platform misses platform-specific issues

When to Use This Skill

Apply C interop when wrapping existing C libraries for Nim projects.

Use importc to leverage battle-tested C code without reimplementation.

Export Nim functions to create libraries usable from C applications.

Integrate with system APIs only available through C interfaces.

Optimize hot paths by calling optimized C implementations.

Build upon C ecosystems while writing higher-level Nim code.

Resources

平台分布

OpenCode

26.51%
按下载量换算967

Codex

23.2%
按下载量换算846

Claude Code

19.23%
按下载量换算701

windsurf

11.78%
按下载量换算429

Cursor

7.24%
按下载量换算264

Antigravity

3.91%
按下载量换算143

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

继续浏览同类 Skills