Bạn có thể xác định chức năng tải cho thư viện linux bằng cơ chế .init
. Điều này giống với việc chỉ định điểm nhập thời gian tải cho một tệp nhị phân (ví dụ: sử dụng thứ gì đó khác với điểm chính làm điểm nhập cho chương trình).
Khi liên kết sử dụng ld
trực tiếp bạn sử dụng:
-init <function name>
hoặc nếu bạn đang sử dụng cc/gcc để liên kết, bạn sử dụng:
-Wl,-init,<function name>
Đây là lúc đó là mức độ đơn giản nhất.
Chỉnh sửa Đối với trình phá hủy/finalizers, bạn sử dụng cơ chế .fini
. Điều này hoạt động theo cách tương tự như tùy chọn init và bạn sử dụng:
-fini <function name>
khi gọi ld
. Tính khả dụng được giới hạn ở tùy chọn -init
trên nền tảng Mac OSX.
Bạn cũng sẽ có thể sử dụng cú pháp __attribute__((constructor))
cho gcc:
static void con() __attribute__((constructor));
void con() {
printf("I'm a constructor\n");
}
Mà có lẽ là một cách cầm tay hơn là chỉnh với các tùy chọn liên kết. Tất cả các nhà xây dựng nên được gọi vào thời gian tải, nhưng không phụ thuộc vào thứ tự khởi tạo của chúng, dẫn đến các lỗi điên rồ và không thể sản xuất mà tốn thời gian và công sức để gỡ lỗi.
Chỉnh sửa 2 Việc sử dụng ngữ nghĩa __attribute__((constructor))/__attribute__((destructor))
là cơ chế thích hợp nhất cho ngôn ngữ lập trình C/C++.
Đối với ngôn ngữ D
lập trình bạn thực sự cần sử dụng tĩnh mô-đun constructor/destructor:
static this() {
printf("static this for mymodule\n");
}
static ~this() {
printf("static ~this for mymodule\n");
}
Hoặc lớp constructor tĩnh:
class Foo {
static this() {
printf("static this for Foo\n");
}
}
này được ám chỉ mạnh mẽ ở trong writing win32 DLLS và trong đặc tả ngôn ngữ relating to static constructors/destructors.
Chỉnh sửa 3 Bạn sẽ cần liên kết trong một .o
để xuất các hàm khởi tạo/phá hủy, sẽ cho phép sử dụng trình khởi tạo tĩnh. Như tất cả những gì cần làm là gọi Runtime.initialize(), điều này thực sự gọi tất cả các hàm tạo/các hàm hủy tĩnh trong mã D
.
Stub d mã cho initializer (trong một tập tin gọi là myshared.d
):
import core.runtime;
extern (C) {
void attach();
void detach();
}
export void attach() {
Runtime.initialize();
}
export void detach() {
Runtime.terminate();
}
Tạo .o cho cuống này:
dmd -m32 -c myshared.d
Kiểm tra tên của các đính kèm/tách chức năng:
nm myshared.o
Hiển thị (trong số các đầu ra khác):
0000001c S _D8myshared6attachFZv
00000034 S _D8myshared6detachFZv
mẫu mã c cho cách gọi này (gọi tắt là export.c trong trường hợp này), chúng tôi tham khảo các tên của các thói quen xuất khẩu từ my shared.o
file:
extern void D8myshared6attachFZv(void);
extern void D8myshared6detachFZv(void);
void __attach(void) __attribute__((constructor));
void __detach(void) __attribute__((destructor));
void __attach(void)
{
D8myshared6attachFZv();
}
void __detach(void)
{
D8myshared6detachFZv();
}
Lưu ý rằng các tài liệu tham khảo extern void
cần sử dụng tên bị xé của hàm được xuất. Các thẻ này phải khớp hoặc mã sẽ không liên kết.
biên dịch mã C sử dụng:
gcc -m32 -c export.c
liên kết .c.o và các tập tin .d.o cùng nhau sử dụng:
cc -o libmyshared.dylib -m32 -shared myshared.o export.o -lphobos2
Giả sử rằng các thư viện phobos2 là trong con đường tìm kiếm mối liên kết tiêu chuẩn của bạn. Các smatterings của -m32
tùy chọn cho trình biên dịch và liên kết là bởi vì phiên bản của trình biên dịch D mà tôi xây dựng tại địa phương chỉ hỗ trợ 32bit.
Điều này tạo ra .dylib có thể liên kết đến. Dường như nó hoạt động dựa trên thử nghiệm giới hạn mà tôi đã thực hiện. Dường như hỗ trợ cho các đối tượng được chia sẻ/thư viện động rất hạn chế, do đó, có một cơ hội tốt là sẽ có một trở ngại khác cần khắc phục.
https://stackoverflow.com/q/2053029/4361073 – parasrish