来自C#的gcc DLL:" DLL初始化例程失败"在Windows 10上

时间:2017-09-19 08:25:07

标签: c# c++ visual-studio gcc dll

我正在开发C#DLL,它需要我作为C ++ DLL的代码,由gcc构建。 为此,我编写了一个C包装器,并使用gcc(TDM-GCC MinGW-w64)作为DLL编译它。换句话说,我有:

  • C++.dll由gcc构建;加上使用DLL的C++_test.exe,所以我知道它有效。
  • C.dll由gcc构建,调用C++.dll;加上使用DLL的C_test.exe ......
  • 由Visual Studio构建的
  • C#.dll,调用C.dll;加C#_test.exe

整个链构建为64位代码。

我的问题是虽然这个设置在我的旧Windows 7机箱上工作正常,但在我的新机器上使用Windows 10(以及更新版本的软件和库),C#_test.exe在它调用函数时失败了来自C.dll,其中包含以下消息:Unable to load DLL 'C.dll': A dynamic link library (DLL) initialization routine failed. (Exception from HRESULT: 0x8007045A)

在C#代码中,该函数定义为:

    [DllImport("C.dll", CallingConvention = CallingConvention.Cdecl)]
    private static extern int pg_generate(..);

我将所有其他DLL放在同一个文件夹中(否则我会收到有关丢失DLL的其他错误消息)。

知道如何找出问题是什么以及如何解决问题? 我知道它可能有助于在VS中构建整个链,但是我没有所需的项目文件,并且还会构建C ++ .dll所依赖的几个库,所以我宁愿避免这种情况 - 特别是因为它以前工作过。 ..

更新:当我在VS中调试C#_test.exe时,它会从pg_generate()投出:Exception thrown at 0x000000006E0436B0 (C++.dll) in C#_test.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFB64927F5.

更新2:当我在旧盒子上构建并测试C#_test.exe(和所有依赖项)时,我也得到了相同的错误(DLL初始化例程失败)。这表明问题出在Windows 10与Windows 7中。 (这也意味着一旦客户端升级到Windows 10,我们提供的代码将停止工作......)

1 个答案:

答案 0 :(得分:0)

我有同样的问题。事实证明,它的来源是新的/删除操作符。一旦我实现了自己的运算符,应用程序就可以正常工作。对于第三方库,这并不容易!

以下是重现错误的最小示例,包括解决方法(如果AddNewOperator已定义operator new[]将被定义,并且生成的.dll将正常工作):

Test.cs(使用Visual Studio 2017编译/运行):

using System;
using System.Runtime.InteropServices;
class Program
{
    [DllImport("libTest", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    public static extern int TestFunction();
    static void Main(string[] args)
    {
        Console.WriteLine("!!" + TestFunction());
    }
}

用mingw编译的Test.cpp:

#include <new>
#include <cstdlib>

#ifdef AddNewOperator // This will fix the issue
void* operator new[](std::size_t sz){
    return std::malloc(sz);
}
#end

extern "C" {
int __stdcall __declspec(dllexport) TestFunction() {
        int* test = new int[3]; // removing this line will make everything work when building
        return test[2];
}

这是构建脚本:

# Remove the following # and the compiled dll will work just fine
g++ -g -s -Wall -c -fmessage-length=0 Test.cpp  #-DAddNewOperator
g++ -g -shared -o libTest.dll *.o -Wl,--subsystem,windows