C#调用C++dll报错ACCESS VIOLATION

wangzhihongji 2015-04-12 03:28:23
原帖地址:http://bbs.csdn.net/topics/391012458
代码改了一下,问题还没有解决。于是重开一个贴

-----------------------------------------------------C#代码

namespace WpfApplication2
{
class MyClass1 : INotifyPropertyChanged
{
public MyClass1()
{
result="null";
}
private string result;

public string Result
{
get { return result; }
set { result = value;
if (PropertyChanged != null)
{
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Result"));
}
}

}
public event PropertyChangedEventHandler PropertyChanged;
}
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>

public class mytransdll
{
[DllImport("mytransdll.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern int mytransfunc(StringBuilder exportpath, StringBuilder importpath);
}
public partial class Main : Window
{

MyClass1 myout=new MyClass1 ();
private StringBuilder exportpath;
private StringBuilder importpath;
public Main()
{
InitializeComponent();
myout.Result = "there will show ,if transform is ok ";// Result 赋值应该放到Main的构造函数或者窗口的Loaded事件中赋值的。
//把结果binding上去。。。请注意,XAML里的binding并不能访问C#里的变量,而C#里的变量却可以访问XAML
Binding bind1 = new Binding();
bind1.Source = myout;
bind1.Path = new PropertyPath("Result");
this.MyLabel.SetBinding(Label.ContentProperty, bind1);


}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
//int isornotsuccess = 1;

int isornotsuccess = mytransdll.mytransfunc(exportpath, importpath);
myout.Result = " Transforming,please wait....";
Binding bind3 = new Binding();
bind3.Source = myout;
bind3.Path = new PropertyPath("Result");
this.MyLabel.SetBinding(Label.ContentProperty, bind3); //按下按钮之后马上显示正在传输
if (isornotsuccess == 1)
{
myout.Result = exportpath.ToString() ;
Binding bind2 = new Binding();
bind2.Source = myout;
bind2.Path = new PropertyPath("Result");
this.MyLabel.SetBinding(Label.ContentProperty, bind2); //这里写成功后的反应
}
}

private void textBox1_KeyDown_1(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter) //key是一个类,这是一个类的判断
{
StringBuilder exportpath=new StringBuilder(this.textBox1.Text,200);


}
}



---------------------------------------------------C++编写的DLL

//

#include "stdafx.h"
#include "stdio.h"
#include"pcap.h"
#include<WinSock.h>
#include"packet32.h"
#include<Win32-Extensions.h>
#include "stdlib.h"



extern "C" _declspec(dllimport) int mytransfunc(char* exportpath,char* importpath);
int mytransfunc(char* exportpath,char* importpath)
{
//和EXPORTPATH无关的代码
char A[]="regenerate_original_picture.txt";
char PA[1024];
char exportpathvalue=*exportpath;
//!!!!高能,就是这句出问题。不管是用这种方法中转还是直接调用*exportpath都出现报错
sprintf(PA,"%s\\%s",exportpathvalue,A);//连接字符串
FILE *fpopen = fopen(PA, "rb");
//和EXPORTPATH无关的代码
}


-----------------------------------------问题
C#编写了一个UI界面,调用DLL的时候传入文件所在地址,然后由DLL对其操作
测试过DLL程序的正确性。

之前大神们说的,如使用stringbuilder,DllImport函数的参数的设定都不管用。有网友说是关于托管代码和非托管代码内存管理的问题。。。楼主是新手,不太明白,还请指教。
...全文
355 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangzhihongji 2015-04-13
  • 打赏
  • 举报
回复
补充一下,这个问题原帖就已经解决了。。。 这里楼主犯了一个低级错误。。。各位看官见笑
wangzhihongji 2015-04-13
  • 打赏
  • 举报
回复
引用 8 楼 Forty2 的回复:
char exportpathvalue=*exportpath; sprintf(PA,"%s\\%s",exportpathvalue,A);//连接字符串 这是另外的一个错误。 %s将期待一个字符串指针,但你传入了一个char(char的取值范围是0~255),小数值指针将导致’违规访问‘。
搞定了。。。。谢谢
Forty2 2015-04-13
  • 打赏
  • 举报
回复
char exportpathvalue=*exportpath; sprintf(PA,"%s\\%s",exportpathvalue,A);//连接字符串 这是另外的一个错误。 %s将期待一个字符串指针,但你传入了一个char(char的取值范围是0~255),小数值指针将导致’违规访问‘。
wangzhihongji 2015-04-13
  • 打赏
  • 举报
回复
引用 2 楼 armipotence 的回复:
[DllImport("mytransdll.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)] public static extern int mytransfunc([MarshalAs(UnmanagedType.LPStr)]string exportpath, [MarshalAs(UnmanagedType.LPStr)]string importpath);
依然报错,和原来不一样的是加了这么一长串之后,反汇编多运行了几步。
xian_wwq 2015-04-13
  • 打赏
  • 举报
回复
char exportpathvalue=*exportpath; 把字符串赋给一个字符,这样也行?
wangzhihongji 2015-04-13
  • 打赏
  • 举报
回复
引用 1 楼 wyd1520 的回复:
还没搞定?
对啊。。。我感觉可能是托管和非托管内存地址是否变动的问题? 不过网上出现内存地址问题的程序都是随机报错,而我这个是必然报错。。。
wangzhihongji 2015-04-13
  • 打赏
  • 举报
回复
引用 3 楼 Forty2 的回复:
因为你的exportpath没有初始化,传了null到C++,引发Access Violation异常。 解决方法: 1、去掉75行StringBuilder本地声明: [删]StringBuilder[/删] exportpath=new StringBuilder(this.textBox1.Text,200); 2、或者,更好的是,exportpath即用即拿(不用声明为类成员,也不需要textBox1_KeyDown_1事件): private void Button_Click_2(object sender, RoutedEventArgs e) { StringBuilder exportpath=new StringBuilder(this.textBox1.Text,200); int isornotsuccess = mytransdll.mytransfunc(exportpath, importpath);
不像是初始化的问题,在运行的时候,我会先触发keydown事件,即此刻exportpath已被初始化。。。 您的答案我试过了,依然报错。谢谢您帮我简化程序。
Forty2 2015-04-13
  • 打赏
  • 举报
回复
因为你的exportpath没有初始化,传了null到C++,引发Access Violation异常。 解决方法: 1、去掉75行StringBuilder本地声明: [删]StringBuilder[/删] exportpath=new StringBuilder(this.textBox1.Text,200); 2、或者,更好的是,exportpath即用即拿(不用声明为类成员,也不需要textBox1_KeyDown_1事件): private void Button_Click_2(object sender, RoutedEventArgs e) { StringBuilder exportpath=new StringBuilder(this.textBox1.Text,200); int isornotsuccess = mytransdll.mytransfunc(exportpath, importpath);
armipotence 2015-04-12
  • 打赏
  • 举报
回复
[DllImport("mytransdll.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)] public static extern int mytransfunc([MarshalAs(UnmanagedType.LPStr)]string exportpath, [MarshalAs(UnmanagedType.LPStr)]string importpath);
本拉灯 2015-04-12
  • 打赏
  • 举报
回复
还没搞定?

110,577

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