2009-03-17 11 views
17

J'ai une DLL qui provient d'un tiers, qui a été écrit en C++. Voici quelques informations qui provient de la documentation dll:"Impossible de trouver un point d'entrée nommé [fonction] dans dll" (conversion de type C++ à C#)

//start documentation 

RECO_DATA{ 
wchar_t Surname[200]; 
wchar_t Firstname[200]; 
} 

Description: structure de données pour recevoir le résultat de la fonction. Tout le résultat de la fonction sera enregistré en tant qu'Unicode (UTF-8).

Méthode:

bool recoCHN_P_Name(char *imgPath,RECO_DATA *o_data); 

entrée:

char * imgPath 

le chemin complet de l'emplacement d'image pour cette fonction reconnaître

RECO_DATA * o_data 

objet de données pour recevoir la fonction résultat . Retour de fonction: Vrai si succès, sinon faux retournera. J'essaie d'appeler le recoCHN_P_Name de mon application C#. À cette fin, je suis venu avec ce code:

Le code pour importer les 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); 
} 

Le code pour appeler la fonction:

  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); 

Et l'erreur que je reçois "" Impossible de trouver un point d'entrée nommé 'recoCHN_P_Name' dans la DLL 'cnOCRsdk.dll'. " Je me doute que j'ai une erreur dans la conversion d'un type de C++ en C#. Mais où exactement ... ?

Répondre

29

d'abord, assurez-vous que la fonction est effectivement exportée:

Dans l'invite de commande Visual Studio, utilisez dumpbin /exports whatever.dll

+0

J'ai une ligne dans la sortie qui dit « 14 D 00007B40 recoCHN_P_Name @ CcnOCRsdk @@ QAE_NPADPAURECO_DATA @@@ Z " qu'est-ce que cela me dit? – Evgeny

+3

Voir http://www.kegel.com/mangle.html pour une explication détaillée sur la façon de le décrypter. Assurez-vous que les types de données sont corrects. –

+0

Cela m'a vraiment indiqué la bonne direction, merci – Evgeny

15

C# ne prend pas en charge le nom de C++ mutiler et vous devez soit de déclarer les fonctions C++ avec

extern "C" {...} 

(peut ne pas être une option si elles proviennent d'un tiers), ou appelez directement le nom tronqué si vous pouvez le faire fonctionner. Il peut être plus facile d'obtenir que le tiers fournisse une interface non mutilée à la fonctionnalité.

+0

Votre réponse a sauvé ma journée. –

3

J'écrirais un wrapper en utilisant C++/CLI. Ce wrapper sera en mesure d'inclure les fichiers .h et un lien vers les fichiers .lib que vous avez obtenus du fournisseur tiers. Il est alors facile et sûr d'écrire une interface gérée pour votre programme C#.

15

Résolu - au moins au point où le programme ne se casse pas et me renvoie une valeur booléenne.

La clé, je suppose, était de préciser le point d'entrée comme le nom « mutilée »

[DllImport(@"cnOCRsdk.dll", EntryPoint="[email protected]@@[email protected]@@Z")] 
    public static extern bool recoCHN_P_Name(ref string imgPath, ref RECO_DATA o_data); 

Après que je suis arrivé quelques autres erreurs, mais le « incapable de trouver le point d'entrée » allé loin.

+0

Cela a résolu mon problème! Merci! – user20493

0

Vous pouvez essayer d'utiliser le nom non substantypés en spécifiant un CallingConvention dans le DllImport

0

correct chaîne EntryPoint se trouve dans le fichier « .lib » qui vient avec les principaux dll non géré.

1

J'ai résolu le même problème dans ces étapes:

étape 1) Si vous programmez votre DLL personnalisé en C++ en utilisant Visual Studio, puis à la page de propriétés de votre projet définissez le paramètre Common Language Runtime Support (/clr)-Common Language Runtime Support (/clr).

étape 2) à la fonction décélération .h utilisation de fichiers __declspec(dllexport) mot-clé comme ci-dessous:

__declspec(dllexport) double Sum(int a,int b); 

étape 3) Construire et fichier DLL d'exportation, puis utilisez le logiciel Dependency Walker pour obtenir votre fonction EntryPoint.

step4) Importation de fichiers DLL Dans le projet C# et mis EntryPoint et CallingConvention variables comme ci-dessous:

[DllImport("custom.dll", EntryPoint = "[email protected]@[email protected]", CallingConvention = CallingConvention.Cdecl)] 

    public static extern double Sum(int a,int b);