使用非托管DLL的访问冲突 [英] Access Violation with unmanaged DLL

查看:81
本文介绍了使用非托管DLL的访问冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当前,我们使用来自供应商的非托管DLL,该DLL使我们可以访问特定工具.感兴趣的特定功能在头文件中指定为:

Currently, we use an unmanaged DLL from a vendor that allows us to access a particular instrument. The particular function of interest is specified in a header file as this:

extern "C" short CCONV acq_get_board_count ();

在我的应用程序中,我有pinvoke语句:

In my application, I have the pinvoke statement:

public class bograms
{
    [DllImport("bograms.dll", EntryPoint = "acq_get_board_count", CallingConvention = CallingConvention.StdCall)]
    public static extern short acq_get_board_count();
}

现在,在我的代码中,我试图处理冗余,因此我创建了一个计时器,试图使事情继续运行:

Now, in my code I am attempting to handle redundancy, so I create a timer that attempts to keep things running:

public class Instrument
{
    private System.Threading.Timer keepAliveTimer;
    public Instrument()
    {
        keepAliveTimer = new Timer(new TimerCallback(this.KeepAlive), null, 0, 300000);
    }

    void KeepAlive(object state)
    {
        if(instrumentIsUninitialized) // some check that accomplishes this
        {
            Console.WriteLine("Some status statements"); // in console
            short numBoards = bograms.acq_get_board_count();
            Console.WriteLine("Initialization caught {0} boards.", numBoards); // not in console
        }
    }
}

计时器的第一次计时,它获得零个板(可能是因为硬件尚未完成初始化),并将这两个消息都打印到控制台.但是,第二个勾号,我在bograms.dll中收到APPCRASH错误0xc0000005,发现它是访问冲突错误.在呼叫周围进行try/catch不会捕获该错误.第一行在控制台中,第二行不在控制台中.在调试转储文件时(以我所掌握的专门知识),此调用似乎发生了错误.

The first tick of the timer, it gets zero boards (presumably because the hardware is not finished initializing), and prints both messages to the console. However, the second tick, I get an APPCRASH error 0xc0000005 in the bograms.dll, which I've found to be an Access Violation error. Putting try/catch around the call does not catch the error. The first line is in the console, the second line is not. When debugging the dump file (to the best of my limited knowhow), the error seems to occur on this call.

我的pinvoke陈述有误吗?它是如此简单,我简直不敢相信,但是我错过了什么吗?是由于计时器引起的线程引起某种类型的问题?

Is my pinvoke statement wrong? It's such a simple function that I can't believe it would be, but am I missing something? Is the threading due to the timer causing some type of problem?

我猜第一个调用将其置于某种状态,导致第二个调用失败,尤其是考虑到在后台进行硬件初始化时.如果是这种情况,是否有任何方法可以卸载驱动程序DLL,以便它可以重置为应处于的初始状态?

I'm guessing the first call puts it into some type of state that results in the second call's failure, especially when considering the hardware initialization going on behind the scenes. If this is the case, is there any way to unload the driver DLL so it can reset back to the initial state it should be in?

或者您还有其他想想的东西吗?

Or are there any other things you can think of?

推荐答案

立即想到的一件事是,该API是否可以在线程之间安全地使用. System.Threading.Timer回调进入ThreadPool线程,因此每次可能有所不同.某些API具有线程相似性要求,这意味着只能从单个线程中调用它们.取而代之的是,如果对同一API的两次调用同时发生,则可能仍然存在一些并发问题.最后,您可能会发现问题与线程无关.我只是想提出一种可能的解释.

One thing that immediately comes to mind is whether the API can be used safely across threads. The System.Threading.Timer callbacks come in on a ThreadPool thread so it could be different each time. Some APIs have thread affinity requirements which means that they can only be called from a single thread. In lieu of that there still may be some concurrency problem if two calls to the same API occur simultaneously. In the end you may find out that the problem has nothing to do with threading. I am just trying to present one possible explanation.

这篇关于使用非托管DLL的访问冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