“Incapaz de encontrar um ponto de entrada chamado [função] na DLL” (C ++ para C# Tipo de conversão)
Pergunta
Eu tenho uma DLL que vem de terceiros, que foi escrita em C ++. Aqui estão algumas informações que vêm da documentação da DLL:
//start documentation
RECO_DATA{
wchar_t Surname[200];
wchar_t Firstname[200];
}
Descrição: Estrutura de dados para receber o resultado da função. Todo o resultado da função será armazenado como Unicode (UTF-8).
Método:
bool recoCHN_P_Name(char *imgPath,RECO_DATA *o_data);
Entrada:
char * imgPath
O caminho completo do local da imagem para esta função reconhecer
RECO_DATA * o_data
Objeto de dados para receber o resultado da função. Função Retorno: True se o sucesso, caso contrário, False retornará.
//end documentation
Estou tentando chamar o Recochn_P_Name do meu aplicativo C#. Para esse fim, criei este código:
O código para importar a DLL:
public class cnOCRsdk
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct RECO_DATA{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=200)]
public string FirstName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 200)]
public string Surname;
}
[DllImport(@"cnOCRsdk.dll", EntryPoint="recoCHN_P_Name")]
public static extern bool recoCHN_P_Name(byte[] imgPath, RECO_DATA o_data);
}
O código para chamar a função:
cnOCRsdk.RECO_DATA recoData = new cnOCRsdk.RECO_DATA();
string path = @"C:\WINDOWS\twain_32\twainrgb.bmp";
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] bytes = encoding.GetBytes(path);
bool res = cnOCRsdk.recoCHN_P_Name(bytes, recoData);
E o erro que estou recebendo é "" Incapaz de encontrar um ponto de entrada chamado 'Recochn_P_Name' em dll 'cnocrsdk.dll'. "Suspeito que estou tendo um erro ao converter um tipo de C ++ em C#. onde exatamente ... ?
Solução
Primeiro, verifique se a função é realmente exportada:
No prompt de comando do Visual Studio, use dumpbin /exports whatever.dll
Outras dicas
C# não suporta o nome C ++ e você precisa declarar as funções C ++ com
extern "C" {...}
(pode não ser uma opção se eles forem de terceiros) ou ligue diretamente no nome mutilado, se você puder fazer funcionar. Pode ser mais fácil conseguir que o terceiro forneça uma interface não usada à funcionalidade.
Resolvido - pelo menos até o ponto em que o programa não quebra e realmente me devolve um valor BOOL.
A chave, eu acho, era especificar o ponto de entrada como o nome 'mutilado'
[DllImport(@"cnOCRsdk.dll", EntryPoint="?recoCHN_P_Name@CcnOCRsdk@@QAE_NPADPAURECO_DATA@@@Z")]
public static extern bool recoCHN_P_Name(ref string imgPath, ref RECO_DATA o_data);
Depois disso, recebi outros erros, mas o 'incapaz de encontrar o ponto de entrada' desapareceu.
Eu escreveria um invólucro usando C ++/CLI. Esse invólucro poderá incluir os arquivos .h e link para os arquivos .lib que você obteve do fornecedor de terceiros. Em seguida, é fácil e seguro escrever uma interface gerenciada para o seu programa C#.
Eu resolvi o mesmo problema nessas etapas:
passo 1) Se você programar sua DLL personalizada em C ++ usando o Visual Studio, na página da propriedade do seu projeto Defina o Common Language Runtime Support (/clr)
parâmetro para Common Language Runtime Support (/clr)
.
passo 2) Para funcionar desaceleração em .h
Uso de arquivo __declspec(dllexport)
Palavra -chave como abaixo:
__declspec(dllexport) double Sum(int a,int b);
etapa 3) Construir e exportar o arquivo DLL e depois usar o Walker dependência Software para obter sua função Ponto de entrada.
Passo 4) Importar arquivo DLL no projeto C# e definir Ponto de entrada e Chamando a concessão variável como abaixo:
[DllImport("custom.dll", EntryPoint = "?Sum@@YAXHHHHHHNNN@Z", CallingConvention = CallingConvention.Cdecl)]
public static extern double Sum(int a,int b);
Você pode tentar usar o nome não dalhado enquanto especifica uma CallingConvention no Dllimport
Correto Ponto de entrada A string pode ser encontrada no arquivo ".lib" que vem junto com a DLL não gerenciada principal.