Adicionando impulso faz compilação de depuração dependem “não-D” MSVC DLLs de tempo de execução

StackOverflow https://stackoverflow.com/questions/222778

Pergunta

Eu tenho um problema chato que eu poderia ser capaz de alguma forma contornar, mas por outro lado seria muito melhor estar no topo do mesmo e entender o que exatamente está acontecendo, já que parece que este material é realmente veio para ficar.

Aqui está a história: Eu tenho um aplicativo OpenGL simples que funciona bem: nunca é um problema importante na compilação, ligando, ou executá-lo. Agora eu decidi tentar mover alguns dos cálculos mais intensivos em um segmento de trabalho, a fim de, eventualmente, fazer a interface gráfica ainda mais responsivo -. Utilizando Boost.Thread, é claro

Em suma, se eu adicionar o seguinte fragmento no início do meu arquivo .cpp:

#include <boost/thread/thread.hpp>

void dummyThreadFun() { while (1); }    

boost::thread p(dummyThreadFun);

, então eu começar a receber "Esta aplicação falhou ao iniciar porque msvcp90.dll não foi encontrado" ao tentar lançar a compilação de depuração. (Modo de disparo funciona ok.)

Agora, olhando para o executável usando o Dependency Walker, que também não encontrar esta DLL (que se espera eu acho), eu podia ver que nós estamos olhando para ele, a fim de ser capaz de chamar as seguintes funções:

?max@?$numeric_limits@K@std@@SAKXZ
?max@?$numeric_limits@_J@std@@SA_JXZ
?min@?$numeric_limits@K@std@@SAKXZ
?min@?$numeric_limits@_J@std@@SA_JXZ

Em seguida, eu tentei converter cada instância de min e max para macros de uso em vez disso, mas provavelmente não poderia encontrar todas as referências a eles, pois isso não ajuda. (Estou usando algumas bibliotecas externas para o qual eu não tenho o código fonte disponível Mas mesmo se eu poderia fazer isso -.. Eu não acho que é o caminho certo realmente)

Então, minhas perguntas - eu acho - são:

  1. Por que olhar para uma DLL não-debug, embora trabalhando com a compilação de depuração?
  2. O que é a maneira correta de resolver o problema? Ou até mesmo uma rápida e suja?

Eu tive esse primeiro de uma instalação vanilla praticamente do Visual Studio 2008. Em seguida, tentou instalar o Feature Pack e SP1, mas não quer ajudar. Claro que também tentou reconstruir várias vezes.

Eu estou usando binários pré-construídos para Impulso (v1.36.0). Esta não é a primeira vez que eu uso impulso neste projecto, mas pode ser a primeira vez que eu uso uma parte que é baseado em uma fonte separada.

A desativação vinculação incremental não ajuda. O fato de que o programa é OpenGL não parece ser relevante quer - Eu tenho um problema semelhante ao adicionar as mesmas três linhas de código em um programa simples console (mas lá estava reclamando MSVCR90.DLL e _mkdir, e quando eu substituiu o último com boost::create_directory, o problema foi embora !!). E é realmente apenas removendo ou adicionando essas três linhas que torna o ok execução do programa, ou não funcionam em tudo, respectivamente.

Eu não posso dizer que entendo Side-by-Side (nem sei se isso está relacionado, mas é isso que eu assumir por agora), e para ser honesto, eu não sou super-interessados, quer - contanto posso apenas construir, depurar e implantar meu aplicativo ...


Editar 1: Ao tentar construir um despojado exemplo, que de qualquer maneira reproduz o problema, eu descobri que a questão tem a ver com a propagação Toolkit , cuja utilização é um fator comum a todos os meus programas com este problema. (No entanto, eu nunca tive isso antes de começar a ligação no material Boost.)

Eu já vêm com um programa mínimo que me permite reproduzir o problema. É composto por duas unidades de compilação, a.cpp e B.cpp.

a.cpp:

