Getting at unmanaged C++ functions from C#
我有一些权威的ANSI标准C代码。这就是说,尽管我有原文,但我不能翻译成另一种语言,也不能修改调用参数,因为这些动作会使授权无效。有超过150个功能。
我可以进行偶然的更改,例如将文件名从.C更改为.CPP,以便使用Visual Studio 2009的C编译器进行编译。也可以添加编译器指令等。如有必要,我还可以遍历package层。
另一个限制是我的公司不希望我在任何C#代码中使用不安全的关键字。
我需要从C#程序中获取这些功能。
典型的C / C函数如下所示:
double SomeFunction(double a, double[3] vec, double[3][3] mat);
有时输入数组内容,有时输出数组内容,很少同时使用这两种内容。
我首先尝试制作一个非托管的DLL(带有标记为Extern C的功能)。仅带有简单参数(int,double)的函数可以正常工作,但是我无法确定如何对数组进行编组。 (实际上,我确实找到了一些示例代码,但是它非常复杂并且重复150次是不合理的。)
然后我在同一个解决方案中尝试了两个项目,一个在C中,另一个在C#中。在C项目中,我创建了一个托管函数,该函数仅称为原始函数,该函数被标记为非托管。这是非常干净和简单的,再说一次,简单的参数就可以了。但是对于数组,我找不到如何使参数类型跨C#到C边界匹配:
(并且如上所述,我不能使用不安全的方法来获取指针)。
当然,我要做的事情一定是可能的。
获得这些功能的最佳方法是什么?
(使用上述函数的示例代码将非常酷。)
示例C / C实现:
1 2 3 4 5 6 7 8 9 10 11 | extern"C" __declspec(dllexport) double SomeFunction(double a, double vec[3], double mat[3][3]) { double sum = a; for (int ix = 0; ix < 3; ++ix) { sum += vec[ix]; for (int iy = 0; iy < 3; ++iy) { sum += mat[ix][iy]; } } return sum; } |
示例C#用法:
1 2 3 4 5 6 7 8 9 10 11 12 13 | private void Form1_Load(object sender, EventArgs e) { double[] vec = new double[3]; double[,] mat = new double[3, 3]; for (int ix = 0; ix < 3; ++ix) { vec[ix] = ix; for (int iy = 0; iy < 3; ++iy) { mat[ix, iy] = (ix + 1) * iy; } } double sum = SomeFunction(1, vec, mat); } [System.Runtime.InteropServices.DllImport("cpptemp8.dll")] private static extern double SomeFunction(double a, double[] vec, double[,] mat); |
如果您无法使用外部和P / Invoke解决方案,那么package可能是最好的选择。创建同时使用托管代码和非托管代码的托管C DLL。向此DLL添加一个.NET类,该类只是对C DLL中的函数的一个简单package。您的C#代码可以调用C .NET类,该类将依次在C函数上进行。
这样,您可以自己编写.NET和非托管代码之间的转换,而不必依赖运行时为您完成转换。
使用swig,它将为您生成拼音