系统.从c#调用到不安全的c++时的AccessViolationException

本文关键字:c++ 时的 AccessViolationException 不安全 调用 系统 | 更新日期: 2023-09-27 18:12:01

我正在编写c#代码,导入一个类似于以下的c++函数:

//C++ code
extern "C" _declspec(dllexport) int foo(double *var1, double *var2){
    double dubs[10];
    RandomFunction(dubs);
    *var1 = dubs[5];
    *var2 = dubs[7];
    return 0;
}

为了将这个函数导入c#,我尝试了2种方法,都导致了System.AccessViolationException。这意味着我试图访问受保护的内存…

//C# import code
//method 1
[DllImport(example.dll,CallingConvention = CallingConvention.Cdecl)]
public static unsafe extern int foo(ref double var1, ref double var2);
//method 2
[DllImport(example.dll,CallingConvention = CallingConvention.Cdecl)]
public static unsafe extern int foo(double *var1, double *var2);
//C# calling code
//method 1
public unsafe int call_foo(){
    ....Stuff
    double var1 = 0;
    double var2 = 0;
    foo(ref var1, ref var2);
    ....More Stuff
}
//method 2
public unsafe int call_foo(){
    ....Stuff
    double var1 = 0;
    double var2 = 0;
    double *v1 = &var1;
    double *v2 = &var2;
    foo(v1, v2);
    ....More Stuff
}

到目前为止,我一直认为这是我的c#代码的问题,但是c++代码对数组的使用会导致问题吗?我是不是错过了什么很明显的东西?

系统.从c#调用到不安全的c++时的AccessViolationException

这不是c# p/调用或本机函数foo签名的问题。除了c++数组语法和RandomFunction的作用之外,一切都很好。我刚刚用我自己的小演示进行了测试:

c++:

void RandomFunction( double dubs[] );
extern "C" __declspec(dllexport) int foo ( double* var1, double* var2 ) 
{
    double dubs[10];
    RandomFunction( dubs );
    *var1 = dubs[5];
    *var2 = dubs[7];
    return 0;
}
void RandomFunction( double dubs[] ) {
    for ( int i = 0; i < 10; i++ ) {
        dubs[i] = i;
    }
}
c#:

[DllImport( "Native.dll", CallingConvention = CallingConvention.Cdecl )]
private static extern int foo( ref double var1, ref double var2 );
public static void Main( string[] args )
{
    FooTest();
}
private static void FooTest()
{
    double var1 = 0;
    double var2 = 0;
    foo( ref var1, ref var2 );
    Console.Out.WriteLine( "Var1: {0:0.0}; Var2: {1:0.0}", var1, var2 );
    // Prints "Var1: 5.0; Var2: 7.0"
}

我和你只有一些不同之处:

  • 我的c++数组是使用标准语法double dubs [10]来声明的。
  • 我的编译器在__declspec语法中需要两个下划线
  • 我在Windows 7 SP 1上使用64位的Visual Studio 2012编译所有内容。