#include "sp.h"

int main(int argc, char* argv[])
{
    mailbox mbox = -1;
    SP_join(mbox, "foo");

    return 0;
}

B.cpp:

#include <boost/filesystem.hpp>

Algumas observações:

  1. Se eu comente a SP_join linha de a.cpp, o problema desaparece.
  2. Se eu comente a linha única de B.cpp, o problema desaparece.
  3. Se eu mover ou copiar uma única linha de B.cpp para o início ou final de a.cpp, o problema desaparece.

(Em cenários 2 e 3, o programa falha ao chamar SP_join, mas isso é só porque a caixa de correio não é válido ... isso não tem nada a ver com o assunto em questão.)

Além disso, a biblioteca central da Spread éligados, e que é certamente parte da resposta à minha pergunta # 1, uma vez que não há nenhuma compilação de depuração do que lib no meu sistema.

Atualmente, eu estou tentando chegar a algo que tinha que fazer isso possível reproduzir o problema em outro ambiente. (Mesmo que eu vai ser muito surpreso se ele realmente pode ser repetido fora minhas premissas ...)


Editar 2: Ok, então aqui nós agora temos um pacote usando o que eu era capaz de reproduzir o problema em uma instalação quase baunilha de WinXP32 + VS2008 + impulsionar 1.36.0 (ainda binários pré-construídos de BoostPro Computing ).

O culpado é certamente o lib Spread, minha compilação de que de alguma forma requer uma versão bastante arcaica de STLport para MSVC 6 ! No entanto, eu continuo a achar os sintomas relativamente divertido. Além disso, seria bom ouvir se você pode realmente reproduzir o problema - incluindo cenários 1-3 acima. O pacote é bastante pequeno, e deve conter todas as peças necessárias.

Como se vê, a questão realmente não tem nada a ver com Boost.Thread especificamente, como este exemplo agora usa o impulso biblioteca de sistema de arquivos. Além disso, ele agora reclama MSVCR90.DLL, não P como anteriormente.

Foi útil?

Solução

Boost.Thread tem algumas combinações possíveis de construção, a fim de tentar e atender a todas as diferenças em vinculação cenários possíveis com MSVC. Em primeiro lugar, você pode ligar estaticamente para Boost.Thread, ou link para Boost.Thread em uma DLL separada. em seguida, você pode ligar para a versão DLL do tempo de execução MSVC, ou o tempo de execução biblioteca estática. Finalmente, você pode ligar para o tempo de execução de depuração ou o tempo de execução de lançamento.

Os cabeçalhos Boost.Thread tentar detectar automaticamente o cenário de compilação usando as macros predefinidas que o compilador gera. A fim de ligação contra a versão que utiliza o tempo de execução de depuração que você precisa ter _DEBUG definido. Este é automaticamente definida pelas MD e / compilador MDd interruptores /, por isso deve ser OK, mas sua descrição do problema sugere o contrário.

Onde você conseguiu os binários pré-construídos a partir de? Você está explicitamente selecionar uma biblioteca em suas configurações do projeto, ou você está deixando o mecanismo de auto-link, selecione o arquivo lib apropriada?

Outras dicas

Eu acredito que eu tive esse mesmo problema com o impulso no passado. No meu entendimento, isso acontece porque os cabeçalhos impulso usar uma instrução de pré-processador para ligação contra o lib adequado. Se seus depuração e versão bibliotecas estão na mesma pasta e têm nomes diferentes o recurso "auto-link" não funcionará corretamente.

O que tenho feito é definir BOOST_ALL_NO_LIB para o meu projeto (que impede os cabeçalhos de "auto ligando") e, em seguida, usar as configurações do projeto VC a ligação com as bibliotecas corretas.

Looks como outras pessoas responderam lado do impulso da questão. Aqui está um pouco de informação de fundo no lado MSVC das coisas, que podem economizar ainda mais dor de cabeça.

