Страницы

Поиск по вопросам

вторник, 25 декабря 2018 г.

Не удаётся подключить Dll

К проекту на C# подключаю библиотеку C++, библиотека полностью рабочая. Руководство по подключению взял тут
[DllImport("C:\\Users\\Zaki\\Desktop\\SetsGen.dll", CallingConvention = CallingConvention.Cdecl)] public static extern string GetSets(string ids, int power);
public void DllSub(string param) { try { string myAns = GetSets(param, 3); string[] tokens = myAns.Split('/'); foreach (var token in tokens) { Console.WriteLine(token); } } catch (Exception ex) { Console.WriteLine(ex.Message); } }
Нативная сигнатура функции GetSets в Dll выглядит следующим образом:
std::string GetSets(std::string ids, int power)
Получаю исключение при обращении к портированной функции GetSets:
An unhandled exception of type 'System.AccessViolationException' occurred in Test.exe Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Какие могут быть причины и как исправить?


Ответ

Причины могут быть разные:
Ошибка в реализации нативной функции. Чтобы её исключить, попробуйте сделать пустую GetSets и пересобрать DLL. Проблемы совместимости DLL и С# кода. Был случай, когда DLL, собранная в C++Builder приводила к ошибкам на стадии выполнения. Пересборка компилятором MS решила проблему на корню. Неправильно передаются аргументы в функцию. См. маршалинг строк.
Если сигнатура нативной функции содержит сложные типы из стандартной библиотеки C++ (в том числе и std::string), использовать такую функцию в P/Invoke будет проблематично (читай как невозможно). Разные компиляторы по-разному реализуют стандартные классы, поэтому передавать между модулями такие типы довольно опасно.
В данном случае наиболее правильное решение будет заключаться в том, чтобы экспортировать функцию, принимающую const char* (си-строку), а дальше в потрохах DLL уже можно использовать и std::string для удобства.

Комментариев нет:

Отправить комментарий