2015-10-02 17 views
17

Tôi đã đọc qua "ràng buộc C" trong hướng dẫn nhưng tôi là người mới làm quen với nội dung C.Thư viện Crystal có thể được liên kết tĩnh với C không?

Có thể ai đó vui lòng cho tôi biết nếu một chương trình Crystal có thể được xây dựng như một thư viện tĩnh để liên kết tới và nếu bạn có thể vui lòng cung cấp một ví dụ đơn giản?

Trả lời

22

Có, nhưng không nên làm như vậy. Tinh thể phụ thuộc vào một GC làm cho nó ít hấp dẫn hơn để tạo ra các thư viện được chia sẻ (hoặc tĩnh). Vì vậy, cũng không có cấu trúc mức cú pháp để hỗ trợ trong việc tạo ra như vậy cũng như một lời gọi trình biên dịch đơn giản để làm như vậy. Phần C bindings trong tài liệu hướng dẫn là tạo các thư viện được viết bằng C cho các chương trình Crystal.

Dưới đây là một ví dụ đơn giản dù sao đi nữa:

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 

main.c

#include "logger.h" 

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

Chúng tôi có thể tạo ra một thư viện chia sẻ với

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

Hoặc một thư viện tĩnh với

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 

Hãy xác nhận chức năng của chúng tôi đã bao gồm

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

Được rồi, thời gian để biên dịch C của chúng tôi chương trình

# 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 

Hoặc phiên bản tĩnh

# 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 

Với nhiều cảm hứng từ https://gist.github.com/3bd3aadd71db206e828f

+0

Cảm ơn rất nhiều! Đây là một tiện ích duy nhất nhưng lớn hơn trong một chương trình được gọi chỉ một lần, do đó, có tương tác tối thiểu. Nó thực sự được gọi từ một chương trình * Go * và tiện ích đang được chuyển từ * Nim *. Nếu phần này hoạt động, tôi có khả năng sẽ chuyển chương trình * Go * sang * Crystal * nhưng điều này sẽ hoạt động trong thời gian chờ đợi. Cảm ơn một lần nữa! –

+0

Bạn đã có tất cả các ngôn ngữ lập trình hệ thống giống mới được đề cập trong Lye đó, tất cả những gì bạn cần là một số Rust và bạn có toàn bộ bộ sưu tập lol. Dù sao @ Jonne Haß, tóm tắt tuyệt vời. – Shayne

+0

@Jonne Haß: cờ '-N' tới' dải' không chính xác trên OSX (có thể do BSD.) Bạn có biết tương đương OSX là gì không? – andrewdotnich

Các vấn đề liên quan