案例:
有一个.net应用程序调用非托管C代码。使用的方法:
public static class MiracleCreator
{
[DllImport("Library.dll")]
private static extern void RunUnmanaged(string fileName);
public static void Run(string fileName)
{
RunUnmanaged(fileName);
}
}
它在Windows窗体应用程序中使用,所需的文件名由OpenFileDialog获取。代码:
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
MiracleCreator.Run(openFileDialog.FileName);
}
问题:
在Windows窗体应用程序中多次执行代码后,openFileDialog会被异常破坏:“尝试读取或写入受保护的内存。这通常表示其他内存已损坏。” < / p>
在寻找解决方案时:
尝试“更可靠”地使用OpenFileDialog并没有帮助。像这个解决方案(尝试给出链接,但“不允许新用户添加超链接”:)):
public class Invoker
{
public OpenFileDialog InvokeDialog;
private Thread InvokeThread;
private DialogResult InvokeResult;
public Invoker()
{
InvokeDialog = new OpenFileDialog();
InvokeThread = new Thread(new ThreadStart(InvokeMethod));
InvokeThread.SetApartmentState(ApartmentState.STA);
InvokeResult = DialogResult.None;
}
public DialogResult Invoke()
{
InvokeThread.Start();
InvokeThread.Join();
return InvokeResult;
}
private void InvokeMethod()
{
InvokeResult = InvokeDialog.ShowDialog();
}
}
用法:
Invoker I = new Invoker();
if (I.Invoke() == DialogResult.OK)
{
MessageBox.Show(I.InvokeDialog.FileName, "Test Successful.");
}
else
{
MessageBox.Show("Test Failed.");
}
问题:
异常是否真的是由非托管代码引起的?是否可以预期其他可能的问题(打破与OpenFileDialog不同的东西)?对此有什么更好的方法?
感谢您的每一个想法/解决方案。
答案 0 :(得分:1)
您应该为方法声明的MarshalAs
参数指定适当的string
属性。类似的东西:
[DllImport("Library.dll")]
private static extern void RunUnmanaged(
[MarshalAs(UnmanagedType. ... )] string fileName);
答案 1 :(得分:0)
使用SaveFileDialog
通过.NET Windows窗体应用程序(在Windows 7 32位上运行)中的托管代码使用saveAs
时,只有在从模式窗体中显示Dim sfv As New System.Windows.Forms.SaveFileDialog
With sfv
.AutoUpgradeEnabled = False
'[...]
且从数据库加载的任何数据时。经过几个小时的调试和试验/错误之后,我的目光落在了我之前没有意识到的属性上:在VB.NET中,我写了
{{1}}
并且错误消失了。