«Невозможно найти точку входа с именем [function] в dll» (преобразование типа c ++ в c #) - PullRequest
21 голосов
/ 17 марта 2009

У меня есть dll от стороннего разработчика, написанная на C ++. Вот некоторая информация из документации dll:

//start documentation

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

Описание: Структура данных для получения результата функции. Все функции результата будут хранится как Unicode (UTF-8).

Метод:

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

Введите:

char * imgPath

полный путь к местоположению изображения для этого функция распознавания

RECO_DATA * o_data

объект данных для получения функции результат. Возврат функции: True, если Success, в противном случае вернется false.

//end documentation

Я пытаюсь вызвать recoCHN_P_Name из моего приложения на C #. С этой целью я придумал этот код:

Код для импорта 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);
}

Код для вызова функции:

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

И ошибка, которую я получаю, "Не удалось найти точку входа с именем 'recoCHN_P_Name' в DLL 'cnOCRsdk.dll'." Я подозреваю, что у меня возникла ошибка при преобразовании типа из C ++ в C #. Но где именно ...?

Ответы [ 7 ]

32 голосов
/ 17 марта 2009

Сначала убедитесь, что функция действительно экспортирована:

В командной строке Visual Studio введите dumpbin /exports whatever.dll

21 голосов
/ 17 марта 2009

C # не поддерживает искажение имени в C ++, и вам также нужно объявить функции C ++ с помощью

extern "C" {...}

(может не подходить, если они принадлежат третьей стороне), или позвонить искалеченному имени напрямую, если вы можете заставить его работать. Возможно, будет проще заставить третье лицо предоставить функциональный интерфейс без искажений.

16 голосов
/ 18 марта 2009

Решено - по крайней мере до точки, где программа не прерывается и фактически возвращает мне значение bool.

Ключ, я думаю, заключался в том, чтобы указать точку входа в качестве «искаженного» имени

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

После этого у меня появились другие ошибки, но «невозможно найти точку входа» исчезло.

3 голосов
/ 17 марта 2009

Я бы написал обертку с использованием C ++ / CLI. Эта обертка сможет включать файлы .h и ссылки на файлы .lib, полученные от стороннего поставщика. Тогда вам будет легко и безопасно написать управляемый интерфейс для вашей программы на C #.

1 голос
/ 21 июля 2017

Я решил ту же проблему в следующих шагах:

шаг 1) Если вы программируете свою пользовательскую DLL на C ++ с помощью Visual studio, то на странице свойств вашего проекта установите для параметра Common Language Runtime Support (/clr) значение Common Language Runtime Support (/clr).

шаг 2) Для функции замедления в .h файле используйте ключевое слово __declspec(dllexport), как показано ниже:

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

шаг 3) Создайте и экспортируйте файл DLL, затем используйте программное обеспечение Dependency Walker для получения вашей функции EntryPoint .

step4) Импорт файла DLL В проекте C # и установите переменную EntryPoint и CallingConvention , как показано ниже:

[DllImport("custom.dll", EntryPoint = "?Sum@@YAXHHHHHHNNN@Z", CallingConvention = CallingConvention.Cdecl)]

    public static extern double Sum(int a,int b);
0 голосов
/ 24 сентября 2015

Исправить Строка EntryPoint может быть найдена в файле ".lib", который поставляется вместе с основной неуправляемой DLL.

0 голосов
/ 25 марта 2009

Вы можете попытаться использовать ненадежное имя при указании CallingConvention в DllImport

...