获取非托管 C++ C# 中的函数
我有一些权威的ANSI标准C代码。 这意味着,虽然我有源代码,但我无法翻译成另一种语言,也无法修改调用参数,因为这些操作将使权限无效。 有超过 150 个功能。
我可以进行一些偶然的更改,例如将文件名从 .C 更改为 .CPP,以便使用 Visual Studio 2009 的 C++ 编译器进行编译,我已经这样做了。 还可以添加编译器指令等。 如果需要的话,我还可以通过包装层。
另一个限制是我的公司不希望我在任何 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++ 边界上匹配:参数“2”:无法从“double[]”转换为“double*”
(如上所述,我不能使用 unsafe 来获取指针)。
当然,我想做的事情一定是可能的。
获得这些功能的最佳方式是什么?
(使用上述函数的示例代码真的很酷。)
I have some ANSI standard C code which is authoritative. What that means is that although I have the source, I can not translate to another language nor modify calling arguments, as those actions would invalidate the authority. There are over 150 functions.
I can make incidental changes, such as change the file names from .C to .CPP so that it compiles using Visual Studio 2009's C++ compiler, which I have done. Compiler directives and such can also be added. I can also go through a wrapper layer, if necessary.
Another restriction is my company does not want me to use the unsafe key word in any C# code.
I need to get at these functions from a C# program.
A typical C/C++ function looks like this:
double SomeFunction(double a, double[3] vec, double[3][3] mat);
Where the array contents are sometimes input, sometimes output, and rarely both.
I first tried making an unmanaged DLL (with the functions marked Extern C). Functions with only simple arguments (int, double) worked fine, but I could not determine how to Marshal the arrays. (Actually, I did find some sample code, but it was extremely complex and unreasonable to duplicate 150 times.)
I then tried two projects within the same solution, one in C++ and the other in C#. In the C++ project, I created a managed function which just called the original function which was marked as unmanaged. This was extremely clean and simple, and again, simple arguments worked fine. But for arrays, I couldn't find how to make the argument types match across the C# to C++ boundary:Argument '2': cannot convert from 'double[]' to 'double*'
(and as mentioned above, I can't use unsafe to get a pointer).
Certainly what I am trying to do must be possible.
What is the best way to get at these functions?
(Sample code using the above function would be really cool.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
C/C++ 实现示例:
C# 用法示例:
Sample C/C++ implementation:
Sample C# usage:
如果您无法使 extern 和 P/Invoke 解决方案发挥作用,那么包装器可能是您最好的选择。 创建使用托管和非托管代码的托管 C++ DLL。 向此 DLL 添加一个 .NET 类,该类只是 C DLL 中函数的薄包装。 您的 C# 代码可以调用 C++ .NET 类,该类将依次转发 C 函数。
通过这种方式,您可以自己编写 .NET 和非托管代码之间的转换,而不是依赖运行时来为您完成。
If you can't get the extern and P/Invoke solution to work, a wrapper is probably your best bet. Create a managed C++ DLL that uses both managed and unmanaged code. Add a .NET class to this DLL that is just a thin wrapper over the functions in your C DLL. Your C# code can call the C++ .NET class, which will in turn forward on the C functions.
This way you can write the translation between .NET and unmanaged code yourself, instead of relying on the runtime to do it for you.
使用 swig,它会为你生成你的 pinvoke
use swig, it will generate your pinvoke for you