web-dev-qa-db-de.com

"Ein Einstiegspunkt mit dem Namen [Funktion] konnte nicht in der DLL gefunden werden" (Konvertierung von C++ nach C #)

Ich habe eine DLL, die von einem Drittanbieter stammt, die in C++ geschrieben wurde. Hier einige Informationen, die aus der DLL-Dokumentation stammen:

//start documentation

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

Beschreibung: Datenstruktur zum Empfangen des Funktionsergebnisses. Alle Funktionsergebnisse werden Als Unicode (UTF-8) gespeichert.

Methode:

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

Eingang:

char * imgPath

der vollständige Pfad der Bildposition für diese zu erkennende Funktion

RECO_DATA * o_data

datenobjekt zum Empfangen der Funktion Ergebnis. Funktion return: True bei Erfolg, andernfalls wird False zurückgegeben.

//end documentation

Ich versuche, den recoCHN_P_Name von meiner C # -Anwendung aus aufzurufen. Zu diesem Zweck habe ich diesen Code gefunden:

Der Code zum Importieren der 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);
}

Der Code zum Aufrufen der Funktion:

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

Und der Fehler, den ich bekomme, ist "" In DLL 'cnOCRsdk.dll' 'konnte kein Einstiegspunkt mit dem Namen' recoCHN_P_Name 'gefunden werden. " Ich vermute, dass dies der Fall ist Beim Konvertieren eines Typs von C++ in C # ist ein Fehler aufgetreten. Aber wo genau ...?

20
Evgeny

Stellen Sie zunächst sicher, dass die Funktion tatsächlich exportiert wird:

Verwenden Sie in der Visual Studio-Eingabeaufforderung dumpbin /exports whatever.dll.

32
i_am_jorf

C # unterstützt das Verwalten von C++ - Namen nicht und Sie müssen entweder die C++ - Funktionen mit deklarieren

extern "C" {...}

(Möglicherweise keine Option, wenn sie von einem Dritten stammen), oder rufen Sie den entstellten Namen direkt an, wenn Sie ihn zum Laufen bringen können. Es kann einfacher sein, den Drittanbieter dazu zu bringen, eine nicht beeinträchtigte Schnittstelle für die Funktionalität bereitzustellen.

20
paxdiablo

Gelöst - zumindest bis zu dem Punkt, an dem das Programm nicht bricht und tatsächlich einen bool-Wert zurückgibt.

Ich denke, der Schlüssel war, den Einstiegspunkt als den 'entstellten' Namen anzugeben

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

Danach bekam ich andere Fehler, aber der Einstiegspunkt konnte nicht gefunden werden.

15
Evgeny

Ich würde einen Wrapper mit C++/CLI schreiben. Dieser Wrapper kann die .h-Dateien einschließen und eine Verknüpfung zu den .lib-Dateien herstellen, die Sie vom Drittanbieter erhalten haben. Dann ist es einfach und sicher, eine verwaltete Schnittstelle für Ihr C # -Programm zu erstellen.

3
Dan Byström

Ich habe das gleiche Problem in diesen Schritten gelöst:

Schritt 1) ​​Wenn Sie Ihr benutzerdefiniertes DLL in C++ mit Visual Studio programmieren, setzen Sie auf der Eigenschaftsseite Ihres Projekts den Parameter Common Language Runtime Support (/clr) auf Common Language Runtime Support (/clr)

Schritt 2) Um die Verzögerung in .h-Datei zu verwenden, verwenden Sie das __declspec(dllexport)-Schlüsselwort wie folgt:

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

Schritt 3) Erstellen und exportieren Sie DLL -Datei, und verwenden Sie dann die Dependency Walker - Software, um Ihre Funktion zu erhalten EntryPoint .

step4) Importiere DLL datei Im C # -Projekt und setze EntryPoint und CallingConvention wie folgt:

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

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

Sie können versuchen, den unveränderten Namen zu verwenden, während Sie im DllImport eine CallingConvention angeben

0
evilfred

Korrektes EntryPoint string konnte in der ".lib" -Datei gefunden werden, die zusammen mit der nicht verwalteten Haupt-DLL geliefert wird.

0
uzrgm