zoukankan      html  css  js  c++  java
  • c# 调用c++DLL方法及注意事项

    引用命名空间 using System.Runtime.InteropServices

    调用方法:

    一、静态加载

    用DllImprot方式来加载c++DLL。如下格式:

           //对应c++方法
           //void DogInit(WORD*,HWND) //错误返回值,窗口句柄
           [DllImport("DOG.dll", EntryPoint = "DogInit", CallingConvention = CallingConvention.Cdecl)]
           public static extern void DogInit(out short x, IntPtr hwnd);
    
           //对应c++方法
           //void DogReadInfo(WORD*,int,unsigned char*,unsigned short) //错误返回值,读取哪项,返回的内容,初始化长度
           [DllImport("DOG.dll", EntryPoint = "DogReadInfo", CallingConvention = CallingConvention.Cdecl)]
           public static extern void DogReadInfo(out short x, int y,[MarshalAs(UnmanagedType.LPArray,SizeConst=512)]byte[] z,short w);
    
           /// <summary>
           /// 初始化加密狗
           /// </summary>
           public static void DogInit()
           {
               IntPtr zero = IntPtr.Zero;
               short x = -1;
               DogInit(out x,zero);
               //此时x保存了返回的错误码,如0、1、2
           }
    
           public static void DogReadInfo()
           {
               short x;
               int y = 0;
               byte[] z = new byte[512];
               short w = 512;
               DogReadInfo(out x,y,z,w);
               //此时x保存了返回的错误码
               //z保存了返回的读取内容
               string content = System.Text.Encoding.Default.GetString(z);
           }

    注意:

    1、如果只有一个DLL可以用这种方式,把DLL放在bin/Debug或bin文件夹下,在控制台窗体应用程序和Web网页应用程序都有效。如果有多个DLL,存在依赖调用,如A、B两个DLL,A会调用B里面的方法,因为[DllImport("A.dll")] 这样写只能调用一个DLL,在控制台窗体应用程序中,会自动加载B,但是在Web网页应用程序不会自动加载B,导致返回错误码找不到文件。要是这样写[DllImport("A.dll")] 、[DllImport("B.dll")] ,还是不会加载B。用下面二中的动态加载,依然只能加载一个DLL。解决方法:把A、B复制到系统文件夹下,32位系统复制到c/windows/system32下,64位系统复制到c/windows/syswow64文件夹下,写的时候只用[DllImport("A.dll")],就会自动加载B。这种方式只适用于你可以控制电脑,如果用的别人的服务器空间,没法复制,有可能的话最好把A、B编译到一个DLL中来调用。

    2、数据格式对应问题。

    二、动态加载

    1、用Assembly方式加载,这种方式只适用于托管代码。c++也可以编译为托管代码。依然只能加载一个DLL。

    2、用LoadLibrary和GetProcAddress方式加载,这种方式可以加载非托管代码。依然只能加载一个DLL。

    如下格式:

    public class DllInvoke
    {
      [DllImport("kernel32.dll")]
      private extern static IntPtr LoadLibrary(String path);
      [DllImport("kernel32.dll")]
      private extern static IntPtr GetProcAddress(IntPtr lib, String funcName);
      [DllImport("kernel32.dll")]
      private extern static bool FreeLibrary(IntPtr lib);
      private IntPtr hLib;
    
      public DllInvoke(String DLLPath)
      {
        hLib = LoadLibrary(DLLPath);
      }
      ~DllInvoke()
      {
        FreeLibrary(hLib);           
      }
      //将要执行的函数转换为委托
      public Delegate Invoke(String APIName,Type t) 
      {
        IntPtr api = GetProcAddress(hLib, APIName);
        return (Delegate)Marshal.GetDelegateForFunctionPointer(api,t);
      }
    }
      //使用时候
        public class Class1
        {
            //定义委托变量
            public delegate int C();
    
            public ActionResult Index()
            {
                //在方法里初始化类
                DllInvoke dllInvoke = new DllInvoke("DLL绝对路径"); //也可以把Dll保存在bin下,用相对路径转换为绝对路径
                 //调用类里面方法
                C c = (C) dllInvoke.Invoke("DLL里面方法名如DogInit", typeof (C));
                 //得到返回值
                int result = c.Invoke();
            }
        }

    三、其他方式

     在搜索过程中有些关键字也有启示,但没有往下找。如更改Dll搜索目录,加入bin目录到DLL搜索顺序,DllImport加载依赖项Dll。

    四、其他文章,看看

    http://www.cnblogs.com/szytwo/archive/2011/12/11/2283780.html

    http://www.cnblogs.com/kvspas/archive/2008/12/15/1355033.html

    如有地方不正确,欢迎提出。

  • 相关阅读:
    WEB开发者必备的7个JavaScript函数
    json分别算出元素的个数和最多的元素
    jquery 对 Json 的各种遍历
    判断图片是否加载完成
    obj转换成数组
    用JavaScript获取页面上被选中的文字的技巧
    PAT 1088 三人行(20 分)(暴力破解+流程分析)
    PAT 1087 有多少不同的值(20)(STL-set代码)
    PAT 1086 就不告诉你(15 )(代码)
    PAT 1087 有多少不同的值(20)(STL—set)
  • 原文地址:https://www.cnblogs.com/heifengwll/p/3995441.html
Copyright © 2011-2022 走看看