Вызов вложенной .NET dll из проекта C++/CLI Visual Studio

Я пытаюсь вызвать DLL-метод из моего кода C++/CLI в Visual Studio .NET-DLL (v4.5) под названием «LicenseCheck.dll». Это работает нормально, пока эта DLL не попытается получить доступ к другой .NET-DLL с именем «SKCLNET.dll» (.NET v1.0.3705). Значение «LicenseCheck.dll» зависит от «SKCLNET.dll».

Когда я пытаюсь вызвать метод Licensecheck.dll "ValidateLicense::GetLicenseStatus()" из .NET-проекта, все работает нормально.

Вот ошибка, которую я получаю при запуске кода C++/CLI:

Необработанное исключение: System.BadImageFormatException: не удалось загрузить файл или сборку «SKCLNET.dll» или одна из его зависимостей. не является приложением Win32. (Исключение из HRESULT: 0x800700C1) в Seat.Core.LicenseProvider..ctor() в Seat.Core.LicenseProvider.get_Instance() в LicenseCheck.ValidateLicense.GetLicenseStatus() в main(String[] args) в C:\Users\deckenf\Desktop\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1.cpp:строка 13 в mainCRTStartupStrArray (аргументы String []) в D:\a_work\1\s\src\vctools\crt\crtw32\msilcrt\mcrtexe.cpp:строка 241 C:\Users\deckenf\Desktop\ConsoleApplication1\x64\Release\ConsoleApplication1.exe (процесс 33364) завершился с кодом -532462766.

Вот структура используемой dll:

Здесь класс ValidateLicense в .NET dll с функцией GetLicenseStatus(). Эта функция вызывается C++/CLI.

    public static class ValidateLicense
{
    public static string GetLicenseStatus()
    {
        return LicenseProvider.Instance.CheckLicense().ToString();
    }
}

Вот еще некоторые детали сборки SKCLNET:

В первом абзаце вы несколько раз упоминаете LicenseCheck.dll. Разве вы не имели в виду SKCLNET.dll по крайней мере в некоторых из них? Также можете показать структуру SKCLNET.dll? (на вашем скриншоте показана только LicenseCheck.dll).

wohlstad 10.02.2023 09:58

Кстати, о показе кода и т. д. в виде изображений см. здесь: meta.stackoverflow.com/questions/285551/….

wohlstad 10.02.2023 10:00
System.BadImageFormatException в 80 % случаев это связано с проблемами 32/64 бит. Убедитесь, что ваше приложение работает с теми же битами, что и библиотека.
JonasH 10.02.2023 10:00

В свойствах проекта > дополнительно > свойства C++/CLI. Установите поддержку Common Language Runtime, это может исправить это.

Kief 10.02.2023 10:02
stackoverflow.com/questions/72628522/…
Kief 10.02.2023 10:05

Хорошо получил его с изображением кода и удалил изображение. @wohlstand Я редактирую первый абзац, вы были правы. Когда я запускаю приложение с x86, оно выдает другую ошибку... Кажется, что LicenseCheck.sll — это x64, а SKCLNET.dll — это x86. Но, как я упоминал в вопросе, он работает, когда я запускаю его в проекте .NET с x64.

Felix D 10.02.2023 13:03

@wohlstand: см. скриншот обновленной структуры SKCLNET.dll.

Felix D 10.02.2023 13:05

Когда я запускаю приложение формы Windows, ошибка исчезает, когда я устанавливаю флажок в свойствах решения -> Сборка -> Общие -> Предпочитать 32-разрядную версию. Если этот параметр не отмечен, я получаю ту же ошибку, что и в проекте C++CLR. Кто-нибудь знает, как я могу установить этот параметр в проекте C++CLR? Варианты недвижимости совершенно разные.

Felix D 10.02.2023 15:01

Вы продолжаете называть SKCLNET.dll «встроенной» dll. Что это вообще значит? Если это управляемая сборка, для какой архитектуры она создана?

Mark Benningfield 10.02.2023 18:49

Название «встроенный» явно вводит в заблуждение, поэтому я отредактировал его в вопросе. Я предпочитаю собирать его для архитектуры x86, потому что он также может работать на архитектуре x64 из-за обратной совместимости, как я понял - поправьте меня, если я ошибаюсь.

Felix D 10.02.2023 23:28

Вы должны создать смешанный проект C++/CLI для Win32 или x64, так как неуправляемый код должен быть скомпилирован для соответствующей платформы. Откройте «Диспетчер конфигураций» в VS и проверьте правильную целевую платформу.

Mark Benningfield 11.02.2023 03:31

«ConsoleApplication1\x64\Release\ConsoleApplication1.exe» дает убедительный намек на то, что вы используете 64-разрядную сборку файла .exe. И ясно, что SKCLNET требует 32-битного процесса. Кабум. Если проект .exe является проектом C#, используйте вкладку «Проект» > «Свойства» > «Сборка», предпочитая 32-разрядную проверку. Повторите для конфигурации Release.

Hans Passant 14.02.2023 13:52

@ Ханс Пассант, ты был прав. Утром я провел небольшое исследование о том, как правильно настроить цели платформы для моего проекта C++/CLI. После сборки проекта C++/CLI для 32-разрядной версии появляется следующая ошибка (я также установил в App.config «useLegacyV2RuntimeActivationPolicy» = true, потому что это помогло запустить его в проекте C#): Unhandled Exception: System.IO. FileLoadException: сборка в смешанном режиме создана для версии среды выполнения v1.0.3705 и не может быть загружена в среде выполнения 4.0 без дополнительной информации о конфигурации.

Felix D 14.02.2023 14:57

Почему я получаю эту ошибку в своем проекте C++/CLI, но не в проекте C#?

Felix D 14.02.2023 14:59
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
15
96
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

После двух дней исследований я, наконец, нашел проблему. Как писал @Hans Passant в комментариях, ошибка в вопросе вызвана тем, что я создал .exe для 64-разрядной версии, хотя для SKCLNET.dll требуется 32-разрядный процесс.

Поскольку SKCLNET.dll нацелен на .NET v1.0.3705, также необходимо было добавить файл app.config в проект C++/CLI и добавить тег useLegacyV2RuntimeActivationPolicy. Это параметр конфигурации в .NET Framework, который используется для управления политикой активации среды выполнения для приложений, использующих сборки смешанного режима. В .NET Framework 4 и более поздних версиях политика активации среды выполнения была изменена на новое поведение по умолчанию. Такое поведение по умолчанию может привести к сбою некоторых старых приложений, предназначенных для работы с более ранними версиями .NET Framework.

Последним важным шагом было копирование этого файла app.config после сборки по целевому пути. Для этого щелкните правой кнопкой мыши проект C++/CLI > Properties > Build -Events > Post-Build Event и для параметра Command Line вставьте следующую строку:

copy app.config "$(TargetPath).config"

Эта статья помогла решить мою проблему.

Другие вопросы по теме