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

Вот сообщение об ошибке в 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
18.10.2016, 16:55
    #39329150
Cat2
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка вызова из C# приложения метода из C++ CLR DLL
Degun,

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

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

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

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

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

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

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

Одна и та же программа на 32-х разрядной ОС работает, а на 64-х разрядной ОС нет.
...
Рейтинг: 0 / 0
19.10.2016, 12:21
    #39329696
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка вызова из C# приложения метода из C++ CLR DLL
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
19.10.2016, 13:20
    #39329782
Degun
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка вызова из C# приложения метода из C++ CLR DLL
Сон Веры ПавловныВполне можно. Из папки 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
19.10.2016, 14:08
    #39329847
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка вызова из C# приложения метода из C++ CLR DLL
DegunПричина, как выяснилось, не в том, что программа не находит DLL.
Может, в библиотеке все-таки не просто класс с одним методом?
FileNotFoundException - managed-исключение, и возникает только при загрузке managed-библиотек (при пинвоках к несуществующим библиотекам вместо FileNotFoundException выбрасывается System.DllNotFoundException: Исключение из HRESULT: 0x8007007E - что-то типа такого), так что не смотрите в сторону unmanaged-билиотек, у вас затык в managed.
И да, что же показал FUSLOGVW?
...
Рейтинг: 0 / 0
19.10.2016, 15:29
    #39329942
Degun
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка вызова из C# приложения метода из C++ CLR DLL
Сон Веры ПавловныИ да, что же показал 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
19.10.2016, 15:50
    #39329969
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка вызова из C# приложения метода из C++ CLR DLL
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
20.10.2016, 22:06
    #39331092
Degun
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка вызова из C# приложения метода из C++ CLR DLL
Оказалось, что дело было в том, что я проверял debug-версию, а для её работы требуются дебажные библиотеки msvcp120d.dll, msvcr120d.dll и др. Поэтому на машинах где не стояла Visual Studio происходила ошибка, т. к. этих библиотек в системе не было, а где была VS - ошибки не было. У release-версии таких проблем нет. Спасибо вопрос закрыт.
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Ошибка вызова из C# приложения метода из C++ CLR DLL / 18 сообщений из 18, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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