Ответ 1
Сначала убедитесь, что функция фактически экспортирована:
В командной строке Visual Studio используйте dumpbin /exports whatever.dll
У меня есть dll, который поступает от третьей стороны, написанной на С++. Вот некоторая информация, которая поступает из документации 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);
Input:
char * imgPath
полный путь расположения изображения для этого функция распознавания
RECO_DATA * o_data
объект данных для приема функции результат. Возврат функции: Истинно, если Success, иначе false вернется.
//end documentation
Я пытаюсь вызвать recoCHN_P_Name из моего приложения С#. С этой целью я придумал этот код:
Код для импорта 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'." Я подозреваю, что у меня ошибка при преобразовании типа из С++ в С#. Но где именно...?
Сначала убедитесь, что функция фактически экспортирована:
В командной строке Visual Studio используйте dumpbin /exports whatever.dll
С# не поддерживает искажение имени C++, и вам нужно объявить функции C++ с помощью
extern "C" {...}
(может не подходить, если они принадлежат третьей стороне), или позвонить искалеченному имени напрямую, если вы можете заставить его работать. Может быть проще заставить стороннюю организацию предоставить неискаженный интерфейс к функциональности.
Решено - по крайней мере, до того момента, когда программа не сломается и на самом деле возвращает мне значение bool.
Ключ, я думаю, заключался в том, чтобы указать точку входа как "измененное" имя
[DllImport(@"cnOCRsdk.dll", EntryPoint="[email protected]@@[email protected]@@Z")]
public static extern bool recoCHN_P_Name(ref string imgPath, ref RECO_DATA o_data);
После этого у меня появились другие ошибки, но "не удалось найти точку входа" ушел.
Я бы написал обертку, используя С++/CLI. Эта оболочка сможет включать файлы .h и ссылку на файлы .lib, которые вы получили от стороннего поставщика. Тогда легко и безопасно написать управляемый интерфейс для вашей программы на С#.
Я решил ту же проблему на следующих этапах:
шаг 1). Если вы программируете свою пользовательскую DLL на С++ с помощью 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 файл в проект С# и установите переменную EntryPoint и CallingConvention, как показано ниже:
[DllImport("custom.dll", EntryPoint = "[email protected]@[email protected]", CallingConvention = CallingConvention.Cdecl)]
public static extern double Sum(int a,int b);
Вы можете попробовать использовать unmangled name, указав CallingConvention в DllImport
Строка EntryPoint может быть найдена в файле .lib, который поставляется вместе с основной неуправляемой dll.
Боа тарде! Como trabalhar com просмотрщик отчетов no visual c++ visual studio 2017??
Já tentei instalar varias vezes mais não aparece quando vou abrir um novo form и т.д...
Agradeço sua atenção,
Att: Карлос.