如果需要将CUDA编写的dll与其他程序语言编写的项目结合,如窗体界面都采用C#进行编写,核心计算采用CUDA编写并编译成DLL,则只需要在C#项目里面引用这个DLL并调用相应的函数即可。下面仍然以项目Test00302中编译的DLL为例,新建一个名为Test00304的Windows窗体应用程序(Visual C#),如下图所示:
在窗体中添加一个按钮,如下图所示:
然后添加名称空间System.Runtime.InteropServices的引用,并导入外部的DLL文件(Test00302.dll),同时定义外部调用的函数vectorAdd(),最后为按钮的Click事件添加调用函数vectorAdd()的代码,Form1.cs文件的内容如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; namespace Test00304 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //引用外部DLL [DllImport("Test00302.dll")] public static extern int vectorAdd(int[] c, int[] a, int[] b, int size); private void button1_Click(object sender, EventArgs e) { string msg = ""; int[] c = new int[5]; int[] a = new int[5] { 1, 2, 3, 4, 5 }; int[] b = new int[5] { 10, 20, 30, 40, 50 }; const int size = 5; int r = vectorAdd(c, a, b, size); if (r == 0) { msg = "计算成功\n"; msg += "计算结果:\n"; for (int i = 0; i < size; i++) msg +=c[i].ToString()+","; } else msg = "计算失败"; MessageBox.Show(msg); } } }
然后复制项目Test00302中编译的的Test00302.dll 文件到项目Test00304路径下debug文件夹中,如下图所示:
然后运行C#项目,点击按钮,开始执行CUDADLL中的函数,如果C#项目是基于.NetFramework 4.0,可能会出现如下提示消息:
检测到 PInvokeStackImbalance
Message: 对 PInvoke 函数“Test00304!Test00304.Form1::vectorAdd”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。
如下图所示:
由于在C#项目中调用DLL中函数vectorAdd()参数以及参数类型都与原函数一致,所以不存在数据类型不一致的问题,如果忽略该问题也可以继续运行。但是如果将项目的目标框架设置成.Net Framework 3.5,如下图所示,即不存在上面的“检测到PInvokeStackImbalance”问题:
运行程序,其结果如下图所示: