Eu tenho uma biblioteca dll com código de API C ++ não gerenciado que preciso usar em meu aplicativo .NET 4.0. Mas todo método que tento carregar minha dll, recebo um erro:
Não foi possível carregar a DLL 'MyOwn.dll': O módulo especificado não foi encontrado. (Exceção de HRESULT: 0x8007007E)
Eu li e tentei várias soluções que encontrei na internet. Nada funciona..
Tentei usar os seguintes métodos:
[DllImport("MyOwn.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs((UnmanagedType.I4))]
public static extern Int32 MyProIni(string DBname, string DBuser_pass,
string WorkDirectory, ref StringBuilder ErrorMessage);
Quando tentei seguir este artigo e quando executo este exemplo (a partir do código baixado), ele funciona sem problemas (a dll usada está na pasta bin / debug)
Copiei minha dll (junto com todos os arquivos dos quais ela depende para minha pasta bin).
Eu também tentei essa abordagem, mas obtive o mesmo erro:
[DllImportAttribute(MyOwnLibDllPath, EntryPoint="TMproIni")]
[return: MarshalAs(UnmanagedType.I4)]
public static extern int MyproIni(string DBname, string DBuser_pass,
string WorkDirectory, ref StringBuilder ErrorMessage);
Alguma sugestão?
Você pode usar a ferramenta dumpbin para descobrir as dependências DLL necessárias:
Isso informará quais DLLs sua DLL precisa carregar. Particularmente, preste atenção ao MSVCR * .dll. Eu vi seu código de erro ocorrer quando o Visual C ++ Redistributable correto não está instalado.
Você pode obter os "Pacotes redistribuíveis do Visual C ++ para Visual Studio 2013" no site da Microsoft. Ele instala c: \ windows \ system32 \ MSVCR120.dll
No nome do arquivo, 120 = 12.0 = Visual Studio 2013.
Tenha o cuidado de ter a versão certa do Visual Studio (10.0 = VS 10, 11 = VS 2012, 12.0 = VS 2013 ...) arquitetura certa (x64 ou x86) para a plataforma de destino de sua DLL e também deve ser cuidadoso. depurar compilações. A compilação de depuração de uma DLL depende do MSVCR120d.dll, que é uma versão de depuração da biblioteca, instalada com o Visual Studio, mas não pelo pacote redistribuível.
fonte
debug
binário, a versão redistribuível do tempo de execução C ++ precisa ser exatamente a mesma de onde você a construiu.Este é um 'kludge', mas você poderia pelo menos usá-lo para um teste de sanidade: tente codificar o caminho para a DLL em seu código
Tendo dito isto; no meu caso, executar
dumpbin /DEPENDENTS
conforme sugerido por @antony-hayward e copiar versões de 32 bits das DLLs listadas lá para meu diretório de trabalho resolveu esse problema para mim.A mensagem é um pouco enganosa, porque não é "minha" dll que não pode ser carregada - são as dependências
fonte
A DLL deve estar na pasta bin.
No Visual Studio, adiciono a dll ao meu projeto (NÃO nas referências, mas em "Adicionar arquivo existente"). Em seguida, defina a propriedade "Copiar para diretório de saída" para a dll como "Copiar se mais recente".
fonte
Tente inserir o caminho completo da dll. Se não funcionar, tente copiar a dll para a pasta system32.
fonte
Certifique-se de que todas as dependências de sua própria dll estejam presentes perto da dll ou em
System32
.fonte
Há uma coisa muito engraçada (e de relevância técnica) que pode desperdiçar suas horas, então pensei em compartilhá-la aqui -
Criei um projeto de aplicativo de console
ConsoleApplication1
e um projeto de biblioteca de classesClassLibrary1
.Todo o código que estava fazendo o p / invoke estava presente em
ClassLibrary1.dll
. Portanto, antes de depurar o aplicativo do visual studio, simplesmente copiei o assembly não gerenciado C ++ (myUnmanagedFunctions.dll
) para o\bin\debug\
diretório doClassLibrary1
projeto para que ele possa ser carregado em tempo de execução pelo CLR.Eu continuei recebendo o
erro por horas. Mais tarde, percebi que todos os assemblies não gerenciados que devem ser carregados precisam ser copiados para o
\bin\debug
diretório do projeto de inicialização,ConsoleApplication1
que geralmente é um formulário Win, console ou aplicativo da web.Portanto, seja cauteloso, pois
Current Directory
na resposta aceita, na verdade, significa oCurrent Directory
executável principal de onde o processo de inscrição está começando. Parece uma coisa óbvia, mas às vezes pode não ser.Lição aprendida - sempre coloque as dlls não gerenciadas no mesmo diretório do executável de inicialização para garantir que possam ser encontradas.
fonte
bin\Debug
e osobj\Debug
diretórios e eu continuo recebendo o "Unable to DLL load"Ligue o registro de fusão, veja esta pergunta para muitos conselhos sobre como fazer isso. Depurar problemas de carregamento de aplicativos de modo misto pode ser uma verdadeira dor de cabeça. O registro de fusão pode ser uma grande ajuda.
fonte
Certifique-se de definir o Build Platform Target para x86 ou x64 para que seja compatível com sua DLL - que pode ser compilada para uma plataforma de 32 bits.
fonte
Se os projetos DLL e .NET estão na mesma solução e você deseja compilar e executar ambos sempre, pode clicar com o botão direito do mouse nas propriedades do projeto .NET, eventos de compilação e adicionar algo como o seguinte ao evento Pós-compilação linha de comando:
É basicamente uma linha do DOS e você pode ajustar com base em onde sua DLL está sendo construída.
fonte
Eu tive o mesmo problema quando implantei meu aplicativo para testar o PC. O problema foi o desenvolvimento PC teve
msvcp110d.dll
emsvcr110d.dll
mas não o PC de teste.Eu adicionei o módulo de mesclagem "Visual Studio C ++ 11.0 DebugCRT (x86)" no InstalledSheild e funcionou. Espero que isso seja útil para outra pessoa.
fonte
No meu caso, uma dll não gerenciada dependia de outra que estava faltando. Nesse caso, o erro apontará para a dll existente em vez da ausente, o que pode ser muito confuso.
Isso é exatamente o que aconteceu no meu caso. Espero que isso ajude mais alguém.
fonte
Acho que sua biblioteca não gerenciada precisa de um manifesto.
Aqui está como adicioná-lo ao seu binário. e aqui está o porquê.
Em resumo, várias versões de biblioteca redistribuível podem ser instaladas em sua caixa, mas apenas uma delas deve satisfazer seu aplicativo, e pode não ser o padrão, então você precisa informar ao sistema a versão de que sua biblioteca precisa, por isso o manifesto.
fonte
Configuração : Windows 7 de 32 bits
Contexto : Instalei um driver PCI-GPIB pelo qual não consegui me comunicar devido ao problema mencionado.
Resposta curta : Reinstale o driver.
Resposta longa : Eu também usei o Dependency Walker , que identificou vários módulos de dependência ausentes. Imediatamente, pensei que deveria ter sido uma falha na instalação do driver. Eu não queria verificar e restaurar cada arquivo ausente.
O fato de não ter conseguido encontrar o desinstalador em Programas e Recursos do Painel de Controle é outro indicador de instalação incorreta. Tive que excluir manualmente alguns * .dll em \ system32 e as chaves de registro para permitir a reinstalação do driver.
Problema corrigido.
A parte inesperada foi que nem todos os módulos de dependência foram resolvidos. No entanto, o * .dll de interesse agora pode ser referenciado.
fonte
Eu me deparei com o mesmo problema, no meu caso eu tinha dois PCs de 32 bits. Um com .NET4.5 instalado e outro era um PC novo.
minha dll cpp de 32 bits (versão em modo de versão) estava funcionando bem com o PC instalado em .NET, mas não com um PC novo, onde recebi o erro abaixo
finalmente,
fonte
Também enfrentou o mesmo problema ao usar o arquivo dll c / c ++ não gerenciado em ambiente c #.
1. Verificou a compatibilidade da dll com CPU de 32 bits ou 64 bits.
2. Verificou os caminhos corretos da pasta DLL .bin, system32 / sysWOW64 ou o caminho fornecido.
3.Verificado se os arquivos PDB (banco de dados do programa) estão faltando. Este vídeo oferece a você uma melhor compreensão sobre os arquivos PDB.
Ao executar o código binário C / C ++ de 32 bits em um sistema de 64 bits, isso pode ocorrer devido à incompatibilidade de plataforma. Você pode alterá-lo em Build> Configuration manager.
fonte
Eu enfrentei o mesmo problema ao importar C ++ Dll no .Net Framework +4, desmarquei Project-> Properties-> Build-> Prefer 32-bit e resolveu para mim.
fonte