Подтвердить что ты не робот

Может ли библиотека Crystal быть статически связана с C?

Я прочитал "C-привязки" в учебнике, но я новичок в материалах C.

Может кто-нибудь, пожалуйста, сообщите мне, может ли программа Crystal быть построена как статическая библиотека для ссылки, и если бы вы могли бы предоставить простой пример?

4b9b3361

Ответ 1

Да, но это не рекомендуется делать. Кристалл зависит от GC, который делает менее желательным создание общих (или статических) библиотек. Таким образом, также нет конструкций синтаксического уровня, которые могли бы помочь в создании такого или простого вызова компилятора для этого. Раздел C привязок в документации касается создания библиотек, написанных на C, доступными для программ Crystal.

Вот простой пример:

logger.cr

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

  # We need to invoke Crystal "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

main.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