现在项目基本都是旁边C++的哥们做好dll扔给我,然后我调用。好久之前晚上down了一份c#调用c++dll的方法,出处早已经遗忘。闲来无事,放上来好了。原作者看到后可以留言,我会把您链接放上的,帮了我很多!!!

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Reflection.Emit;
  6. using System.Runtime.InteropServices;
  7. using System.Text;
  8.  
  9. namespace TEDS_App
  10. {
  11. public enum ModePass
  12. {
  13. ByValue = 0x0001,
  14. ByRef = 0x0002
  15. }
  16. public class FaultFunc
  17. {
  18. [DllImport("kernel32.dll")]
  19. static extern IntPtr LoadLibrary(string lpFileName);
  20. [DllImport("kernel32.dll")]
  21. static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
  22. [DllImport("kernel32", EntryPoint = "FreeLibrary", SetLastError = true)]
  23. static extern bool FreeLibrary(IntPtr hModule);
  24. private IntPtr hModule = IntPtr.Zero;
  25. private IntPtr farProc = IntPtr.Zero;
  26. public void LoadDll(string lpFileName)
  27. {
  28. hModule = LoadLibrary(lpFileName);
  29. if (hModule == IntPtr.Zero)
  30. {
  31. throw (new Exception("没有找到:" + lpFileName + "."));
  32. }
  33. }
  34. public void LoadDll(IntPtr HMODULE)
  35. {
  36. if (HMODULE == IntPtr.Zero)
  37. {
  38. throw (new Exception("所传入的函数库模块的句柄为空"));
  39. }
  40. hModule = HMODULE;
  41. }
  42. public void LoadFun(string lpProcName)
  43. {
  44. if (hModule == IntPtr.Zero)
  45. {
  46. throw (new Exception("函数库模块的句柄为空,确保已进行加载dll操作"));
  47. }
  48. farProc = GetProcAddress(hModule, lpProcName);
  49. if (farProc == IntPtr.Zero)
  50. {
  51. throw (new Exception("没有找到:" + lpProcName + "这个函数的入口点"));
  52. }
  53. }
  54. public void LoadFun(string lpFileName, string lpProcName)
  55. {
  56. hModule = LoadLibrary(lpFileName);
  57. if (hModule == IntPtr.Zero)
  58. {
  59. throw (new Exception("没有找到:" + lpFileName + "."));
  60. }
  61. farProc = GetProcAddress(hModule, lpFileName);
  62. if (farProc == IntPtr.Zero)
  63. {
  64. throw (new Exception("没有找到:" + lpProcName + "这个函数的入口点"));
  65. }
  66. }
  67. public void UnLoadDll()
  68. {
  69. FreeLibrary(hModule);
  70. hModule = IntPtr.Zero;
  71. farProc = IntPtr.Zero;
  72. }
  73. public object Invoke(object[] ObjArray_Parameter, Type[] TypeArray_parameterType, ModePass[] ModePassArray_Parameter, Type Type_Return)
  74. {
  75. if (hModule == IntPtr.Zero)
  76. throw (new Exception("函数库模块的句柄为空,请确保进行了LoadLll操作"));
  77. if (farProc == IntPtr.Zero)
  78. throw (new Exception("函数指针为空,请确保已进行LoadFun操作"));
  79. if (ObjArray_Parameter.Length != ModePassArray_Parameter.Length)
  80. throw (new Exception("参数个数及其传递方式的个数不匹配"));
  81. AssemblyName MyAssemblyName = new AssemblyName();
  82. MyAssemblyName.Name = "InvokeFun";
  83. AssemblyBuilder MyAssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(MyAssemblyName, AssemblyBuilderAccess.Run);
  84. ModuleBuilder MyModuleBuilder = MyAssemblyBuilder.DefineDynamicModule("InvokeDll");
  85. MethodBuilder MyMethodBuilder = MyModuleBuilder.DefineGlobalMethod("FaultFun", MethodAttributes.Public | MethodAttributes.Static, Type_Return, TypeArray_parameterType);
  86. ILGenerator IL = MyMethodBuilder.GetILGenerator();
  87. int i;
  88. for (i = ; i < ObjArray_Parameter.Length; i++)
  89. {
  90. switch (ModePassArray_Parameter[i])
  91. {
  92. case ModePass.ByValue:
  93. IL.Emit(OpCodes.Ldarg, i);
  94. break;
  95. case ModePass.ByRef:
  96. IL.Emit(OpCodes.Ldarga, i);
  97. break;
  98. default:
  99. throw (new Exception("第" + (i + ).ToString() + "个参数没有给定正确的传递方式"));
  100. }
  101. }
  102. if (IntPtr.Size == )
  103. {
  104. IL.Emit(OpCodes.Ldc_I4, farProc.ToInt32());
  105. }
  106. else if (IntPtr.Size == )
  107. {
  108. IL.Emit(OpCodes.Ldc_I8, farProc.ToInt64());
  109. }
  110. else
  111. {
  112. throw new PlatformNotSupportedException();
  113. }
  114. IL.EmitCalli(OpCodes.Calli, CallingConvention.StdCall, Type_Return, TypeArray_parameterType);
  115. IL.Emit(OpCodes.Ret);
  116. MyModuleBuilder.CreateGlobalFunctions();
  117. MethodInfo MyMethodInfo = MyModuleBuilder.GetMethod("FaultFun");
  118. return MyMethodInfo.Invoke(null, ObjArray_Parameter);
  119. }
  120. public object Invoke(IntPtr IntPtr_Function, object[] ObjArray_Parameter, Type[] TypeArray_ParameterType, ModePass[] ModePassArray_Parameter, Type Type_Return)
  121. {
  122. if (hModule == IntPtr.Zero)
  123. throw (new Exception("函数库模块的句柄为空,请确保已进行LoadDll操作"));
  124. if (IntPtr_Function == IntPtr.Zero)
  125. throw (new Exception("函数指针IntPtr_Function为空"));
  126. farProc = IntPtr_Function;
  127. return Invoke(ObjArray_Parameter, TypeArray_ParameterType, ModePassArray_Parameter, Type_Return);
  128. }
  129. }
  130.  
  131. }

