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