C# DllImport 意外崩溃
C# DllImport crashes unexpectedly
我有一个带有 C++ 组件的 C# 应用程序。我在模块之间与 DllImport
通信。该应用程序可以正常工作很多天,有时会意外崩溃。
[DllImport("recorder", CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr start_recording();
是否可以 运行 受保护容器中的 C++ 部分,以免整个应用程序崩溃?
事件查看器
Application Error
Faulting application name: Recorder.exe, version: 1.0.0.0, time stamp: 0x59eef7cb
Faulting module name: avformat-57.dll, version: 57.71.100.0, time stamp: 0x00000000
Exception code: 0xc0000005
Fault offset: 0x00000000000d7e7f
Faulting process id: 0x186c
Faulting application start time: 0x01d3620b7e41ef96
Faulting application path: C:\Test\Recorder.exe
Faulting module path: C:\Test\avformat-57.dll
Report Id: 3fde49fc-d2ed-11e7-bf5c-002590abb7d4
.NET Runtime
Application: Recorder.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: exception code c0000005, exception address 000007FEEA407E7F
一般来说,有一些情况总是会导致进程退出,而你与它无关。
虽然您可以通过捕获异常、设置信号处理程序或只是修复错误来处理一些错误,但这只会修复特定情况,不会为您提供通用解决方案,而且您可能不这样做完全控制模块。
这种情况下的常见解决方案是将模块分离到不同的代理进程中,该代理进程将与您自己的应用程序进行通信。
在这里您可以找到 Interprocess Communications
的更多信息
我决定使用 NamedPipes 非常快,我可以双向通信。
C++ 示例
cout << "Connecting to pipe..." << endl;
// Open the named pipe
// Most of these parameters aren't very relevant for pipes.
HANDLE pipe = CreateFile(
L"\\.\pipe\MyServerPipe",
GENERIC_READ, // only need read access
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
//NULL,
NULL
);
if (pipe == INVALID_HANDLE_VALUE) {
cout << "Failed to connect to pipe." << endl;
// look up error code here using GetLastError()
system("pause");
return 1;
}
cout << "Reading data from pipe..." << endl;
// The read operation will block until there is data to read
char buffer[128];
DWORD numBytesRead = 0;
BOOL result = ReadFile(
pipe,
buffer, // the data from the pipe will be put here
127 * sizeof(char), // number of bytes allocated
&numBytesRead, // this will store number of bytes actually read
NULL // not using overlapped IO
);
if (result) {
buffer[numBytesRead / sizeof(char)] = '[=10=]'; // null terminate the string
cout << "Number of bytes read: " << numBytesRead << endl;
//wcout << "Message: " << buffer << endl;
//wstring ws(buffer);
//string str(ws.begin(), ws.end());
cout << "Test:" << buffer << endl;
}
else {
wcout << "Failed to read data from the pipe." << endl;
}
// Close our pipe handle
CloseHandle(pipe);
//wcout << "Done." << endl;
system("pause");
return 0;
C#获取所有可用的管道
var listOfPipes = System.IO.Directory.GetFiles(@"\.\pipe\")
C# 示例
using (var pipeServer = new NamedPipeServerStream("MyServerPipe", PipeDirection.InOut))
{
Console.WriteLine("NamedPipeServerStream object created.");
// Wait for a client to connect
Console.Write("Waiting for client connection...");
pipeServer.WaitForConnection();
Console.WriteLine("Client connected.");
try
{
using (var bw = new BinaryWriter(pipeServer))
{
var data = Encoding.ASCII.GetBytes("SendInformation data1 data2 data3");
//var data = Encoding.ASCII.GetBytes("Start\r\n");
bw.Write(data);
}
}
// Catch the IOException that is raised if the pipe is broken
// or disconnected.
catch (IOException e)
{
Console.WriteLine("ERROR: {0}", e.Message);
}
}
我有一个带有 C++ 组件的 C# 应用程序。我在模块之间与 DllImport
通信。该应用程序可以正常工作很多天,有时会意外崩溃。
[DllImport("recorder", CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr start_recording();
是否可以 运行 受保护容器中的 C++ 部分,以免整个应用程序崩溃?
事件查看器
Application Error
Faulting application name: Recorder.exe, version: 1.0.0.0, time stamp: 0x59eef7cb
Faulting module name: avformat-57.dll, version: 57.71.100.0, time stamp: 0x00000000
Exception code: 0xc0000005
Fault offset: 0x00000000000d7e7f
Faulting process id: 0x186c
Faulting application start time: 0x01d3620b7e41ef96
Faulting application path: C:\Test\Recorder.exe
Faulting module path: C:\Test\avformat-57.dll
Report Id: 3fde49fc-d2ed-11e7-bf5c-002590abb7d4
.NET Runtime
Application: Recorder.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: exception code c0000005, exception address 000007FEEA407E7F
一般来说,有一些情况总是会导致进程退出,而你与它无关。
虽然您可以通过捕获异常、设置信号处理程序或只是修复错误来处理一些错误,但这只会修复特定情况,不会为您提供通用解决方案,而且您可能不这样做完全控制模块。
这种情况下的常见解决方案是将模块分离到不同的代理进程中,该代理进程将与您自己的应用程序进行通信。
在这里您可以找到 Interprocess Communications
的更多信息我决定使用 NamedPipes 非常快,我可以双向通信。
C++ 示例
cout << "Connecting to pipe..." << endl;
// Open the named pipe
// Most of these parameters aren't very relevant for pipes.
HANDLE pipe = CreateFile(
L"\\.\pipe\MyServerPipe",
GENERIC_READ, // only need read access
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
//NULL,
NULL
);
if (pipe == INVALID_HANDLE_VALUE) {
cout << "Failed to connect to pipe." << endl;
// look up error code here using GetLastError()
system("pause");
return 1;
}
cout << "Reading data from pipe..." << endl;
// The read operation will block until there is data to read
char buffer[128];
DWORD numBytesRead = 0;
BOOL result = ReadFile(
pipe,
buffer, // the data from the pipe will be put here
127 * sizeof(char), // number of bytes allocated
&numBytesRead, // this will store number of bytes actually read
NULL // not using overlapped IO
);
if (result) {
buffer[numBytesRead / sizeof(char)] = '[=10=]'; // null terminate the string
cout << "Number of bytes read: " << numBytesRead << endl;
//wcout << "Message: " << buffer << endl;
//wstring ws(buffer);
//string str(ws.begin(), ws.end());
cout << "Test:" << buffer << endl;
}
else {
wcout << "Failed to read data from the pipe." << endl;
}
// Close our pipe handle
CloseHandle(pipe);
//wcout << "Done." << endl;
system("pause");
return 0;
C#获取所有可用的管道
var listOfPipes = System.IO.Directory.GetFiles(@"\.\pipe\")
C# 示例
using (var pipeServer = new NamedPipeServerStream("MyServerPipe", PipeDirection.InOut))
{
Console.WriteLine("NamedPipeServerStream object created.");
// Wait for a client to connect
Console.Write("Waiting for client connection...");
pipeServer.WaitForConnection();
Console.WriteLine("Client connected.");
try
{
using (var bw = new BinaryWriter(pipeServer))
{
var data = Encoding.ASCII.GetBytes("SendInformation data1 data2 data3");
//var data = Encoding.ASCII.GetBytes("Start\r\n");
bw.Write(data);
}
}
// Catch the IOException that is raised if the pipe is broken
// or disconnected.
catch (IOException e)
{
Console.WriteLine("ERROR: {0}", e.Message);
}
}