我正在开发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
...... 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,我们提供的代码将停止工作......)
答案 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