积极答复者
在C#调用C的dll,报“未找到入口”;什么情况?

问题
-
环境VS2010+Nsight2
kernel.cu 相当于C,编译成TestDll.DLL
#include "cuda_runtime.h" #include "device_launch_parameters.h" #include <stdio.h> cudaError_t addWithCuda(int *c, const int *a, const int *b, size_t size); __global__ void addKernel(int *c, const int *a, const int *b) { int i = threadIdx.x; c[i] = a[i] + b[i]; } int __declspec(dllexport) cu_main(int a[],int b[]) { const int arraySize = 5; int c[arraySize] = { 0 }; // Add vectors in parallel. cudaError_t cudaStatus = addWithCuda(c, a, b, arraySize); if (cudaStatus != cudaSuccess) { fprintf(stderr, "addWithCuda failed!"); return 1; } printf("{1,2,3,4,5} + {10,20,30,40,50} = {%d,%d,%d,%d,%d}\n", c[0], c[1], c[2], c[3], c[4]); // cudaDeviceReset must be called before exiting in order for profiling and // tracing tools such as Parallel Nsight and Visual Profiler to show complete traces. cudaStatus = cudaDeviceReset(); if (cudaStatus != cudaSuccess) { fprintf(stderr, "cudaDeviceReset failed!"); return 1; } return 0; }
Program.cs:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; namespace ConsoleTest { class Program { [DllImport (".\\Cuda\\TestDll.dll",CharSet=CharSet.Auto)] public static extern int cu_main(int[] arg1, int[] arg2); static void Main(string[] args) { int[] a = { 1, 2, 3, 4, 5 }; int[] b = { 10, 20, 30, 40, 50 }; cu_main(a, b); Console.ReadLine(); // end static void Main(string[] args) } // end class Program } // end namespace ConsoleTest }
文件列表:
D:\MyProject\CUDA\TestDll\Bin>dir /s
驱动器 D 中的卷是 Studio
卷的序列号是 1059-D0BDD:\MyProject\CUDA\TestDll\Bin 的目录
2011/06/12 08:50 <DIR> .
2011/06/12 08:50 <DIR> ..
2011/06/12 08:50 5,120 ConsoleTest.exe
2011/06/12 08:50 11,776 ConsoleTest.pdb
2011/06/12 08:44 11,600 ConsoleTest.vshost.exe
2010/03/17 22:39 490 ConsoleTest.vshost.exe.manifest
2011/06/12 08:50 <DIR> Cuda
4 个文件 28,986 字节D:\MyProject\CUDA\TestDll\Bin\Cuda 的目录
2011/06/12 08:50 <DIR> .
2011/06/12 08:50 <DIR> ..
2011/03/23 07:04 407,656 cudart32_40_12.dll
2011/03/23 07:04 576,616 cudart64_40_12.dll
2011/06/12 08:50 75,776 TestDll.dll
2011/06/12 08:50 643 TestDll.exp
2011/06/12 08:50 356,412 TestDll.ilk
2011/06/12 08:50 1,748 TestDll.lib
2011/06/12 08:50 388,096 TestDll.pdb
7 个文件 1,806,947 字节所列文件总数:
11 个文件 1,835,933 字节
5 个目录 10,565,853,184 可用字节报错信息。
D:\MyProject\CUDA\TestDll\Bin>ConsoleTest.exe
未经处理的异常: System.EntryPointNotFoundException: 无法在 DLL“.\Cuda\TestDll.
dll”中找到名为“cu_main”的入口点。
在 ConsoleTest.Program.cu_main(Int32[] arg1, Int32[] arg2)
在 ConsoleTest.Program.Main(String[] args) 位置 D:\MyProject\CUDA\TestDll\Con
soleTest\Program.cs:行号 18求助大侠,谢谢。
答案
-
你好,
1. 建议你先在函数名的修饰符前加extern "C" 作为修饰符:
extern "C" int __declspec(dllexport) cu_main(int a[],int b[])
此方法不可行,我们再通过加入.def文件的方法。2. 加入.def方法,此文件需要手动加入项目,再重新编译dll。
def文件中,library 后面是dll的名字,在你的code中看来,应该是TestDLL, exports 后面是需要导出的函数名。
如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
立刻免费下载 MSDN 论坛好帮手
全部回复
-
你好,
看起来你的DLL是基于C++而不是C语言的。
实际上C++和C语言的编译器在生成DLL的时候,函数名并不是和我们代码中写的函数名一致的,编译器会给函数名加一串前缀字符。为了导出到Managed code中作为导出函数名,而不添加其他字符,在C++和C中是不一样的。
如果是在C++中, 我们在导出方法声明中加入extern “C”,这样,就可以作为导出方法名使用了。
如果是在C中,我们在编译DLL前,要加入.c程序的.Def,声明函数库,再编译导出函数,具体做法参照:
http://support.microsoft.com/kb/106553
如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
立刻免费下载 MSDN 论坛好帮手
-
你好,
看起来你的DLL是基于C++而不是C语言的。
实际上C++和C语言的编译器在生成DLL的时候,函数名并不是和我们代码中写的函数名一致的,编译器会给函数名加一串前缀字符。为了导出到Managed code中作为导出函数名,而不添加其他字符,在C++和C中是不一样的。
如果是在C++中, 我们在导出方法声明中加入extern “C”,这样,就可以作为导出方法名使用了。
如果是在C中,我们在编译DLL前,要加入.c程序的.Def,声明函数库,再编译导出函数,具体做法参照:
http://support.microsoft.com/kb/106553
-
-
你好,
1. 建议你先在函数名的修饰符前加extern "C" 作为修饰符:
extern "C" int __declspec(dllexport) cu_main(int a[],int b[])
此方法不可行,我们再通过加入.def文件的方法。2. 加入.def方法,此文件需要手动加入项目,再重新编译dll。
def文件中,library 后面是dll的名字,在你的code中看来,应该是TestDLL, exports 后面是需要导出的函数名。
如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
立刻免费下载 MSDN 论坛好帮手