线程中调用第三方DLL,WinForm程序正常,windows服务中调用报“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”

totoz 2011-09-09 03:43:36
同一个DLL,实现同一个功能,在WinForm中使用计时器或Thread调用都正常,但是在windows服务中调用一直报“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”

郁闷的是,如果windows服务中取消线程直接调用也正常,希望大家帮我看下,代码入下:

public AlarmEvent()
{
InitializeComponent();

timerReAlarm = new System.Timers.Timer(20* 1000);//秒
timerReAlarm.Elapsed +=new ElapsedEventHandler(timerReAlarm_Elapsed);
timerReAlarm.AutoReset = true;
}

private void timerReAlarm_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
timerReAlarm.Stop();
ThreadPool.QueueUserWorkItem(new WaitCallback(ExecuteTask), null);
timerReAlarm.Start();
}

/// <summary>
/// 开始执行任务
/// </summary>
private void ExecuteTask(object status)
{
TMsgCongestion.MsgAction();
}

---------------------------------------------------------------------------------------以下是调用DLL的部分
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
public static extern int LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);

[DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]
public static extern IntPtr GetProcAddress(int hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName);

delegate int Sends([MarshalAs(UnmanagedType.LPStr)]string par1, int par2);

Sends sends;
public void MsgAction(string content)
{
int hmodule = LoadLibrary("SSMQ2Client.dll");
IntPtr intPtrSends = GetProcAddress(hmodule, "sends");
sends = (Sends)Marshal.GetDelegateForFunctionPointer(intPtrSends, typeof(Sends));

sends(content,300);
}


每次就会在执行到 sends(content,300);的地方报“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”
...全文
342 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
马少华 2011-09-13
  • 打赏
  • 举报
回复
Control.Invoke方法,MSDN解释如下:在拥有此控件的基础窗口句柄的线程上执行指定的委托。
所以这里不算跨线程.
至于怎么解决,那要看看你的dll函数里干了些什么?或者不要使用线程处理。
totoz 2011-09-13
  • 打赏
  • 举报
回复
UP一下,求助高手帮忙啊
totoz 2011-09-13
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 evionmzs 的回复:]

vc中,一个线程new出来的内存,另一个线程是不能访问的。
[/Quote]

那有什么办法可以解决吗?同样的功能,在WINFORM里面,我用类似的方法可以调用成功的,下面这样的:

System.Timers.Timer NTbMove_timer = new System.Timers.Timer(20000);
NTbMove_timer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimer);
NTbMove_timer.AutoReset = true; ;
NTbMove_timer.Enabled = true;


public void OnTimer(Object source, System.Timers.ElapsedEventArgs e)
{
NTbMove_timer.Stop();
Invoke(new EventHandler(NTbMove_timer_Tick), source, e);
NTbMove_timer.Start();
}


private void NTbMove_timer_Tick(object sender, EventArgs e)
{
TMsgCongestion.MsgAction();
}
马少华 2011-09-13
  • 打赏
  • 举报
回复
贴出来看看你的dll里面的函数原型
totoz 2011-09-13
  • 打赏
  • 举报
回复
UP 自顶一下
totoz 2011-09-13
  • 打赏
  • 举报
回复
7楼的我贴出来的代码是WINFORM下的,可以正常调用,无错误

出现错误的是1楼windows服务的
totoz 2011-09-13
  • 打赏
  • 举报
回复
我是windows服务没有Invoke的,那个是WINFORM的

我是要定时器功能,所以无法避免线程
totoz 2011-09-12
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 sdl2005lyx 的回复:]

Dll部分有问题,改成如下:

[DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
public static extern int LoadLibrary(string lpLibFileName);

[DllImport("kernel32.dll", EntryPoint = "GetProcAddress……
[/Quote]

改成这样试过米用,应该跟这个无关,这个只是格式转换
马少华 2011-09-12
  • 打赏
  • 举报
回复
vc中,一个线程new出来的内存,另一个线程是不能访问的。
sdl2005lyx 2011-09-11
  • 打赏
  • 举报
回复
Dll部分有问题,改成如下:

[DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
public static extern int LoadLibrary(string lpLibFileName);

[DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]
public static extern IntPtr GetProcAddress(int hModule, string lpProcName);

delegate int Sends([string par1, int par2);
totoz 2011-09-09
  • 打赏
  • 举报
回复
去掉了,应该不是只读的问题

我是不用线程调用是正常的,加上线程就失败了
蝶恋花雨 2011-09-09
  • 打赏
  • 举报
回复
H只读属性去掉了吗
totoz 2011-09-09
  • 打赏
  • 举报
回复
UP 大家都过节去了?

麻烦帮我看下

110,535

社区成员

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

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

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