【发布时间】:2018-10-03 15:30:20
【问题描述】:
我正在尝试在 Windows 10 上从 C# 调用最小的 C 函数。我使用 mingw/g++ 将 C 代码编译成 .dll
事实证明,我必须定义 opterator new[] 或使用 Visual Studio 编译 .dll。否则我的 C# 程序会因以下错误而崩溃:
The program '[14740] Test.exe' has exited with code -1073741819 (0xc0000005) 'Access violation'.
我真的很想了解这里到底发生了什么,以及如何在不覆盖所有新/删除运算符但仍使用 mingw 的情况下解决此问题。
这是重现错误的最小示例,包括解决方法(如果定义了 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
编辑: 为 x86 而不是 64 位编译所有内容也解决了这个问题(这对我来说再次没有选择)
【问题讨论】:
-
我的意思是如果我想使用
new[]。因此,如果我想使用new[],我要么必须覆盖operator new[],要么必须使用Visual Studio 编译.dll。我更改了这句话以进行澄清。