一直以来,对于C++程序员报以崇高的敬意。。。一直觉得他们屌屌的,哈哈。

调用方式如下:

  1. PlusFunction.LoadDll(@"C:\win32dll.dll");//PlusFunction为调用类的实例
  2. PlusFunction.LoadFun("MyFun");
  3. byte[] a = File.ReadAllBytes(@"E:\19-bw\19-73.jpg");
  4. object[] Parameters = new object[] {a}; // 实参为a
  5. Type[] ParameterTypes = new Type[] { typeof(byte[])}; // 实参类型为byte[]
  6. ModePass[] themode = new ModePass[] {ModePass.ByValue}; // 传送方式为值传
  7. Type Type_Return = typeof(int); // 返回类型为int
  8. ret = (int)PlusFunction.Invoke(Parameters, ParameterTypes, themode, Type_Return);

其实,c++与c#主要的就是数据类型的对应了。简单点的还好说,稍微复杂的各种麻烦。。。关键是不好调试。

下面举些我用到的例子,以后遇到其他的再补充。日积月累- -

  1. c++ c#
  2. char* char[](string.tochararray)
  3. byte* byte[]
  4. int int
  5. int* int[]
  6. 结构体
  7. c++
  8. typedef struct SRectChange_TAG
  9. {
  10. //NV_RECT rect;
  11. int x;//左上角x轴坐标
  12. int y;//左上角y轴坐标
  13. int width;//宽
  14. int height;//高
  15. int degree;//报错级别;1最低,目前暂时设定3级
  16. }
  17. SRectChange;
  18. c#
  19. [StructLayout(LayoutKind.Sequential)]
  20. public struct SRectChange
  21. {
  22. public int x;
  23. public int y;
  24. public int width;
  25. public int height;
  26. public int degree;
  27. }
  28. 结构体传递
  29. [DllImport("win32dll.dll", EntryPoint = "MyFun", CallingConvention = CallingConvention.Cdecl)]
  30. public static extern int MyFun(ref SRectChange rect, char[] str, char[] str2);
  31. c++结构体
  32. typedef struct
  33. {
  34. int osVersion;
  35. int majorVersion;
  36. int minorVersion;
  37. int buildNum;
  38. int platFormId;
  39. char szVersion[];
  40. }OSINFO;
  41. c#
  42. // OSINFO定义
  43. [StructLayout(LayoutKind.Sequential)]
  44. public struct OSINFO
  45. {
  46. public int osVersion;
  47. public int majorVersion;
  48. public int minorVersion;
  49. public int buildNum;
  50. public int platFormId;
  51. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
  52. public string szVersion;
  53. }
  54.  
  55. 结构体数组传递
  56. c#代码
  57. [DllImport("win32dll.dll", EntryPoint = "MyFun", CallingConvention = CallingConvention.Cdecl)]
  58. public static extern int MyFun(IntPtr p, char[] str, char[] str2);
  59. 数组传指针
  60. char[] newpic = ("").ToCharArray();
  61. char[] oldpic = ("").ToCharArray();
  62. SRectChange[] rects = new SRectChange[];
  63. for (int i = ; i < rects.Length; i++)
  64. {
  65. rects[i] = new SRectChange();
  66. }
  67. IntPtr[] ptArr = new IntPtr[];
  68. ptArr[] = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SRectChange)) * ); //分配包含两个元素的数组
  69. IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SRectChange)));
  70. Marshal.Copy(ptArr, , pt, ); //拷贝指针数组
  71. MyFun(pt, newpic, oldpic);
  72. for (int i = ; i < ; i++)
  73. {
  74. rects[i] = (SRectChange)Marshal.PtrToStructure((IntPtr)(pt.ToInt32() + i * Marshal.SizeOf(typeof(SRectChange))), typeof(SRectChange));
  75. Console.WriteLine("x:{0} y:{1}", rects[i].x, rects[i].y);
  76. }

还说那句话:种一棵树最好的时间是十年前,其次是现在。

