Crystal库能否以静态方式链接到C语言中?

20

我已经阅读了教程中的"C绑定"部分,但我对C方面还是新手。

请问能否将Crystal程序构建为静态库来链接,如果可以,是否可以提供一个简单的示例?

1个回答

29

是的,但不建议这样做。Crystal 依赖于垃圾回收器(GC),这使得生成共享(或静态)库变得不太理想。因此,也没有语法级别的结构来帮助创建这种库,也没有简单的编译器调用来实现它。文档中的 C 绑定部分是关于将用 C 编写的库提供给 Crystal 程序使用的。

无论如何,这里有一个简单的示例:

logger.cr

fun init = crystal_init : Void
  # We need to initialize the GC
  GC.init

  # We need to invoke Crystal's "main" function, the one that initializes
  # all constants and runs the top-level code (none in this case, but without
  # constants like STDOUT and others the last line will crash).
  # We pass 0 and null to argc and argv.
  LibCrystalMain.__crystal_main(0, Pointer(Pointer(UInt8)).null)
end

fun log = crystal_log(text: UInt8*): Void
  puts String.new(text)
end

logger.h

#ifndef _CRYSTAL_LOGGER_H
#define _CRYSTAL_LOGGER_H

void crystal_init(void);
void crystal_log(char* text);
#endif

主函数.c

#include "logger.h"

int main(void) {
  crystal_init();
  crystal_log("Hello world!");
}

我们可以创建一个共享库。

crystal build --single-module --link-flags="-shared" -o liblogger.so

或者是一个静态库

crystal build logger.cr --single-module --emit obj
rm logger # we're not interested in the executable
strip -N main logger.o # Drop duplicated main from the object file
ar rcs liblogger.a logger.o

让我们确认我们的函数已被包含

nm liblogger.so | grep crystal_
nm liblogger.a | grep crystal_

好了,是时候编译我们的 C 程序了。

# Folder where we can store either liblogger.so or liblogger.a but
# not both at the same time, so we can sure to use the right one
rm -rf lib
mkdir lib
cp liblogger.so lib
gcc main.c -o dynamic_main -Llib -llogger
LD_LIBRARY_PATH="lib" ./dynamic_main

或者静态版本

# Folder where we can store either liblogger.so or liblogger.a but
# not both at the same time, so we can sure to use the right one
rm -rf lib
mkdir lib
cp liblogger.a lib
gcc main.c -o static_main -Llib -levent -ldl -lpcl -lpcre -lgc -llogger
./static_main

在很大程度上受到https://gist.github.com/3bd3aadd71db206e828f的启发


非常感谢!这是一个程序中的单个实用工具,只被调用一次,因此交互很少。它实际上是从 Nim 转移而来,由 Go 程序调用。如果这部分成功了,我可能也会将 Go 程序转移到 Crystal,但在此期间这将起作用。再次感谢! - Lye Fish
你已经在Lye中涵盖了所有新一代的系统编程语言,只需要加入一些Rust,你就拥有了整个集合。哈哈,不过话说回来,@Jonne Haß,总结得非常好。 - Shayne
@Jonne Haß:在OSX上,“strip”的“-N”标志是不正确的(可能是因为BSD)。您知道OSX的等效物是什么吗? - andrewdotnich
@LyeFish为什么不加上V呢? - iconoclast

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接