Pergunta

Ei caras eu tenho algumas perguntas rápidas sobre Windows DLL.

Basicamente eu estou usando os IFDEFs para lidar com o dllexport e dllimport, a minha pergunta é, na verdade, sobre a colocação dos dllexports e dllimports, bem como palavra-chave externo.

Estou colocando os dllimports / dllexports sobre os arquivos de cabeçalho, mas eu tenho que colocar o dllexport e dllimports na definição actualy?

E para typedefs?

faço para colocar o dllimport / dllexport na frente? como em

dllexport typedef map<string, int> st_map

Ainda sobre a palavra-chave extern eu já vi isso sendo usado como este:

extern "C" {

dllexport void func1();

}

Eu também vi isso sendo usado como este:

extern dllexport func1();

Um inclui o "C" e o outro não, a minha pergunta é qual é a diferença e eu preciso usá-lo? Se eu fizer, então eu usá-lo tanto para dllexport e dllimport também que eu tenho que usá-lo em ambas as declarações do arquivo de cabeçalho e as definições?

Meu projeto vai ser biblioteca compartilhada, que contém vários arquivos de classe que eu quero exportação, alguns typdefs eu quero exportação e algumas funções globais que também deseja exportar tudo em uma dll.

Qualquer um me esclareça, por favor?

EDIT:

Ok eu pensei que eu vou postar um pequeno extrato do que eu fiz, também aviso que estou construindo a biblioteca para Linux e Windows, então eu fazer uma verificação para isso:

mydll.h

#ifdef WINDOWS
#   ifdef PSTRUCT_EXPORT
#   define WINLIB __declspec(dllexport)
#   else
#   define WINLIB __declspec(dllimport)
#   endif
#else
#  define WINLIB
#endif

WINLIB void funct1();

Agora, no código fonte:

mydll.cpp

#define PSTRUCT_EXPORT

void funct1() <---- do i need to add WINLIB in front of it? 
                      Or is doing it in the header enough?
Foi útil?

Solução

Primeiro, você não precisa typedefs de importação ou exportação. Enquanto eles estão nos arquivos de cabeçalho que ambos os lados usar, você é bom. Você precisa fazer para funções de importação / exportação e definições de classe.

Provavelmente, você usar os mesmos arquivos de cabeçalho, tanto para a importação e exportação de código, para que você pudesse fazer alguma mágica makefile para definir uma macro pré-processador em cada lado, em seguida, fazer algo como isto:

#if defined( LIBRARY_CODE )
#define MYAPI __declspec(dllexport)
#else
#define MYAPI __declspec(dllimport)
#endif

extern MYAPI void func1();
class MYAPI MyClass {
    ...
};

No que diz respeito funções C vs C ++, você pode fazer isso:

#if defined( __cplusplus__ ) // always defined by C++ compilers, never by C
#define _croutine "C"
#else
#define _croutine
#endif

extern _croutine void function_with_c_linkage();

Certifique-se de importar este arquivo de cabeçalho do seu arquivo de origem C ++ (que contém a implementação desta função) ou o compilador não saberá dar-lhe C ligação.

Outras dicas

  1. typedefs não precisa de um dllimport / dllexport, é apenas uma definição
  2. dllimport / dllexport não são padrão, pense de definir uma macro para outras plataformas / compiladores
  3. também cuidar da convenção de chamada (cdecl, stdcall, ...) usado caso contrário você vai correr em problemas (se você precisa para ser interoperável com stdcall usar o Visual Basic)
  4. enclose dentro extern "C" para que seu lib pode ser usado de dentro programas C ++, use #ifdef __cplusplus para mantê-lo visível apenas para C ++.

Tenha um olhar em diferentes libs OpenSource. Lá você vai encontrar muitos exemplos de como fazer um bom cabeçalho da biblioteca. Não poderia haver problemas com a decoração de nome no caso do C ++ sem o externo "C".

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top