C#调用C++ Dll的更多相关文章

  1. c# 调用c++DLL方法及注意事项

    引用命名空间 using System.Runtime.InteropServices 调用方法: 一.静态加载 用DllImprot方式来加载c++DLL.如下格式: //对应c++方法 //voi ...

  2. 在.net中调用Delphi dll的Pchar转换

    Pchar是非托管代码,要在.net中调用Delphi dll中的功能,请使用MarshalAs属性告知.net调用PInvoke去转换.net中标准的string类型.如果Delphi dll是De ...

  3. Java调用第三方dll文件的使用方法 System.load()或System.loadLibrary()

    Java调用第三方dll文件的使用方法 public class OtherAdapter { static { //System.loadLibrary("Connector") ...

  4. C#调用C++ DLL类方法

    C++的优势在于高效灵活,C#的优势在于简单易用,两者结合起来对项目开发来说是件好事,而且C++不容易反编译,也保障了代码的安全性,如果一些核心算法使用C#编写,那么保密就是一个问题. C++生成的D ...

  5. paip.java 调用c++ dll so总结

    paip.java 调用c++ dll so总结 ///////JNA (这个ms sun 的) 我目前正做着一个相关的项目,说白了JNA就是JNI的替代品,以前用JNI需要编译一层中间库,现在JNA ...

  6. C#调用C++ DLL 文件

    说来惭愧,都注册一年多了,却没有发表过一篇正式的博文,中间很多学习的过程也没有记录下来.如今到了一个新的环境,也有了学习的机会,一定要把每天的收获记录一下. 要做的东西需要引用C++编写的DLL,刚开 ...

  7. LR调用动态链接库DLL

    什么是动态库? 动态库一般又叫动态链接库(DLL),是Dynamic Link Library 的缩写形式,DLL是一个包含可由多个程序同时使用的代码和数据的库. 动态链接提供了一种方法 ,使进程可以 ...

  8. 【JNI】OPUS压缩与解压的JNI调用(.DLL版本)

    OPUS压缩与解压的JNI调用(.DLL版本) 一.写在开头: 理论上讲,这是我在博客园的第一篇原创的博客,之前也一直想找个地方写点东西,把最近做的一些东西归纳总结下,但是一般工程做完了一高兴就把东西 ...

  9. c#调用c++ dll的几种类型(转)

    http://www.sosuo8.com/article-2012/dllleixingzhuanhuan.htm   在合作开发时,C#时常需要调用C++DLL,当传递参数时时常遇到问题,尤其是传 ...

随机推荐

  1. MFC学习 画图设置字体按钮风格

    修改按钮样式时, 设置按钮关联哪个按钮类, 按钮类是自己写的, 从CButton继承, 重写DrawItem可修改按钮样式. 代码中包括画线, 点, 圆, 设置这些的样式, 如线粗, 颜色, 字体. ...

  2. C# ToolStripProgressBar

    ToolStripProgressBar 将所有 ToolStrip控件的移动和渲染功能和其典型的进程跟踪功能结合在一起.ToolStripProgressBar通常放在StatusStrip中,偶尔 ...

  3. POJ2376_Cleaning Shifts_C++

    题目:http://poj.org/problem?id=2376 英文题强行看不懂,只看的懂输入输出,输入n,m,下接n行每行一个区间两个数左端点 l,有端点 r 给出n个闭区间,求选择最少的区间能 ...

  4. iis 站点部署后 Microsof .Net Framework异常

    最近在部署站点到 iis 中时,遇到 iis 崩溃的问题,一打开部署好 的站点后,就出现 Microsoft .Net Framework 异常的消息提示,具体的 异常情况如下: 于是在网上查找了很多 ...

  5. SQO (标准查询运算符)方法 & Linq To Object

    #region SQO (标准查询运算符) 方法 #region Where() Find() FindAll() FirstOrDefault()等方法 static void c01where() ...

  6. 通用简单的 分页 SQL

    select                ID,TITLE,CONTENT,USERNAME,REALNAME,UNIT,UNITID,NOWTIMES,ACCEPTERID,ACCEPTERNAM ...

  7. zedboard如何从PL端控制DDR读写(二)——AXI总线

     虽然Xilinx已经将和AXI时序有关的细节都封装起来,给出了官方IP和向导生成自定义IP,用户只需要关注自己的逻辑实现,但是还是有必要简单了解一下AXI的时序,毕竟咱是做硬件设计的. AXI(Ad ...

  8. linux地址空间划分

    LDD讲的很明白了: Linux 是一个虚拟内存系统, 意味着用户程序见到的地址不直接对应于硬件使用的物理地址. 虚拟内存引入了一个间接层, 它允许了许多好事情. 有了虚拟内存, 系统重运行的程序可以 ...

  9. linq to xml 基本操作

    使用XDocument类来进行简单的xml操作,用于软件参数的设置保存. using System; using System.Collections.Generic; using System.Li ...

  10. 一款安卓ShowcaseView视图源码效果

    该源码是从源码天堂那边转载过来的,大家可以看看一下吧啊,一款安卓ShowcaseView视图源码效果,非常不错的,特别是在做引导时使用. 源码下载地址:http://code.662p.com/vie ...