Pergunta

Eu estou trabalhando em um projeto de C ++ que usa Qt (gui lib), VTK (gráficos LIB) e outra biblioteca que é tão obscuro Não vou mencionar o seu nome e em vez disso chamar LIB_X. O projeto utiliza Qt para os componentes GUI e VTK (mais precisamente a extensão QVTKWidget fornecido pelo VTK que suportes Qt) para renderizar geometria .. e ele usa LIB_X para recolher e manipular geometria.

O problema é que acontece que LIB_X realmente usa VTK (onde e como, eu não sei, é de código fechado). No início não havia nenhum problema, compilação com ambas as libs vinculados estava indo bem, mas em algum momento eu liguei para um certo (e altamente necessário) função LIB_X e compilar levou a um monte de 'blá, blá, algo sobre um VTK lib / obj já definido em LIB_X dLL' erros.

por exemplo. (E note que este é com / FORCE: MULTIPLE por isso é um aviso aqui, deixe-me saber se você quer o erro sem / FORCE: MULTIPLE e eu vou postá-lo):

1>LIB_X.lib(LIB_X.dll) : warning LNK4006: "public: __thiscall std::vector<double,class std::allocator<double> >::~vector<double,class std::allocator<double> >(void)" (??1?$vector@NV?$allocator@N@std@@@std@@QAE@XZ) already defined in vtkCommon.lib(vtkInformationDoubleVectorKey.obj);

Eu tentei usar / FORCE: MULTIPLE e parecia ser um milagre no início, mas estou recebendo erros aleatórios no código que principalmente dão erros heap. Eu decidi para remover todas as referências a LIB_X do projeto principal e criou uma lib estático que iria lidar com todas as coisas LIB_X. Eu não sou um especialista em C ++, então eu não tenho certeza de como ele lida confronto lib quando você estiver usando um lib pré-compilados, mas eu ainda recebeu lib confronto erros ao vincular minha lib estática no meu projeto principal, então eu ainda tem que usar / FORCE: MULTIPLE.

Uma vez eu tive a estática lib parecia que os erros aleatórios tinha ido embora, eu era capaz de fazer muita coisa com métodos LIB_X no projeto principal via da lib estática, mas do nada, eu adicionei um novo membro de dados para classe meu principal do projeto (a std :: vector de duplas) e de repente eu estava ficando um erro de pilha em um dos métodos de minha biblioteca estática. Se eu comentou o novo membro de dados, o método da biblioteca estática iria correr bem. Eu odeio dar o erro atual, porque honestamente eu não tenho certeza se o exame que vai valer a pena, mas aqui é assim mesmo no caso que pode ajudar:

Nota: ele trava para xutility em aproximadamente linha 151, aparece afirmação: "File: linha dbgheap.c: 1.279 expressão: _CrtIsValidHeapPointer (pUserData)"

O erro surge após a adição de um vector vector dupla a um vector vector vector duplo, falhando na linha push_back:

std::vector<std::vector<double>> tmpVec;
for(srvl_iter = srvl.begin(); srvl_iter != srvl.end(); ++srvl_iter)
{
 tmpVec.push_back((*srvl_iter).getControlPoints());
}
this->_splines.push_back(tmpVec); //CRASH

Ele só começou a bater aqui quando eu adicionei um novo membro de dados ao meu projeto principal (separar do lib estática!) Comentando o novo membro de dados leva o erro de distância.

std::vector<std::vector<std::vector<double>>> _geometry; 

Assim, / FORCE: MULTIPLE parece ruim, eu recebo erros aleatórios que simplesmente não fazem sentido para mim. Existem outras soluções? Am I parafusado? Existe algo que eu possa fazer com LIB_X do ligando de VTK?

Foi útil?

Solução

Eu encontrei um monte de erros LNK4006 ao vincular meu aplicativo para uma biblioteca (chamemos-lhe LIB_Y biblioteca) que fizeram uso pesado de std::vector<std::string>, que eu também fiz em meu aplicativo. Depois de um pouco de experimentação eu encontrei uma solução que funcionou - LIB_Y envoltório em uma DLL separada que chama LIB_Y (LIB_Y_WRAPPER, digamos) e vincular o aplicativo principal contra LIB_Y_WRAPPER

.

Para experimentar a minha sugestão que você vai precisar:

  1. Alterar o seu "lib estática que lida com todas as coisas LIB_X" a partir de um projeto de biblioteca estática em um projeto DLL (que chamarei LIB_X_WRAPPER).
  2. Verifique se os arquivos de cabeçalho de LIB_X_WRAPPER não incluem qualquer um dos arquivos de cabeçalho LIB_X. Esta é realmente importante , porque as necessidades de mensagens publicitárias para isolar completamente a sua aplicação a partir dos tipos de dados declarados nos arquivos de cabeçalho LIB_X (como std::vector<double>). Só se referir a arquivos de cabeçalho do LIB_X de dentro dos arquivos de origem de LIB_X_WRAPPER.
  3. Alterar a declaração de todas as classes e funções na sua lib estática para garantir que eles são exportados a partir da DLL (veja esta resposta se precisar detalhes sobre como exportar a partir de uma DLL).

Esta solução funcionou para mim porque manteve a instanciação (compilador gerado funções) da classe std::vector<std::string> usado por liby completamente separado da instanciação de std::vector<std::string> em meu aplicativo.

Como um aparte, eu suspeito que a causa do acidente que você está vendo (você comentar, é no processo de destruição de std::vector<double>) é porque a instanciação de std::vector<double> em seu aplicativo é diferente daquela em LIB_X.

Outras dicas

O comentando é provavelmente apenas sorte aleatória - se você está corrompendo a pilha nem sempre você vê-lo imediatamente, mas um vetor de stl irá alocar e coisas desalocar esquerda e à direita por isso é de admirar é encontrar o erro

Alguns libs exigem que você incluir coisas em uma determinada ordem. Não tenho a certeza por que exatamente porque me parece que desistir e dizer que você não pode criar uma biblioteca adequada, mas é a triste verdade. Enquanto você não incluir isso em qualquer lugar lib_x que incluem vtk ele deve estar bem, apesar de tudo.

No entanto, eles podem ser brigando por algum recurso ou usando algo indevidamente que torna impossível para eles trabalharem juntos. Se você é capaz de obter o compilador ok trabalho, segregando-os e ainda falhar, então sim, você está apenas fora de sorte, porque isso é apenas uma falha na maneira que este lib_x foi projetado e uma vez que é tão obscuro que não é provável que tenha sido completamente depurado contra todos os usos. Quando algo não é amplamente utilizado, geralmente, acaba sendo algo que funciona na máquina do desenvolvedor e projeto, mas não é necessariamente qualquer outra pessoa.

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