结合C++和C#是一个好主意还是会造成任何直接问题?
我有一个应用程序,需要一些部分是C++,有些部分是C#(为了提高效率).在C#中使用本机C++ DLL的最佳方法是什么?
问题显然是如何将他自己的C++代码集成到他的C#解决方案中,而不仅仅是使用什么属性来从win32 API调用现有函数.即使答案已被接受,我认为这是不完整的,以下内容应适用.
是的,在任务可以运行得更快,使用更少的资源,以及在某些情况下访问.net框架中不可用的方法的情况下,这是常见的做法.
如果你的目标是提高效率,你需要编写一个原生的非托管C++库,你将在visual studio中创建一个新的非托管C++项目(编译为dll库),并从你的C#项目中引用这个库.
在您的情况下,您似乎可能正在编写非托管C++库,以下内容适用.
至于您询问的任何直接问题,它会影响部署和混淆.
部署:请记住,您构建的C#DLL将在任何CPU(32位和64位)上运行,但是这个新的本机和非托管C++库将强制您的程序特定于32或64.
这是您将在Visual Studio配置管理器中配置的内容,并将在编译时进行处理,您将为C#程序集选择AnyCPU,并为您的新的非托管C++库选择,这将是它自己的项目,您将不得不从win32或x64中选择.
因此,您现在将有2个设置,建议最佳做法是使用单独的设置,一个用于32,另一个用于64.或者由于32位支持速度非常快,您可以只关注64位.
此外,您的库最终可能会引用Visual Studio提供的VC++ redistibutable,您可能必须将其包含在部署中,尽管它的某些版本包含在许多操作系统中,我发现它很少与我编译的相同,并且它是最好的与您的应用程序一起部署它以确保.如果缺少此包,则目标计算机将在事件查看器 - >应用程序日志中具有SideBySide异常.
要捕获和处理从非托管代码抛出的异常,唯一有效的catch是空的,catch()之后的括号中没有异常类型的catch.因此,您可以将对此非托管代码的调用包装起来,以处理从非托管代码中抛出的所有非托管异常,如果您放置类似catch(异常)的.net类型,它将跳过它.在托管代码中捕获非托管异常的唯一方法是采用这种格式.
try { //call unmanaged code } catch { //handle unmanaged exception }
混淆:从C#完成的任何现在调用非托管代码的方法调用现在将被排除在自动重命名之外.另一方面,如果您的非托管C++库需要从托管程序集中调用方法,那么需要手动重命名这些方法,以便C++库可以看到它们.
如果您只需要调用知名的C++库(如Windows),则无需创建新的非托管C++项目,只需使用上一个答案中建议的[DllImport()]属性.在这种情况下,你可以看看这个参考http://www.pinvoke.net/
是的,使用C#和C++为您的产品是非常普遍和一个好主意.
有时您可以使用托管C++,在这种情况下,您可以像使用任何其他.NET模块一样使用托管C++模块.
通常,您可以在C#中执行所有操作.对于您需要在C++中执行的部分,您通常会创建一个C++ DLL,然后从C#调用该DLL.参数的编组会自动为您完成.
以下是将DLL内部的C函数导入C#的示例:
[DllImport("user32", CharSet=CharSet.Auto, SetLastError=true)] internal static extern int GetWindowText(IntPtr hWnd, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpString, int nMaxCount);