简体   繁体   中英

shared library in C

I am creating a shared library in C but don't know what is the correct implementation of the source codes.

I want to create an API like for example, printHello,

int printHello( char * text );

This printHello function will call another function:

In source file, libprinthello.c,

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

Since this printHello function is the interface for the user or application:

In header file libprinthello.h,

extern void printHello( char * text);

Then in the source file of the printHi function, printhi.c

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

Then my problem is, since printHello is the only function that I want to expose in the user, what implementation should I do in printHi function?

Should I also extern the declaration of the printHi function?

You can use two separate header files:

In libprinthello.h :

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

void printHello(char * text); 

#endif

In 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);  
}  

In libprinthi.c :

#include "libprinthi.h"

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

Then the user code includes only libprinthello.h , and you keep libprinthi.h away from the user, making printHi() invisible to them (the user code would also link against the shared library):

#include "libprinthello.h"

int main()
{
    printHello("Hello World!\n");
    return 0;
}

If you put the definition of printHi in libprinthello.c, you can simply declare it static and it will only be accessible to the other functions defined in that same file. If you want to put the definition in its own translation unit there is no portable way to make it hidden to users of the library, but you can hide it in implementation specific ways. For example, with gcc you can use __attribute__((visibility("hidden"))). However, simply leaving the declaration out of the public header file should be sufficient to keep users of the library from using the function.

Ideally, if you don't want users calling the printHi() function, it should not be visible to them. If that's not feasible, use a convention to indicate which names are intended to be called by the user and which are not. Classically, that is done with leading underscores, but that can lead to various conflicts. So, if you have a naming convention for your library, you might use pfx_GlobalName() for documented, user-callable functions and pfxInternalName() for undocumented functions, or the reverse, or some faintly similar convention. You can then simply tell users that direct calls to the undocumented functions are not supported and any use of them is liable to break at a future release (or the function may be renamed or whatever). And occasionally make changes to make it clear that you mean what you say.

So, if the hidden function can fit in the same source module as the public functions that are documented, do hide them. If you can't, use a naming convention to indicate that the hidden functions are not for end-user use.

You can control the visibility of symbols with symbol maps and things with GCC; it is fiddly, though.

Consider this file (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

In your source code do this:

#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);

This works for me pretty well.

A more complete explanation and export macro you can find here .

Later edit: This should work in Unix and Windows without any big problems.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM