общая библиотека в C - PullRequest
2 голосов
/ 26 мая 2010

Я создаю разделяемую библиотеку в C, но не знаю, как правильно реализовать исходные коды.

Я хочу создать API, например, printHello,

int printHello( char * text );

Эта функция printHello вызовет другую функцию:

В исходном файле libprinthello.c,

void printHello( char * text )
{
   printHi();
   printf("%s", text);
}

Поскольку эта функция printHello является интерфейсом для пользователя или приложения:

В заголовочном файле libprinthello.h,

extern void printHello( char * text);

Затем в исходном файле функции printHi printhi.c

void printHi()
{
   printf("Hi\n");
}

Тогда моя проблема в том, что printHello - единственная функция, которую я хочу показать пользователю, какую реализацию я должен сделать в функции printHi?

Должен ли я также выйти за пределы объявления функции printHi?

Ответы [ 4 ]

5 голосов
/ 26 мая 2010

Вы можете использовать два отдельных заголовочных файла:

В libprinthello.h:

#ifndef LIBPRINTHELLO_H /* These are include guards */
#define LIBPRINTHELLO_H

void printHello(char * text); 

#endif

В libprinthi.h:

#ifndef LIBPRINTHI_H
#define LIBPRINTHI_H

void printHi();

#endif

In libprinthello.c:

#include "libprinthi.h"
#include "libprinthello.h"

void printHello(char * text)  
{  
    printHi();  
    printf("%s", text);  
}  

В libprinthi.c:

#include "libprinthi.h"

void printHi()    
{    
    printf("Hi\n");    
}    

Тогда код пользователя включает только libprinthello.h, и вы держите libprinthi.h подальше от пользователя, делая printHi() невидимым для него (код пользователя также связывается с общей библиотекой):

#include "libprinthello.h"

int main()
{
    printHello("Hello World!\n");
    return 0;
}
3 голосов
/ 26 мая 2010

Если вы поместите определение printHi в libprinthello.c, Вы можете просто объявить это статическим, и это будет только быть доступным для других функций, определенных в этом тот же файл. Если вы хотите поместить определение в его собственный переводчик не существует портативного способа сделать это скрыто для пользователей библиотеки, но вы можете скрыть это в реализации конкретных способов. За Например, с GCC вы можете использовать __attribute __ ((видимость ( "скрытый"))). Тем не менее, просто оставив декларацию из публичный заголовочный файл должен быть достаточным для пользователи библиотеки от использования функции.

1 голос
/ 26 мая 2010

Рассмотрим этот файл (Export_Macro.h)

#ifndef EXPORT_MACRO_H
#define EXPORT_MACRO_H

#ifdef _WINDOWS
    #ifdef I_WANT_TO_EXPORT_MACROS
        #define EXPORT_MACRO __declspec(dllexport)
    #else
        #define EXPORT_MACRO __declspec(dllimport)
    #endif
#else
    #define EXPORT_MACRO
#endif

#endif // EXPORT_MACRO_H

В исходном коде сделайте это:

#include "Export_Macro.h"
...
// for functions you want to export outside the DLL (Dynamic Link Library)/so (Shared Object)
EXPORT_MACRO void printHello( char * text);

Это хорошо работает для меня.

Более полное объяснение и макрос экспорта вы можете найти здесь .

Позднее редактирование: Это должно работать в Unix и Windows без особых проблем.

1 голос
/ 26 мая 2010

В идеале, если вы не хотите, чтобы пользователи вызывали функцию printHi(), она не должна быть им видна. Если это невозможно, используйте соглашение, чтобы указать, какие имена предназначены для вызова пользователем, а какие нет. Классически это делается с помощью подчеркивания, но это может привести к различным конфликтам. Итак, если у вас есть соглашение об именах для вашей библиотеки, вы можете использовать pfx_GlobalName() для документированных, вызываемых пользователем функций и pfxInternalName() для недокументированных функций, или наоборот, или какое-то слегка похожее соглашение. Затем вы можете просто сказать пользователям, что прямые вызовы недокументированных функций не поддерживаются, и любое их использование может быть прервано в будущем выпуске (или функция может быть переименована или как угодно). И иногда вносите изменения, чтобы было ясно, что вы имеете в виду то, что говорите.

Итак, если скрытая функция может поместиться в том же модуле исходного кода, что и публичные функции, которые задокументированы, действительно скрывайте их. Если вы не можете, используйте соглашение об именах, чтобы указать, что скрытые функции не предназначены для конечного пользователя.

Вы можете контролировать видимость символов с помощью карт символов и вещей с помощью GCC; хотя это неоправданно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...