2009-03-17 9 views
17

Mam dll, które pochodzi od strony trzeciej, która została napisana w C++. Oto kilka informacji, które pochodzi z dokumentacji biblioteki dll:"Nie można znaleźć punktu wejścia o nazwie [funkcja] w dll" (konwersja C++ do C#)

//start documentation 

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

Opis: struktury danych do odbioru wynik funkcji. Wszystkie wyniki funkcji będą przechowywane jako Unicode (UTF-8).

Metoda:

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

Wejście:

char * imgPath 

pełną ścieżkę położenia obrazu w tym funkcji rozpoznawania

RECO_DATA * o_data 

obiektu danych do odbioru wynik funkcja . Zwrot funkcji: Prawda, jeśli sukces, w przeciwnym razie false powróci.

//end documentation 

Próbuję wywołać recoCHN_P_Name z mojej aplikacji C#. W tym celu, wymyśliłem ten kod:

Kod importować 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); 
} 

kod, aby wywołać funkcję:

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

a błąd Dostaję to jest "" Nie można znaleźć punktu wejścia o nazwie "recoCHN_P_Name" w pliku DLL "cnOCRsdk.dll". " Podejrzewam, że wystąpił błąd podczas konwersji typu z C++ na C#. Ale gdzie dokładnie ... ?

Odpowiedz

29

Najpierw upewnij się, że funkcja jest faktycznie wywiezione:

W Visual wierszem Studio polecenia użyć dumpbin /exports whatever.dll

+0

mam linię na wyjściu, który mówi „14 D 00007B40 recoCHN_P_Name @ CcnOCRsdk @@ QAE_NPADPAURECO_DATA @@@ Z " co mi to mówi? – Evgeny

+3

Zobacz http://www.kegel.com/mangle.html w celu uzyskania szczegółowego wyjaśnienia, jak go odszyfrować. Upewnij się, że masz poprawne typy danych. –

+0

To zdecydowanie wskazało mi właściwy kierunek, dzięki – Evgeny

15

C# nie obsługuje C nazwa ++ maglowania i albo trzeba zadeklarować C++ funkcje z

extern "C" {...} 

(opcja może nie być dostępna, jeśli pochodzą od strony trzeciej) lub zadzwonić bezpośrednio po zniekształconej nazwie, jeśli możesz ją uruchomić. Może być łatwiej, aby strona trzecia zapewniła niezmienny interfejs do tej funkcji.

+0

Twoja odpowiedź uratowała mi dzień. –

3

Napisałbym wrapper używając C++/CLI. To opakowanie będzie mogło zawierać pliki .h i link do plików .lib pobranych od zewnętrznego dostawcy. Wówczas łatwo i bezpiecznie napiszesz zarządzany interfejs dla twojego programu C#.

15

Rozwiązany - przynajmniej do punktu, w którym program się nie łamie i zwraca mi wartość bool.

Kluczem, jak sądzę, było określić punkt wejścia jako „zniekształcone” nazwa

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

Po tym mam kilka innych błędów, ale „nie można odnaleźć punktu wejścia” odszedł.

+0

To rozwiązało mój problem! Dzięki! – user20493

0

Można spróbować użyć nazwy unmangled podczas określania CallingConvention w prawidłowej EntryPoint ciąg DllImport

0

można znaleźć w „.lib” pliku, który przychodzi wraz z głównym dll niezarządzanego.

1

I rozwiązać ten sam problem w tych krokach:

etap 1) Jeśli zaprogramować swój własny DLL w C++ przy użyciu Visual Studio, a następnie na stronie właściwości projektu ustawić parametr Common Language Runtime Support (/clr) do Common Language Runtime Support (/clr).

krok 2) Aby funkcjonować opóźnienie w .h stosowania plików __declspec(dllexport) kluczowe jak poniżej:

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

krok 3) Budowa i eksport plików DLL, a następnie użyć Dependency Walker oprogramowania dostać swoją funkcję EntryPoint.

step4) plik DLL importu W projekcie C# i ustawić EntryPoint i CallingConvention zmienny jak poniżej:

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

    public static extern double Sum(int a,int b); 
Powiązane problemy