关闭

C#调用C++动态库的一些理解

发表于:2015-1-26 09:42

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Bonker    来源:51Testing软件测试网采编

  c#调用c++动态库一般我们这样写
  [DllImport("UCamer.dll", CallingConvention = CallingConvention.Winapi)]
  public extern static void Disp_Destroy(IntPtr hShow);
  DllImport的第一个参数UCamer.dll是动态库dll的路径,此dll放在程序运行的根目录或者c:windows/sytem32下
  CallingConvention 参数是c#调用c++的方式 是个枚举 msdn解释如下
  从上面来看Winapi方式是根据系统自动选择调用规约的。 而thisCall是对c++类的调用方法。 所以 一般情况下我们选择Winapi就可以了。
  c#调用dll另一个难点:数据类型转换
  http://wenku.baidu.com/link?url=SihlxtHC-HMcEhq3izpd2bux8rNaKOMTpu8NPqjdYlLSwYSV1CqNJdVbxkaZm7OqaaSTEK-KUJqX5jbtkdpnUZ_38No4tsrgqCsf7Th5dqK
  百度文库这篇文章基本把c++与c#的对应数据类型总结完了。但是为什么这里还要说呢
  1,百度文库这篇文章,包括大部分度娘的类型转换的资料中 对c++中的返回值类型char[] 都转换成了char[] 没做任何改变。
  c++中char占一个字节,assic编码。而c#中的char占2个字节(我是在中文版的vs中测试的)。
  如果这样转换就会出现问题,很容易发生越界,或者读写到受保护的内存等问题。
  解决方法是 把char[] 变成c#中的byte[] ,再用Encoding.Assic.getstring方法转换。
  2,关于指针,c++所有的指针 在c#上用Intptr ,问题又来了。假如返回的Intptr是个数组指针,在c#中我们怎么读取数组里面的元素呢?
  Marshal.Copy();
  Marshal类是c#中专门把非托管内存转换成托管内存的神器,不需要unsafe。 Marshal中copy方法是最最常用的方法。里面有16个重载。能解决目前你能遇到的大部分问题。
  msdn中对各个重载解释如下
  我们也可以使用共享内存的方式进行操作。部分代码如下
//初始化返回图片的大小等信息
myContext = new VlcControlWpfRendererContext(width, height, System.Windows.Media.PixelFormats.Bgr24);
//创建共享内存区域
myBitmapSectionPointer = Win32Interop.CreateFileMapping(new IntPtr(-1), IntPtr.Zero, Win32Interop.PageAccess.ReadWrite, 0, myContext.Size, null);
//获取共享内存的首地址
map = Win32Interop.MapViewOfFile(myBitmapSectionPointer, Win32Interop.FileMapAccess.AllAccess, 0, 0, (uint)myContext.Size);
//把接收后的图片拷入共享内存区域
Win32Interop.CopyMemory(map, data, myContext.Size);
//把共享内存中的数组转换为图片
myBitmap = (InteropBitmap)Imaging.CreateBitmapSourceFromMemorySection(myBitmapSectionPointer, myContext.Width, myContext.Height, myContext.PixelFormat, myContext.Stride, 0);
  这里是共享内存的辅助类  主要是一些api函数
  其实Intptr本质也是一个Int,Int在c#中和Int32是一样的。所以基本上指针,Long,int在c#中都是int。只是这样些 方便大家知道他是c++中的什么类型,方便转换而已。
  3,c++中的函数指针  与c#中的委托
  这是c++中对函数指针的定义
  typedef VOID (WINAPI *PUSERCALL)( PUCHAR pData, ULONG Length, PVOID pUserData );
  对应c#中的例子如下
  public delegate void PUSERCALL(IntPtr pData, uint Length, UInt32 pUserData);
21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号