本机 C++ 程序在使用 C++/CLI 和 C# 互操作 DLL 启动时崩溃
Native C++ program crashes on startup with C++/CLI & C# interop DLL
我现在需要将 C# WPF UserControls 包装在 C++/CLI 包装器中,以便在本机 C++ 程序中使用。本机程序大量使用MFC,在VS2010中编译。我已经在单独的解决方案中正确生成了 C++/CLI .lib 和 .dll 文件,并从 MFC 应用程序链接到它们,它成功编译和链接,照常生成可执行文件。但是,当我启动 MFC 应用程序时,我什至在它到达 main() 之前收到访问冲突错误 0xc0000005。当我注释掉包装代码时,程序正常启动。
为了尝试隔离问题,我尝试创建一个完全独立的本机 C++ 项目,其唯一目的是使用虚拟数据调用包装器 class。该项目到达 main() 但在我调用包装器 class.
的构造函数时抛出异常 (0xe0434352)
我已经尝试搜索任何可能的解决方案,但最符合我的情况的是检查函数签名以确保我传递了正确数量的参数(我是)。我还从独立项目中查找了 0xe0434352 异常,它似乎是一个通用的 .NET 异常。
我还看到了 question posted, but was hoping the solution would be simpler than that. I've been following the instructions on this 创建包装器的博客 class。
我包括了除 MFC 应用程序代码之外的所有代码,因为它甚至没有加载到 main()。我希望如果我能设法解决全新项目中的问题,MFC 应用程序将启动。
C# WPF:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace ManagedWPFLink
{
public struct TestResultData
{
public string inspectionType;
public string testResult;
public string measuredValue;
public string passCondition;
public string comments;
}
/// <summary>
/// Interaction logic for TestResultsDialog.xaml
/// </summary>
public partial class TestResultsDialog : UserControl
{
private Window window;
public TestResultsDialog()
{
InitializeComponent();
DataGridTextColumn col1 = new DataGridTextColumn();
DataGridTextColumn col2 = new DataGridTextColumn();
DataGridTextColumn col3 = new DataGridTextColumn();
DataGridTextColumn col4 = new DataGridTextColumn();
DataGridTextColumn col5 = new DataGridTextColumn();
this.testResultsGrid.Columns.Add(col1);
this.testResultsGrid.Columns.Add(col2);
this.testResultsGrid.Columns.Add(col3);
this.testResultsGrid.Columns.Add(col4);
this.testResultsGrid.Columns.Add(col5);
col1.Binding = new Binding("inspectionType");
col2.Binding = new Binding("testResult");
col3.Binding = new Binding("measuredValue");
col4.Binding = new Binding("passCondition");
col5.Binding = new Binding("comments");
col1.Header = "Inspection Type";
col2.Header = "Test Result";
col3.Header = "Measured Value";
col4.Header = "Pass Condition";
col5.Header = "Comments";
this.window = new Window
{
Title = "Inspection Results",
Content = this,
SizeToContent = SizeToContent.WidthAndHeight,
ResizeMode = ResizeMode.NoResize
};
}
public void addRow(string inspectionType, string testResult, string measuredValue, string passCondition, string comments)
{
TestResultData data = new TestResultData();
data.inspectionType = inspectionType;
data.testResult = testResult;
data.measuredValue = measuredValue;
data.passCondition = passCondition;
data.comments = comments;
this.testResultsGrid.Items.Add(data);
}
public void deleteAllRows()
{
this.testResultsGrid.Items.Clear();
}
public void showDialog()
{
this.window.ShowDialog();
}
}
}
C#XAML:
<UserControl x:Class="ManagedWPFLink.TestResultsDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="400" d:DesignWidth="600">
<Grid>
<DataGrid AutoGenerateColumns="True" Height="376" HorizontalAlignment="Left" Margin="12,12,0,0" Name="testResultsGrid" VerticalAlignment="Top" Width="576" ItemsSource="{Binding}" MinColumnWidth="40">
</DataGrid>
</Grid>
</UserControl>
C++/CLI header:
// ManagedWPFLink.h
#pragma once
namespace WPFLink
{
class WPFPrivate;
class __declspec(dllexport) WPFWrapper
{
private:
WPFPrivate *internalWrapper;
public:
WPFWrapper();
~WPFWrapper();
void addItems(const char **data);
void deleteAllRows();
void showDialog();
};
}
C++/CLI 源代码:
// This is the main DLL file.
#include "stdafx.h"
#using <WindowsBase.dll>
#using <PresentationCore.dll>
#using <PresentationFramework.dll>
#using "ManagedWPFLink.dll"
#include "WPFLink.h"
using namespace System::Runtime::InteropServices;
namespace WPFLink
{
public class WPFPrivate
{
public:
msclr::auto_gcroot<System::String^> inspectionType;
msclr::auto_gcroot<System::String^> testResult;
msclr::auto_gcroot<System::String^> measuredValue;
msclr::auto_gcroot<System::String^> passCondition;
msclr::auto_gcroot<System::String^> comments;
msclr::auto_gcroot<ManagedWPFLink::TestResultsDialog^> testResultDialog;
public:
WPFPrivate()
{
}
~WPFPrivate()
{
delete testResultDialog;
}
};
WPFWrapper::WPFWrapper()
{
this->internalWrapper = new WPFLink::WPFPrivate();
}
WPFWrapper::~WPFWrapper()
{
delete this->internalWrapper;
}
void WPFWrapper::addItems(const char **data)
{
this->internalWrapper->inspectionType = gcnew System::String(data[0]);
this->internalWrapper->testResult = gcnew System::String(data[1]);
this->internalWrapper->measuredValue = gcnew System::String(data[2]);
this->internalWrapper->passCondition = gcnew System::String(data[3]);
this->internalWrapper->comments = gcnew System::String(data[4]);
this->internalWrapper->testResultDialog->addRow(this->internalWrapper->inspectionType, this->internalWrapper->testResult,
this->internalWrapper->measuredValue, this->internalWrapper->passCondition, this->internalWrapper->comments);
}
void WPFWrapper::deleteAllRows()
{
this->internalWrapper->testResultDialog->deleteAllRows();
}
void WPFWrapper::showDialog()
{
this->internalWrapper->testResultDialog->showDialog();
}
}
本机 C++ 代码:
#include "..\WPFLink\WPFLink.h"
int main()
{
WPFLink::WPFWrapper wrapper; // Generates 0xe0434352 error
return 0;
}
经过多次纠缠,我在这里使用了post中的方法:http://www.codeguru.com/cpp/cpp/cpp_managed/nfc/article.php/c14589/Hosting-WPF-Content-in-an-MFC-Application.htm
我使用相关代码生成了一个 HWND,该程序与我自己的本机 C++ 代码完美配合。但是,我仍然 运行 在我们的主 MFC 应用程序启动时遇到访问冲突,我根本没有设法缩小范围。我所掌握的唯一信息是,如果我尝试 link 我的 DLL,程序就会崩溃。我将不得不放弃这种 linking 到存根 .lib 文件并加载必要的 DLL 的方法,而是重做接口以仅使用 extern "C" 函数并在我的 DLL 上手动调用 LoadLibrary。
感谢所有试图提供帮助的人。
我现在需要将 C# WPF UserControls 包装在 C++/CLI 包装器中,以便在本机 C++ 程序中使用。本机程序大量使用MFC,在VS2010中编译。我已经在单独的解决方案中正确生成了 C++/CLI .lib 和 .dll 文件,并从 MFC 应用程序链接到它们,它成功编译和链接,照常生成可执行文件。但是,当我启动 MFC 应用程序时,我什至在它到达 main() 之前收到访问冲突错误 0xc0000005。当我注释掉包装代码时,程序正常启动。
为了尝试隔离问题,我尝试创建一个完全独立的本机 C++ 项目,其唯一目的是使用虚拟数据调用包装器 class。该项目到达 main() 但在我调用包装器 class.
的构造函数时抛出异常 (0xe0434352)我已经尝试搜索任何可能的解决方案,但最符合我的情况的是检查函数签名以确保我传递了正确数量的参数(我是)。我还从独立项目中查找了 0xe0434352 异常,它似乎是一个通用的 .NET 异常。
我还看到了
我包括了除 MFC 应用程序代码之外的所有代码,因为它甚至没有加载到 main()。我希望如果我能设法解决全新项目中的问题,MFC 应用程序将启动。
C# WPF:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace ManagedWPFLink
{
public struct TestResultData
{
public string inspectionType;
public string testResult;
public string measuredValue;
public string passCondition;
public string comments;
}
/// <summary>
/// Interaction logic for TestResultsDialog.xaml
/// </summary>
public partial class TestResultsDialog : UserControl
{
private Window window;
public TestResultsDialog()
{
InitializeComponent();
DataGridTextColumn col1 = new DataGridTextColumn();
DataGridTextColumn col2 = new DataGridTextColumn();
DataGridTextColumn col3 = new DataGridTextColumn();
DataGridTextColumn col4 = new DataGridTextColumn();
DataGridTextColumn col5 = new DataGridTextColumn();
this.testResultsGrid.Columns.Add(col1);
this.testResultsGrid.Columns.Add(col2);
this.testResultsGrid.Columns.Add(col3);
this.testResultsGrid.Columns.Add(col4);
this.testResultsGrid.Columns.Add(col5);
col1.Binding = new Binding("inspectionType");
col2.Binding = new Binding("testResult");
col3.Binding = new Binding("measuredValue");
col4.Binding = new Binding("passCondition");
col5.Binding = new Binding("comments");
col1.Header = "Inspection Type";
col2.Header = "Test Result";
col3.Header = "Measured Value";
col4.Header = "Pass Condition";
col5.Header = "Comments";
this.window = new Window
{
Title = "Inspection Results",
Content = this,
SizeToContent = SizeToContent.WidthAndHeight,
ResizeMode = ResizeMode.NoResize
};
}
public void addRow(string inspectionType, string testResult, string measuredValue, string passCondition, string comments)
{
TestResultData data = new TestResultData();
data.inspectionType = inspectionType;
data.testResult = testResult;
data.measuredValue = measuredValue;
data.passCondition = passCondition;
data.comments = comments;
this.testResultsGrid.Items.Add(data);
}
public void deleteAllRows()
{
this.testResultsGrid.Items.Clear();
}
public void showDialog()
{
this.window.ShowDialog();
}
}
}
C#XAML:
<UserControl x:Class="ManagedWPFLink.TestResultsDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="400" d:DesignWidth="600">
<Grid>
<DataGrid AutoGenerateColumns="True" Height="376" HorizontalAlignment="Left" Margin="12,12,0,0" Name="testResultsGrid" VerticalAlignment="Top" Width="576" ItemsSource="{Binding}" MinColumnWidth="40">
</DataGrid>
</Grid>
</UserControl>
C++/CLI header:
// ManagedWPFLink.h
#pragma once
namespace WPFLink
{
class WPFPrivate;
class __declspec(dllexport) WPFWrapper
{
private:
WPFPrivate *internalWrapper;
public:
WPFWrapper();
~WPFWrapper();
void addItems(const char **data);
void deleteAllRows();
void showDialog();
};
}
C++/CLI 源代码:
// This is the main DLL file.
#include "stdafx.h"
#using <WindowsBase.dll>
#using <PresentationCore.dll>
#using <PresentationFramework.dll>
#using "ManagedWPFLink.dll"
#include "WPFLink.h"
using namespace System::Runtime::InteropServices;
namespace WPFLink
{
public class WPFPrivate
{
public:
msclr::auto_gcroot<System::String^> inspectionType;
msclr::auto_gcroot<System::String^> testResult;
msclr::auto_gcroot<System::String^> measuredValue;
msclr::auto_gcroot<System::String^> passCondition;
msclr::auto_gcroot<System::String^> comments;
msclr::auto_gcroot<ManagedWPFLink::TestResultsDialog^> testResultDialog;
public:
WPFPrivate()
{
}
~WPFPrivate()
{
delete testResultDialog;
}
};
WPFWrapper::WPFWrapper()
{
this->internalWrapper = new WPFLink::WPFPrivate();
}
WPFWrapper::~WPFWrapper()
{
delete this->internalWrapper;
}
void WPFWrapper::addItems(const char **data)
{
this->internalWrapper->inspectionType = gcnew System::String(data[0]);
this->internalWrapper->testResult = gcnew System::String(data[1]);
this->internalWrapper->measuredValue = gcnew System::String(data[2]);
this->internalWrapper->passCondition = gcnew System::String(data[3]);
this->internalWrapper->comments = gcnew System::String(data[4]);
this->internalWrapper->testResultDialog->addRow(this->internalWrapper->inspectionType, this->internalWrapper->testResult,
this->internalWrapper->measuredValue, this->internalWrapper->passCondition, this->internalWrapper->comments);
}
void WPFWrapper::deleteAllRows()
{
this->internalWrapper->testResultDialog->deleteAllRows();
}
void WPFWrapper::showDialog()
{
this->internalWrapper->testResultDialog->showDialog();
}
}
本机 C++ 代码:
#include "..\WPFLink\WPFLink.h"
int main()
{
WPFLink::WPFWrapper wrapper; // Generates 0xe0434352 error
return 0;
}
经过多次纠缠,我在这里使用了post中的方法:http://www.codeguru.com/cpp/cpp/cpp_managed/nfc/article.php/c14589/Hosting-WPF-Content-in-an-MFC-Application.htm
我使用相关代码生成了一个 HWND,该程序与我自己的本机 C++ 代码完美配合。但是,我仍然 运行 在我们的主 MFC 应用程序启动时遇到访问冲突,我根本没有设法缩小范围。我所掌握的唯一信息是,如果我尝试 link 我的 DLL,程序就会崩溃。我将不得不放弃这种 linking 到存根 .lib 文件并加载必要的 DLL 的方法,而是重做接口以仅使用 extern "C" 函数并在我的 DLL 上手动调用 LoadLibrary。
感谢所有试图提供帮助的人。