Existem 4 versões do C (e C ++) tempos de execução possíveis:

  • / MT: LIBCMT.LIB (C), libcpmt.lib (C ++)
  • / MTd: LIBCMTD.LIB, libcpmtd.lib
  • / MD: msvcrt.lib, MSVCPRT.lib
  • / MDd: Msvcrtd.lib, MSVCPRTD.lib

As versões DLL ainda exigem links para que lib estático (que de alguma forma faz todo o setup para link para a DLL em tempo de execução - Eu não sei os detalhes). Observe na versão todos os casos de depuração tem o sufixo d. O tempo de execução C usa o infixa c, e o tempo de execução C ++ usa o infixa cp. Ver o padrão? Em qualquer aplicativo, você só deve fazer o link com as bibliotecas em uma dessas linhas.

Às vezes (como no seu caso), encontra-se ligando para outra pessoa biblioteca estática que está configurado para usar a versão errada do C ou C ++ tempos de execução (via #pragma comment(lib) terrivelmente irritante). Você pode detectar isso transformando sua maneira vinculador verbosidade-se, mas é realmente muito chato para caçar. O "matar um roedor com uma bazuca" solução é usar a configuração /nodefaultlib:... vinculador para descartar os C e C ++ bibliotecas 6 que você sabe que você não precisa. Eu usei isso no passado sem problema, mas eu não sou positivo que vai sempre trabalhar ... talvez alguém vai sair da toca me dizendo como esta "solução" pode causar seu programa para comer bebês na terça-feira à tarde .

Este é um erro de link clássico. Parece que você está ligando para um impulso DLL que se liga ao tempo de execução errada C ++ (há também desta página , fazer uma pesquisa de texto para "threads"). Também parece que as ligações biblioteca boost::posix::time para a DLL correta.

Infelizmente, eu não estou encontrando a página que discute como escolher o DLL impulso corretamente-construído (embora ENTENDI encontrar um e-mail de três anos de idade que parece apontar para BOOST_THREAD_USE_DLL e BOOST_THREAD_USE_LIB).


Olhando para a sua resposta novamente, parece que você está usando os binários pré-construídos. O DLL que você não é capaz de link para é parte do TR1 Feature Pack (segunda questão nessa página). Esse Feature Pack está disponível no site da Microsoft . Ou você vai precisar de um binário diferente para ligação contra. Aparentemente, as ligações biblioteca boost::posix::time contra o sem correção C ++ tempo de execução.

Uma vez que você já aplicou o pacote de recursos, acho que o próximo passo eu tomaria seria a construção de impulso com a mão. Esse é o caminho que eu sempre tomadas, e é muito simples: baixar o bjam binário, e executar o script impulso Construir na fonte biblioteca. É isso.

Agora, isso ficou ainda um pouco mais interessante ... Se eu apenas adicionar isso em algum lugar na fonte:

boost::posix_time::ptime pt = boost::posix_time::microsec_clock::universal_time();

(juntamente com o material #include correspondente), então ele novamente funciona ok. Portanto, este é um rápido e nem mesmo solução muito sujo, mas hey - o que está acontecendo aqui, realmente

A partir de memória várias partes das bibliotecas de impulso preciso de você para definir algumas bandeiras de pré-processamento, a fim de ser capaz de compilar corretamente. Coisas como BOOST_THREAD_USE_DLL e assim por diante.

O BOOST_THREAD_USE_DLL não vai ser o que está causando esse erro particular, mas pode estar esperando que você defina _DEBUG ou algo parecido. Lembro-me de há alguns anos atrás em nossa impulso C ++ projectos que tivemos algumas definições BOOST_XYZ de pré-processamento extras declarado nas opções do compilador visual studio (ou makefile)

Verifique o arquivo config.hpp no diretório impulso fio. Quando você puxar o material ptime É possivelmente incluindo um arquivo config.hpp diferente, o que pode, em seguida, definir as coisas de pré-processamento de forma diferente.

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