C#的ShowDialog()抛出,因为进口的C ++错误DLL抛出、错误、ShowDialog、DLL

由网友(不经历风雨,怎能见彩红。)分享简介:本C#程序能正常工作,而无需使用的ShowDialog(),但是当我试图使用的ShowDialog它创建系统访问冲突异常()。奇怪的!! C#code 使用系统;使用System.Collections.Generic;使用System.ComponentModel;使用System.Data这;使用Syst...

本C#程序能正常工作,而无需使用的ShowDialog(),但是当我试图使用的ShowDialog它创建系统访问冲突异常()。奇怪的!!

C#code

 使用系统;
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Data这;
使用System.Drawing中;
使用System.Linq的;
使用System.Text;
使用System.Windows.Forms的;
使用了System.Runtime.InteropServices;

命名空间w_CSharp_GUI_1
{
    公共部分类Form1中:形态
    {
        私人字符串W_Addr,C_Addr,Pic_Addr =笑;

        [的DllImport(face_proj_trial_dll.dll)]
        公共静态外部串f_detect(字符串路径);

        公共Form1中()
        {
            的InitializeComponent();
        }

        私人无效的button1_Click(对象发件人,EventArgs的)
        {
        打开文件对话框openFileDialog2 =新的OpenFileDialog();

        openFileDialog2.ShowDialog(本);

            Pic_Addr =(f_detect(C: pic.jpg));

            textBox1.Text = Convert.ToString(Pic_Addr);
        }

    }
}
 

C ++ code:

 的#includeface_detect_DLL.h

外部的C__declspec(dllexport)的字符* _stdcall f_detect(字符*路径)
{
    返回路径;
}
 
runtime error dllhost.exe

解决方案

函数返回一个字符串是一个内存管理的问题。该字符串的存储器具有被释放。该PInvoke的编组会调用CoTaskMemFree()方法返回的字符串。这是要崩溃的Vista和起来,默默地在XP泄漏内存,因为该字符串没有分配CoTaskMemAlloc来。

您需要从这样声明的返回类型的IntPtr以prevent编组。而自己名帅它Marshal.PtrToStringAnsi()。这解决了碰撞,但没有内存泄漏。您需要将函数声明为无效f_detect(常量字符*路径,字符* someValue中,为size_t somevaluebuffersize),以便调用者可以通过自己的缓冲区。 StringBuilder的被管理方。

This C# program works fine without using showdialog() but it creates "system access violation" exception when i tried to use showdialog(). Weird!!

C# Code

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace w_CSharp_GUI_1
{
    public partial class Form1 : Form
    {
        private String W_Addr,C_Addr,Pic_Addr="lol";

        [DllImport("face_proj_trial_dll.dll")]
        public static extern string f_detect(string path);

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
        OpenFileDialog openFileDialog2 = new OpenFileDialog();

        openFileDialog2.ShowDialog(this);

            Pic_Addr = (f_detect("C:pic.jpg"));

            textBox1.Text = Convert.ToString(Pic_Addr);
        }

    }
}

C++ code:

#include "face_detect_DLL.h"

extern "C" __declspec(dllexport) char* _stdcall f_detect(char* path)
{
    return path;
}

解决方案

Functions that return a string are a memory management problem. The memory for the string has to be released. The pinvoke marshaller is going to call CoTaskMemFree() on the returned string. That's going to crash on Vista and up, silently leak memory on XP since the string wasn't allocated with CoTaskMemAlloc.

You'll need to declare the return type as IntPtr to prevent the marshaller from doing this. And marshal it yourself with Marshal.PtrToStringAnsi(). That solves the crash but not the memory leak. You'll need to declare the function as void f_detect(const char* path, char* somevalue, size_t somevaluebuffersize) so that the caller can pass his own buffer. StringBuilder on the managed side.

阅读全文

相关推荐

最新文章