C# 如何避免调用CUDA Dll时出现访问冲突异常?

C# 如何避免调用CUDA Dll时出现访问冲突异常?,c#,dll,cuda,unmanaged,access-violation,C#,Dll,Cuda,Unmanaged,Access Violation,我是CUDA的新手,对C也不是很熟悉。我编写了一个Dll,将CUDA方法(FFT)实现到我的C#程序中。我首先将dll作为控制台应用程序进行调试,以确保其正常工作,然后将其构建为dll。所以我的问题是,在我的dll的第一次调用(cufftPlan1d())时,会导致AccessViolationException。到目前为止,我已经查阅了这个博客和其他谷歌搜索结果,但什么都没有。我使用不安全的代码来处理指针,并使用Marshal.AllocHGlobal()方法分配内存,所以我不知道问题出在哪里

我是CUDA的新手,对C也不是很熟悉。我编写了一个Dll,将CUDA方法(FFT)实现到我的C#程序中。我首先将dll作为控制台应用程序进行调试,以确保其正常工作,然后将其构建为dll。所以我的问题是,在我的dll的第一次调用(cufftPlan1d())时,会导致AccessViolationException。到目前为止,我已经查阅了这个博客和其他谷歌搜索结果,但什么都没有。我使用不安全的代码来处理指针,并使用Marshal.AllocHGlobal()方法分配内存,所以我不知道问题出在哪里。下面是我的dll代码和调用C#类的代码:

动态链接库:

和包装器类:

unsafe public class CudaFft
    public struct cufftDoubleComplex
    {
            public double x;
            public double y;
    }

    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    unsafe public delegate int fftPlan(int* plan, int signal_size, int batch);

    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    unsafe public delegate int allocateMemory(double** signalGPU, cufftDoubleComplex** signalFftGPU, int size);

    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    unsafe public delegate int fftcaller(int* plan, double* signal, double* signalGPU, cufftDoubleComplex* signalFft, cufftDoubleComplex* signalFftGPU, int size);

    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    unsafe public delegate int cudaclean(void* GPUPtr);

    public static int pDll, a;
    //static IntPtr signal, signalFft;
    unsafe static int* plan;
    unsafe static double* signal;
    unsafe static double** signalGPU;
    unsafe static int signal_size;
    unsafe static cufftDoubleComplex* signalFft;
    unsafe static cufftDoubleComplex** signalFftGPU;

    unsafe public static int Plan(int* plan, int signal_size, int batch)
    {
        IntPtr pAddressOfFunctionToCall = DllImport.GetProcAddress(pDll, "fftPlan");


        fftPlan fftplan = (fftPlan)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(fftPlan));
        return fftplan(plan, signal_size, batch); //THIS LINE CAUSES THE EXCEPTION 
    }  
    (...) //some irrelevant code here
    unsafe public CudaFft(int signal_length) //constructor
    {
        pDll = DllImport.LoadLibrary("d:\\CudaFft.dll");
        a = DllImport.GetLastError();
        signal_size = signal_length;
        signal = (double*)Marshal.AllocHGlobal(signal_size * 8).ToPointer();
        signalFft = (cufftDoubleComplex*)Marshal.AllocHGlobal((signal_size / 2 + 1) * 16).ToPointer();
        CudaFft.Plan(plan, signal_length, 1);
        CudaFft.allocMemory(signalGPU, signalFftGPU, signal_size);
    }
提前感谢,,
Szabolcs

计划
似乎从未分配。

'extern“C”和'CallingConvention.StdCall'?你试过“CallingConvention.Cdecl”吗?我刚试过,但问题仍然存在。谢谢,SzabolcsI解决了这个问题,我只是忘了为plan分配mamory,所以添加“plan=(int*)Marshall.AllocHGlobal(sizeof(int));”解决了我的问题。请更新您的代码。这将帮助那些想复制你的代码的人。为了完整起见,请发布一个答案
unsafe public class CudaFft
    public struct cufftDoubleComplex
    {
            public double x;
            public double y;
    }

    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    unsafe public delegate int fftPlan(int* plan, int signal_size, int batch);

    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    unsafe public delegate int allocateMemory(double** signalGPU, cufftDoubleComplex** signalFftGPU, int size);

    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    unsafe public delegate int fftcaller(int* plan, double* signal, double* signalGPU, cufftDoubleComplex* signalFft, cufftDoubleComplex* signalFftGPU, int size);

    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    unsafe public delegate int cudaclean(void* GPUPtr);

    public static int pDll, a;
    //static IntPtr signal, signalFft;
    unsafe static int* plan;
    unsafe static double* signal;
    unsafe static double** signalGPU;
    unsafe static int signal_size;
    unsafe static cufftDoubleComplex* signalFft;
    unsafe static cufftDoubleComplex** signalFftGPU;

    unsafe public static int Plan(int* plan, int signal_size, int batch)
    {
        IntPtr pAddressOfFunctionToCall = DllImport.GetProcAddress(pDll, "fftPlan");


        fftPlan fftplan = (fftPlan)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(fftPlan));
        return fftplan(plan, signal_size, batch); //THIS LINE CAUSES THE EXCEPTION 
    }  
    (...) //some irrelevant code here
    unsafe public CudaFft(int signal_length) //constructor
    {
        pDll = DllImport.LoadLibrary("d:\\CudaFft.dll");
        a = DllImport.GetLastError();
        signal_size = signal_length;
        signal = (double*)Marshal.AllocHGlobal(signal_size * 8).ToPointer();
        signalFft = (cufftDoubleComplex*)Marshal.AllocHGlobal((signal_size / 2 + 1) * 16).ToPointer();
        CudaFft.Plan(plan, signal_length, 1);
        CudaFft.allocMemory(signalGPU, signalFftGPU, signal_size);
    }