Exportando DLL de classe C ++, pergunta sobre arquivo.def
-
06-07-2019 - |
Pergunta
Eu quero usar vinculação implícita no meu projeto, e nmake realmente quer um arquivo .def. O problema é que esta é uma classe, e eu não sei o que escrever na seção exportações. Poderia alguém me aponte na direção certa?
A mensagem de erro é o seguinte:
NMAKE: U1073: não sei como fazer 'DLLCLASS.def'
P.S:. Eu estou tentando construir usando o Windows CE Platform Builder
Solução
Você sempre pode encontrar o nome decorado para a função de membro usando dumpbin / símbolos myclass.obj
no meu caso
class A {
public:
A( int ){}
};
o despejo dumpbin
mostrou o símbolo ??0A@@QAE@H@Z (public: __thiscall A::A(int))
Colocar este símbolo no arquivo .def faz com que o vinculador para criar o :: A (int) símbolo A nos símbolos de exportação.
MAS como estados @paercebal em seu comentário:!. A entrada manual de nomes decorados (mutilados) é uma tarefa - propenso a erros, e infelizmente, não guarenteed para ser portátil entre versões do compilador
Outras dicas
Se bem me lembro, você pode usar __declspec(dllexport)
no class , e VC ++ irá criar automaticamente as exportações para todos os símbolos relacionados com a classe (construtores / destructor, métodos, vtable, typeinfo, etc) .
A Microsoft tem mais informações sobre este aqui .
Eu encontrei o melhor caminho a ser uma fábrica abstrata.
Comece por definir uma classe base puramente virtual. Esta é uma classe sem implementação, uma classe de interface puramente virtual.
Você pode exportar esta base virtual classe "interface abstrata", mas não há nenhuma razão real para fazê-lo. Quando o chamador usa-lo, eles vão estar a usá-lo através de um ponteiro (Pimpl, ou Ponteiro para Implementação) então tudo o chamador conhece é um endereço de memória simples. Um arquivo Def, enquanto um teensy pouco mais de trabalho para acompanhar, oferece benefícios além do que __declspec (dllexport) pode atingir. Quais os benefícios, você pergunta? Nós vamos chegar a isso, você só esperar.
Tenha sua verdadeira classe herdar publicamente a partir da base virtual. Agora criar um método de fábrica para construir o seu objeto e um " versão " destructor exigível ish para executar a limpeza. Nomear esses métodos algo como " ConstructMyClass " e " ReleaseMyClass ". Por favor, por favor substituir " MyClass ": -)
Esses métodos fábrica / liberação deve tomar apenas tipos POD se eles precisam de nenhum paramaters (plain-old-dados: inteiros, carvão animal, etc.). O tipo de retorno deve ser a sua classe base interface abstrata virtual -. Ou melhor, um ponteiro para ele
IMyClass * CreateAnObjectOfTypeIMyClass ();
Talvez agora é óbvio porque precisamos da classe base virtual? Como a classe interface virtual não tem nenhuma implementação, é essencialmente todos os tipos POD (espécie de) para que o "tipo de dados" da classe pode ser entendido pela maioria dos chamadores, como Visual Basic, C ou muito diferentes compiladores C ++.
Se você é suficientemente fantasia, você pode contornar a necessidade de um " desbloqueio manual " método (desculpe, tinha que fazê-lo). Quão? Gerenciar seus próprios recursos na classe através de smart-ponteiros e um tipo Pimpl da arquitetura por isso, quando as matrizes de objetos, ele irá limpar depois de si mesmo. Fazer isso significa que a sua classe é, nas palavras imortais de nosso santo e salvador Scott Meyers , " fácil de usar corretamente e difícil de usar incorretamente " deixando o desrespeito chamador a necessidade de limpar. Que aqueles entre nós que nunca esqueci a chamada " .close " atire a primeira pedra.
Talvez essa arquitetura soa familiar? Ele deveria, é basicamente uma versão micromachine do COM. Bem, espécie de, pelo menos, o conceito de interface, fábrica construção e lançamento.
No final, você tiver exportado a interface para sua classe, fez (e exportados) Criar e Destruir métodos, e agora os chamadores podem invocar o seu PleaseConstructMyClass função de fábrica para ter o seu DLL retornar um objeto completamente construídos, completamente implementada e totalmente cozido sob o disfarce de sua interface. Eles podem ligar para todos os métodos públicos de sua classe (pelo menos os que em sua interface virtual abstrato) e fazer todas as coisas divertidas.
Quando terminarem com o objeto que foi devolvido pela função de fábrica, então eles podem chamar um " ReleaseMyClass " função de pedir ao seu DLL para limpar recursos do objeto, ou você pode ajudá-los junto, fazendo a sua classe de limpeza em si, tornando o " ReleaseMyClass " método redundante e inútil.
Se alguém está interessado nos ganhos e compensações específicas para o uso do arquivo Def ea interface (além de minha cega say-so), por favor tubulação-se e podemos cavar mais fundo.
Não basta você amar este material?
A solução é o seguinte:
-
desde uma classe é exportada, você também precisa adicionar os métodos exportados no arquivo .def
-
Eu não consegui descobrir como exportar um construtor, então eu fui com o uso de um método de fábrica (estática), que retornará novas instâncias de um objeto
-
as outras funções serão exportados adicionando declaração exportação normal no arquivo.def
Hope alguém vai beneficiar com esta informação.