从托管.NET代码调用C函数时如何避免访问冲突执行位置?

问题描述 投票:0回答:1

我有以下 C++ 代码:

#include <stdio.h>
#include <stdlib.h>

extern "C" {
    __declspec(dllexport)
        void addInArray(int** c, int* a, int* b, int size)
        {
            *c = (int*)malloc(sizeof(int) * size);
            for (size_t i = 0; i < size; i++)
            {
                (*c)[i] = a[i] + b[i];
            }
        }
}

int main()
{
    int size = 10;
    int* a = new int[size];
    int* b = new int[size];
    int* c;
    for (size_t i = 0; i < size; i++)
    {
        a[i] = rand() % 100;
        b[i] = rand() % 100;
    }
    addInArray(&c, a, b, size);
    for (size_t i = 0; i < size; i++)
    {
        printf("%d = %d + %d\n", c[i], a[i], b[i]);
    }
    free(a);
    free(b);
    free(c);
}

当我将其作为单独的应用程序运行时,它工作正常。

但是,当我尝试从以下(大致相似).NET 代码运行它时

[DllImport($"ArrayCreation.exe")]
public static extern int addInArray(out int[] c, int[] a, int[] b, int size);

static void Main(string[] args)
{
    int size = 10;
    int[] c;
    int[] a = new int[size];
    int[] b = new int[size];
    Random random = new Random();
    for (int i = 0; i < size; i++)
    {
        a[i] = random.Next(100);
        b[i] = random.Next(100);
    }
    addInArray(out c, a, b, size);
    for (int i = 0; i < size; i++)
    {
        Console.WriteLine($"{c[i]} = {a[i]} + {b[i]}");
    }
}

malloc
函数中调用
addInArray
时,出现“访问冲突执行位置”错误。 请帮助我解决这个问题。

c# c++ .net-core malloc dllimport
1个回答
0
投票

addInArray 函数的调用约定可能有错误。 由于 C++ 代码中未指定任何内容,因此 VC++ addInArray 函数的调用约定为 cdecl。 然而,.NET 中的 DllImport 默认在 Windows 上的 StdCall 中调用。我相信这就是堆栈不匹配和非法内存访问发生的原因。

我认为可以通过将C++函数的调用约定中的addInArray更改为__stdcall,或者将.NET中的DllImport的CallingConvention指定为Cdecl来解决问题。

参考:https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.dllimportattribute.callingconvention?view=net-8.0

© www.soinside.com 2019 - 2024. All rights reserved.