powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Ошибка вызова из C# приложения метода из C++ CLR DLL
18 сообщений из 18, страница 1 из 1
Ошибка вызова из C# приложения метода из C++ CLR DLL
    #39329051
Degun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Разработка ведётся в 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. В чём здесь дело?

Вот сообщение об ошибке в Event Viewer:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
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 приложении:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
    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:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
// TokenApi.h
#pragma once

using namespace System;

namespace TokenApi {

  public ref class TokenApi
  {
    public: TokenApi()
    {
    }

    public: int Test()
    {
      return 1;
    }
  };
}
...
Рейтинг: 0 / 0
Ошибка вызова из C# приложения метода из C++ CLR DLL
    #39329150
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Degun,

Вроде DLL не находит
...
Рейтинг: 0 / 0
Ошибка вызова из C# приложения метода из C++ CLR DLL
    #39329158
Degun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Cat2,

А почему? На 32 разрядной платформе находит, а на 64 нет. Вроде бы я везде в проекте указал, что это 32 разрядное приложение и на 64 платформе вроде бы проблем не должно быть.
...
Рейтинг: 0 / 0
Ошибка вызова из C# приложения метода из C++ CLR DLL
    #39329206
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
DegunА почему?
К сожалению я не вхожу в пул разработчиков МС и не знаю почему.

Попробуйте все скомпилировать под AnyCPU
...
Рейтинг: 0 / 0
Ошибка вызова из C# приложения метода из C++ CLR DLL
    #39329228
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DegunА почему?
проверьте расположение dll/exe - вполне возможно - не лежат они рядышком после билда
...
Рейтинг: 0 / 0
Ошибка вызова из C# приложения метода из C++ CLR DLL
    #39329362
Degun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил,

Я проверяю следующим образом: запускаю программу из директории на 32 разрядной платформе. Все работает. Затем эту же директорию копирую на компьютер с 64 разрядной платформой. Удалённо захожу на тот компьютер и запускаю там - не работает. Почему не понятно. Как тогда делать 32 разрядные приложения с C++ CLR DLL, чтобы они работали и на 64 разрядных платформах?
...
Рейтинг: 0 / 0
Ошибка вызова из C# приложения метода из C++ CLR DLL
    #39329380
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
DegunКак тогда делать 32 разрядные приложения с C++ CLR DLL, чтобы они работали и на 64 разрядных платформах?
Cat2Попробуйте все скомпилировать под AnyCPU
...
Рейтинг: 0 / 0
Ошибка вызова из C# приложения метода из C++ CLR DLL
    #39329418
Degun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Cat2,

При компиляции под AnyCPU также падает.
...
Рейтинг: 0 / 0
Ошибка вызова из C# приложения метода из C++ CLR DLL
    #39329495
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
DegunЗатем эту же директорию копирую на компьютер с 64 разрядной платформой. Удалённо захожу на тот компьютер и запускаю там - не работает.
А если копируете на 32, работает?
...
Рейтинг: 0 / 0
Ошибка вызова из C# приложения метода из C++ CLR DLL
    #39329536
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Degun,

включите Fusion Log Viewer , запустите программу на x64, и посмотрите в логе, откуда процесс пытается загрузить вашу dll.
...
Рейтинг: 0 / 0
Ошибка вызова из C# приложения метода из C++ CLR DLL
    #39329656
Degun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сон Веры Павловны,

На компьютере с 64-ой ОС, где проводится тестирование, Visual Studio не установлена. Поэтому запустить Fusion Log Viewer там я вроде как не могу.
...
Рейтинг: 0 / 0
Ошибка вызова из C# приложения метода из C++ CLR DLL
    #39329658
Degun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Cat2,

Одна и та же программа на 32-х разрядной ОС работает, а на 64-х разрядной ОС нет.
...
Рейтинг: 0 / 0
Ошибка вызова из C# приложения метода из C++ CLR DLL
    #39329696
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DegunСон Веры Павловны,

На компьютере с 64-ой ОС, где проводится тестирование, Visual Studio не установлена. Поэтому запустить Fusion Log Viewer там я вроде как не могу.
Вполне можно. Из папки Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\x64\ копируете FUSLOGVW.exe и папку 1033 с файлом flogvwrc.dll. На компьютере с х64 запускаете FUSLOGVW.exe под администратором, конфигурируете расположение лога и прочие параметры, запускаете вашу программу, в окне FUSLOGVW жмете кнопку Refresh. Всё. Было проверено не раз на компьютерах, где VS отродясь не бывало.
...
Рейтинг: 0 / 0
Ошибка вызова из C# приложения метода из C++ CLR DLL
    #39329782
Degun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сон Веры ПавловныВполне можно. Из папки Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\x64\ копируете FUSLOGVW.exe и папку 1033 с файлом flogvwrc.dll. На компьютере с х64 запускаете FUSLOGVW.exe под администратором, конфигурируете расположение лога и прочие параметры, запускаете вашу программу, в окне FUSLOGVW жмете кнопку Refresh. Всё. Было проверено не раз на компьютерах, где VS отродясь не бывало.

