На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
> Ошибка вызова из C# приложения метода из C++ CLR DLL
    Разработка ведётся в Windows 10 Prof 32bit в Visual Studio 2013.
    Есть тестовое WPF C# приложение, в котором на форме расположена всего одна кнопка. В решении в качестве подпроекта с именем TokenApi имеется С++ CLR DLL с одним методом Test(). В WPF приложении ссылка на С++ CLR DLL добавлена в Reference. При нажатии на кнопку в WPF приложении вызывается тестовый метод из DLL.
    В свойствах WPF C# приложения на вкладке "Build" в поле "Platform target" установлено значение "x86".
    В "Configuration Manager" в "Active solution platform" и у DLL стоит "Win32". У WPF приложения стоит "x86".
    При этом на 32 разрядной платформе всё работает, а на 64 разрядной возникает ошибка. Причём ошибка возникает на этапе создания класса, определённого в DLL, т. е. на строчке TokenApi.TokenApi tokenApi = new TokenApi.TokenApi() и не перехватывается блоком catch. В чём здесь дело?
    Я проверяю следующим образом: запускаю программу из директории на 32 разрядной платформе. Все работает. Затем эту же директорию копирую на компьютер с 64 разрядной платформой. Удалённо захожу на тот компьютер куда скопировал и запускаю там - не работает. Почему не понятно. Как тогда делать 32 разрядные приложения с C++ CLR DLL, чтобы они работали и на 64 разрядных платформах?

    Вот сообщение об ошибке в Event Viewer:

    Application: WpfApplication5.exe
    Framework Version: v4.0.30319
    Description: The process was terminated due to an unhandled exception.
    Exception Info: System.IO.FileNotFoundException
    Stack:
    at WpfApplication5.MainWindow.Button_Click(System.Object, System.Windows.RoutedEventArgs)
    at System.Windows.RoutedEventHandlerInfo.InvokeHandler(System.Object, System.Windows.RoutedEventArgs)
    at System.Windows.EventRoute.InvokeHandlersImpl(System.Object, System.Windows.RoutedEventArgs, Boolean)
    at System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject, System.Windows.RoutedEventArgs)
    at System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs)
    at System.Windows.Controls.Primitives.ButtonBase.OnClick()
    at System.Windows.Controls.Button.OnClick()
    at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs)
    at System.Windows.UIElement.OnMouseLeftButtonUpThunk(System.Object, System.Windows.Input.MouseButtonEventArgs)
    at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(System.Delegate, System.Object)
    at System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate, System.Object)
    at System.Windows.RoutedEventHandlerInfo.InvokeHandler(System.Object, System.Windows.RoutedEventArgs)
    at System.Windows.EventRoute.InvokeHandlersImpl(System.Object, System.Windows.RoutedEventArgs, Boolean)
    at System.Windows.UIElement.ReRaiseEventAs(System.Windows.DependencyObject, System.Windows.RoutedEventArgs, System.Windows.RoutedEvent)
    at System.Windows.UIElement.OnMouseUpThunk(System.Object, System.Windows.Input.MouseButtonEventArgs)
    at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(System.Delegate, System.Object)
    at System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate, System.Object)
    at System.Windows.RoutedEventHandlerInfo.InvokeHandler(System.Object, System.Windows.RoutedEventArgs)
    at System.Windows.EventRoute.InvokeHandlersImpl(System.Object, System.Windows.RoutedEventArgs, Boolean)
    at System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject, System.Windows.RoutedEventArgs)
    at System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs)
    at System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs, Boolean)
    at System.Windows.Input.InputManager.ProcessStagingArea()
    at System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs)
    at System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport)
    at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr, System.Windows.Input.InputMode, Int32, System.Windows.Input.RawMouseActions, Int32, Int32, Int32)
    at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr, MS.Internal.Interop.WindowMessage, IntPtr, IntPtr, Boolean ByRef)
    at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
    at MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
    at MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
    at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
    at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)
    at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)
    at MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef)
    at System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame)
    at System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame)
    at System.Windows.Threading.Dispatcher.Run()
    at System.Windows.Application.RunDispatcher(System.Object)
    at System.Windows.Application.RunInternal(System.Windows.Window)
    at System.Windows.Application.Run(System.Windows.Window)
    at System.Windows.Application.Run()
    at WpfApplication5.App.Main()

    Вот обработчик кнопки в WPF приложении:
    ExpandedWrap disabled
          private void Button_Click(object sender, RoutedEventArgs e)
          {
            try
            {
              TokenApi.TokenApi tokenApi = new TokenApi.TokenApi(); //Здесь падает
              tokenApi.Test();
              MessageBox.Show("Проверка завершилась успехом!");
            }
            catch (Exception ex)
            {
              MessageBox.Show(ex.Message, "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
            }
          }

    Вот класс в C++ CLR DLL:
    ExpandedWrap disabled
      // TokenApi.h
      #pragma once
       
      using namespace System;
       
      namespace TokenApi {
       
        public ref class TokenApi
        {
          public: TokenApi()
          {
          }
       
          public: int Test()
          {
            return 1;
          }
        };
      }
        Цитата Profi @

        Я пробовал разные комбинации, в том числе как и указано в статье, но не работает. Похоже на то, что в системе чего-то не хватает, т. к. я нашёл 64 разрядную машину, где всё работает нормально, т. е. ошибка загрузки не возникает. Как узнать что нужно доставить в системе?
        PS: На всех машинах с 64 битной ОС, где проводится проверка и возникает ошибка, были установлены:
        Microsoft Visual C++ 2013 Redistributable (x64) — 12.0.30501
        Microsoft Visual C++ 2013 Redistributable (x86) — 12.0.30501
          Оказалось, что дело было в том, что я проверял debug-версию, а для её работы требуются дебажные библиотеки msvcp120d.dll, msvcr120d.dll и др. Поэтому на машинах где не стояла Visual Studio происходила ошибка, т. к. этих библиотек в системе не было, а где была VS - ошибки не было. У release-версии таких проблем нет. Спасибо вопрос закрыт.
          1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
          0 пользователей:


          Рейтинг@Mail.ru
          [ Script execution time: 0,0192 ]   [ 15 queries used ]   [ Generated: 18.05.24, 05:47 GMT ]