2010-05-24 36 views
6

Tôi cần cung cấp thư viện tĩnh C cho ứng dụng khách và cần có khả năng xác định cấu trúc không có sẵn. Ngày đầu đó tôi cần để có thể thực thi mã trước khi chính tại khởi tạo thư viện bằng cách sử dụng một biến toàn cầu.Ẩn định nghĩa cấu trúc trong thư viện tĩnh

Dưới đây là mã của tôi:

private.h 


#ifndef PRIVATE_H 
#define PRIVATE_H 

typedef struct TEST test; 

#endif 


private.c (this should end up in a static library) 

#include "private.h" 
#include <stdio.h> 

struct TEST 
{ 
TEST() 
{ 
    printf("Execute before main and have to be unavailable to the user.\n"); 
} 

int a; // Can be modified by the user 
int b; // Can be modified by the user 
int c; // Can be modified by the user 

} TEST; 


main.c 

test t; 

int main(void) 
{ 
t.a = 0; 
t.b = 0; 
t.c = 0; 

return 0; 
} 

Rõ ràng mã này không hoạt động ... nhưng hiển thị những gì tôi cần phải làm ... Bất kỳ ai biết làm thế nào để làm cho công việc này? Tôi google khá một chút nhưng không thể tìm thấy một câu trả lời, bất kỳ trợ giúp sẽ được đánh giá rất nhiều.

TIA!

Trả lời

7

Nếu bạn đang sử dụng gcc bạn có thể sử dụng thuộc tính constructor,

void runs_before_main(void) __attribute__((constructor)) 
{ 
    ... 
} 

Từ các tài liệu gcc

Thuộc tính constructor làm cho chức năng để tự động được gọi be- thực hiện fore vào main(). Tương tự, thuộc tính destructor làm cho chức năng được gọi là tự động sau khi main() có hoàn thành hoặc thoát() đã được gọi. Các chức năng với các thuộc tính này là hữu ích cho việc khởi tạo dữ liệu sẽ được sử dụng ngầm trong khi thực hiện chương trình .

Bạn có thể cung cấp số nguyên tùy chọn để kiểm soát thứ tự trong đó hàm tạo và hàm hủy được chạy. Một hàm tạo có số ưu tiên nhỏ hơn chạy trước một hàm tạo với mức ưu tiên lớn hơn số; mối quan hệ ngược lại giữ cho người hủy. Vì vậy, nếu bạn có một hàm tạo phân bổ một tài nguyên và một destructor mà deallocates cùng một tài nguyên, cả hai hàm thường có cùng mức ưu tiên . Các ưu tiên cho constructor và destructor chức năng cũng giống như những quy định cho namespace-phạm vi C++ đối tượng

Nếu bạn muốn ẩn một struct từ người sử dụng, khai báo struct trong một tiêu đề nhưng định nghĩa nó trong c tập tin, đi qua xung quanh con trỏ. Ví dụ:

// foo.h 
typedef struct private_foo foo; 
foo * create_foo(void); 
void free_foo(foo * f); 

// foo.c 
struct private_foo { 
    int i; 
} 
foo * create_foo(void){ 
    foo * f = malloc(sizeof(*foo)); 
    if (f) f->i = 1; 
    return f; 
} 
... 

foo->i sau đó không thể truy cập được bên ngoài foo.c.

3

Nếu bạn muốn mã máy khách có thể sử dụng "t.a = ...", thì bạn không thể ẩn định nghĩa cấu trúc. Những gì bạn muốn được gọi là loại đục, trông giống như sau:

 
public.h: 
struct foo; 
set_a(struct foo *, int); 
struct foo * new_foo(void); 

main.c: 
#include <public.h> 
int main(void) 
{ 
    struct foo *k; 
    k = new_foo(); 
    set_a(k, 5); 
} 

Định nghĩa cấu trúc chỉ khả dụng cho thư viện. Nếu bạn không làm cho mã nguồn thư viện có sẵn, nó có thể ẩn hoàn toàn nó khỏi người dùng của thư viện.

2

Không có cách di động nào trong C để đảm bảo mã của bạn sẽ chạy trước main().Những gì tôi sẽ làm chỉ là duy trì một lá cờ initialised trong thư viện của bạn, được đặt thành false và sau đó từ chối thực hiện bất kỳ điều gì cho đến khi hàm init của bạn được gọi.

Như trong:

static int initialised = 0; 

int init (void) { 
    // do something. 
    initialised = 1; 
    return ERR_OK; 
} 

int all_other_functions (void) { 
    if (!init) 
     return ERR_NOT_INITED; 

    // do something. 
    return ERR_OK; 
} 
+0

Sử dụng một loại không đầy đủ cho tay cầm cho phép trình biên dịch để bắt lỗi loại, và tránh đúc trong các chức năng thực hiện. –

+0

Trình biên dịch có thể _still_ bắt lỗi loại do mã thư viện của bạn hoạt động với biến được nhập chính xác. Hoặc, nếu bạn thực sự có nghĩa là loại sai được trao cho chức năng của bạn, đó là một lỗi người dùng và họ xứng đáng với tất cả những khó khăn nó sẽ mang lại :-) Như tôi đã nói, đó là _one_ cách để làm điều đó, không phải là cách duy nhất. – paxdiablo

+0

Tại sao trên trái đất sẽ sử dụng void * và mất tất cả các loại kiểm tra? typedef struct MyHiddenStruct MyHandle; MyHandle * allocHandle(); –

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