Причина, как выяснилось, не в том, что программа не находит DLL. Стал грузить DLL динамически с точным указанием пути к библиотеке - ошибка загрузки осталась.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
    //Проверка
    private void Button_Click(object sender, RoutedEventArgs e)
    {
      try
      {
        int iResult = 0;
        if (Environment.Is64BitProcess)
        {
          MessageBox.Show("Требуется 64 разрядная DLL!");
          //var tokenApi = new TokenApi64.TokenApi64();
          //iResult = tokenApi.Test();
          string sDllPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
          sDllPath = Path.Combine(sDllPath,"TokenApi64.dll");
          MessageBox.Show("Путь = " + sDllPath);
          Assembly asm = Assembly.LoadFrom(sDllPath);
          Type t = asm.GetType("TokenApi64.TokenApi64", true, true);
          object obj = Activator.CreateInstance(t);
          MethodInfo method = t.GetMethod("Test");
          object result = method.Invoke(obj, null);
          iResult = (int)result;
        }
        else
        {
          MessageBox.Show("Требуется 32 разрядная DLL!");
          //TokenApi32.TokenApi32 tokenApi = new TokenApi32.TokenApi32();
          //iResult = tokenApi.Test();
          string sDllPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
          sDllPath = Path.Combine(sDllPath, "TokenApi32.dll");
          MessageBox.Show("Путь = " + sDllPath);
          Assembly asm = Assembly.LoadFrom(sDllPath);
          Type t = asm.GetType("TokenApi32.TokenApi32", true, true);
          object obj = Activator.CreateInstance(t);
          MethodInfo method = t.GetMethod("Test");
          object result = method.Invoke(obj, null);
          iResult = (int)result;
        }
        if (iResult == 1)
        {
          MessageBox.Show("Проверка прошла успешно!");
        }
        else
        {
          MessageBox.Show("Проверка не завершилась успехом!");
        }
      }
      catch (Exception ex)
      {
        MessageBox.Show(ex.Message, "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
      }
    }



Похоже на то, что в системе чего-то не хватает. Нашёл 64 разрядную машину, где всё работает нормально. Как узнать что нужно доставить в системе?
PS: На всех машинах с 64 битной ОС, где проводится проверка и возникает ошибка, были установлены:
Microsoft Visual C++ 2013 Redistributable (x64) — 12.0.30501
Microsoft Visual C++ 2013 Redistributable (x86) — 12.0.30501
...
Рейтинг: 0 / 0
Ошибка вызова из C# приложения метода из C++ CLR DLL
    #39329847
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DegunПричина, как выяснилось, не в том, что программа не находит DLL.
Может, в библиотеке все-таки не просто класс с одним методом?
FileNotFoundException - managed-исключение, и возникает только при загрузке managed-библиотек (при пинвоках к несуществующим библиотекам вместо FileNotFoundException выбрасывается System.DllNotFoundException: Исключение из HRESULT: 0x8007007E - что-то типа такого), так что не смотрите в сторону unmanaged-билиотек, у вас затык в managed.
И да, что же показал FUSLOGVW?
...
Рейтинг: 0 / 0
Ошибка вызова из C# приложения метода из C++ CLR DLL
    #39329942
Degun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сон Веры ПавловныИ да, что же показал FUSLOGVW?
Вот по поводу загрузки библиотеки TokenApi64.dll
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
*** Assembly Binder Log Entry  (19.10.2016 @ 15:17:00) ***

The operation was successful.
Bind result: hr = 0x1. Incorrect function.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  D:\Debug6\WpfApplication6.exe
--- A detailed error log follows. 

BEGIN : Native image bind.
END   : Incorrect function. (Exception from HRESULT: 0x00000001 (S_FALSE))


*** Assembly Binder Log Entry  (19.10.2016 @ 15:17:00) ***

The operation was successful.
Bind result: hr = 0x0. The operation completed successfully.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  D:\Debug6\WpfApplication6.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: DisplayName = TokenApi64, Version=1.0.6136.23225, Culture=neutral, PublicKeyToken=null
 (Fully-specified)
LOG: Appbase = file:///D:/Debug6/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = WpfApplication6.exe
Calling assembly : WpfApplication6, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
WRN: No matching native image found.
LOG: IL assembly loaded from D:\Debug6\TokenApi64.dll.
...
Рейтинг: 0 / 0
Ошибка вызова из C# приложения метода из C++ CLR DLL
    #39329969
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DegunСон Веры ПавловныИ да, что же показал FUSLOGVW?
Вот по поводу загрузки библиотеки TokenApi64.dll
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Bind result: hr = 0x1. Incorrect function.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  D:\Debug6\WpfApplication6.exe
--- A detailed error log follows. 

BEGIN : Native image bind.
END   : Incorrect function. (Exception from HRESULT: 0x00000001 (S_FALSE))

http://stackoverflow.com/questions/28252484/fusion-log-assembly-binder-error-bind-result-hr-0x1-incorrect-function :
The actual error code is S_FALSE, a COM error code that means "it successfully failed". Which is why it says The operation was successful . Misinterpreted for the diagnostic message as "Function failed", that's the description for Windows error 1 and returned by the FormatMessage() winapi function.
...
Рейтинг: 0 / 0
Ошибка вызова из C# приложения метода из C++ CLR DLL
    #39331092
Degun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Оказалось, что дело было в том, что я проверял debug-версию, а для её работы требуются дебажные библиотеки msvcp120d.dll, msvcr120d.dll и др. Поэтому на машинах где не стояла Visual Studio происходила ошибка, т. к. этих библиотек в системе не было, а где была VS - ошибки не было. У release-версии таких проблем нет. Спасибо вопрос закрыт.
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Ошибка вызова из C# приложения метода из C++ CLR DLL
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]