wpf — продолжение саги о совместимости C # с неуправляемым переполнением стека

После дня, когда я буквально и метафорически ударился головой о стену, я умоляю о помощи:

У меня есть неуправляемый проект C ++, который скомпилирован как DLL. Давайте назовем это CPP Project. В настоящее время он работает в неуправляемой среде. Кроме того, я создал проект WPF, который будет называться Проект WPF. Этот проект является простым и в настоящее время почти пустым проектом. Он содержит одно окно, и я хочу, чтобы он использовал код из Проекта 1. Для этого я создал проект CLR C ++, который должен называться Interop Project и также скомпилирован как DLL.

Для простоты я приложу некоторый базовый код тестирования, который я сводил к основам.

CPP Project имеет следующие два файла тестирования:

tester.h

#pragma once
extern "C" class __declspec(dllexport) NativeTester
{
public:
void NativeTest();
};

tester.cpp

#include "tester.h"void NativeTester::NativeTest()
{
int i = 0;
}

Interop Project имеет следующий файл:

InteropLib.h

#pragma once
#include <tester.h>
using namespace System;
namespace InteropLib {
public ref class InteropProject
{
public:
static void Test()
{
NativeTester nativeTester;
nativeTester.NativeTest();
}
};
}

Наконец, в проекте WPF есть одно окно, ссылающееся на проект Interop:

MainWindow.xaml.cs

using System;
using System.Windows;
using InteropLib;
namespace AppGUI
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
InteropProject.Test();
}
}
}

И сам XAML имеет пустое окно (создано по умолчанию).

Когда я пытаюсь запустить проект WPF, я получаю следующую ошибку:

System.Windows.Markup.XamlParseException: ‘Вызов конструктора для типа’ AppGUI.MainWindow ‘, который соответствует указанным ограничениям связывания, вызвал исключение.’ Номер строки «3» и позиция «9». —> System.IO.FileNotFoundException: Не удалось загрузить файл или сборку InteropLib.dll или одну из ее зависимостей. Указанный модуль не может быть найден.
в AppGUI.MainWindow..ctor ()

Интересно, что если я не экспортирую класс из CPP Project, я не получу эту ошибку. Скажи, если я изменюсь tester.h чтобы:

#pragma once
class NativeTester
{
public:
void NativeTest()
{
int i = 0;
}
};

Однако в этом случае я не могу использовать свои более сложные классы. Если я перенесу свою реализацию в файл cpp, как и раньше, я получу неразрешенные ошибки компоновки из-за того, что я не экспортировал свой код. Код C ++, который я на самом деле хочу использовать, большой, имеет много классов и объектно-ориентированный, поэтому я не могу просто перенести всю свою реализацию в h-файлы.

Пожалуйста, помогите мне понять эту ужасную ошибку, которую я пытался решить без успеха.

Благодарю.

4

Решение

Это пошло не так с самого начала, ваш файл tester.h неверен. Класс должен иметь атрибут __declspec (dllexport) только при создании проекта тестера. любой Другой Проект, который использует DLL, должен видеть класс с атрибутом __declspec (dllimport). Начните исправлять это с помощью макроса в tester.h:

#undef EXPORTED
#ifdef BUILDING_DLL
#   define EXPORTED __declspec(dllexport)
#else
#   define EXPORTED __declspec(dllimport)
#endif

class EXPORTED NativeTester {
// etc..
};

А в своем проекте тестера используйте C / C ++, Препроцессор, Определения препроцессора и добавьте BUILDING_DLL.

Далее нужно убедиться, что DLL хранится в правильном каталоге. На что жалуется исключение, он не может найти DLL. Каталог сборки для проектов C ++ — Debug, но для проектов WPF — bin \ Debug. Исправьте это, изменив настройки General + Output Directory, сделайте это $(SolutionDir)$bin\(ConfigurationName),

Создайте проект C ++ и убедитесь, что вы можете найти DLL обратно в каталоге bin \ Debug решения. И убедитесь, что у вас также есть файл .lib, он вам понадобится при сборке проекта C ++ / CLI. В качестве дополнительного шага проверки запустите Dumpbin.exe / exports foo.dll из командной строки Visual Studio и убедитесь, что класс действительно экспортируется.

Далее проект C ++ / CLI, вам нужно изменить настройку Output Directory таким же образом. Добавьте файл .lib в свойства дополнительных зависимостей компоновщика. Если вы пропустите этот шаг, вы получите ошибки компоновщика, о которых вы говорили. Постройте его и убедитесь, что вы снова получите DLL в правильном каталоге bin \ Debug.

Повторите эти изменения для конфигурации выпуска.

Установите зависимости проекта, проект WPF зависит от проекта C ++ / CLI. Проект C ++ / CLI зависит от проекта C ++. Это гарантирует, что проекты строятся в правильном порядке.

Теперь вы должны иметь хороший шанс использовать эти библиотеки DLL в своем проекте WPF.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]