代码之家  ›  专栏  ›  技术社区  ›  Paralife

调用非托管dll时发生访问违规

  •  0
  • Paralife  · 技术社区  · 16 年前

    AccessViolationException 。奇怪的是,导出的函数没有参数,所以问题不在于数据的编组。该函数没有参数,只返回一个整数。还要注意,调用约定不是问题。具有相同零参数和整数返回值(但名称不同)的相同函数工作正常。考虑到排除了编组和调用约定的事实,这种调用可能会导致这种异常的其余候选原因是什么?

    ei_connect_init() ei_connect() 最后 ei_reg_send() ei_connect() erl_errno (这些在ei.lib中定义)在XP上运行时,被托管代码调用会导致试图读取或写入受保护的内存,从而导致应用程序崩溃。它不能是微不足道的,因为它在Vista上工作,并且在非托管代码调用时也能工作。

    2 回复  |  直到 16 年前
        1
  •  1
  •   Paralife    16 年前

    好的,我想我知道问题所在:ei.lib使用TLS(线程本地存储)。在文件中 ei_pthreads.c

    #ifdef __WIN32__
    #ifdef USE_DECLSPEC_THREAD
    /* Define (and initialize) the variable __erl_errno */
    volatile __declspec(thread) int __erl_errno = 0;
    #else
    static volatile DWORD errno_tls_index = TLS_OUT_OF_INDEXES;
    static LONG volatile tls_init_mutex = 0;
    #endif
    #endif
    

    USE_DECLSPEC_THREAD 如果未定义,则在源文件的较低位置使用TLS Api。

    以前在Windows操作系统上 Windows Vista, __declspec( thread ) 作为 __declspec(螺纹) ,这可能会导致 动态保护故障 加载。加载DLL后 LoadLibrary,它会导致系统故障 非局部 __declspec(螺纹) 因为全局变量空间 在运行时分配线程 此空间的大小基于 计算需求 应用程序和要求 所有静态的DLL 无法扩展此空间以允许 随着 __declspec(螺纹) DLL中的API,如TlsAlloc,用于 如果DLL可能是 加载了LoadLibrary。

    编译这些二进制文件时。若非如此,我将陷入绝境,我将尝试其他方式来完成我的工作。如果他们确实定义了它,那么我必须安装cygwin并在不定义它的情况下重新编译源代码。(哎呀…)。

    USE_DECLSPEC_TRHEAD _WIN32_WINNT 发生在包含winbase.h之前,因为省略了 _WIN32_WINNT

        2
  •  0
  •   David Lynch    16 年前

    当非托管代码导致内存访问违规时,会发生此异常。检查非托管函数是否正确。如果你有非托管代码的源代码,你也可以 enable 调试器进入非托管代码,查看问题所在。