• C# 调用 qrencode的动态库


     自己根据qrencode的源码导了一个dll动态库,见:

    自己希望能用C#语言调用以下。
    首先构建需要的对象:
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct QrCodeLL
        {
    
            public int version;         ///< version of the symbol
            public int width;
            public int size;///< width of the symbol
            public IntPtr data; ///< symbol data
    
        }
    
    接口:
    [DllImport("LLQrencode.dll", EntryPoint = "OutPutQrCodeCSharp", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
            public static extern IntPtr OutPutQrCodeCSharp(byte[] bts);//接收参数对应 unsigned char* 也就是二维码内容
    

    使用方法:

         public Form1()
            {
                InitializeComponent();
            }
            string str = "https://www.cnblogs.com/HelloQLQ/p/16289395.html";
            private void button1_Click(object sender, EventArgs e)
            {
                var byts = Encoding.UTF8.GetBytes(str);
    
                IntPtr ptr = IntPtr.Zero;
                var i = TestLL.OutPutQrCodeCSharp(byts);
                var qCode = Marshal.PtrToStructure<QrCodeLL>(i);
    
                int size = qCode.width * qCode.width + qCode.width - 1;
                byte[] managedArray = new byte[size];
                Marshal.Copy(qCode.data, managedArray, 0, size);
    
                var arr = getPngArr(managedArray, qCode.width);
                var img = GetMap(arr, qCode.width);
    
                picBox.Image = Magnifier(img, 4);
                picBox.Refresh();
            }
    
            public byte[] getPngArr(byte[] data, int width)
            {
                byte[] arr = new byte[data.Length];
                
                int m = 0;
                for (int y = 0; y < width; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        if ((data[y * width + x] & 0x01) == 1)
                        {
                            arr[m++] = 0;
                        }
                        else
                        {
                            arr[m++] = 1;
                        }
                    }
                }
                return arr;
            }
    
            public Bitmap GetMap(byte[] arr, int w)
            {
                Bitmap map = new Bitmap(w, w);
    
                for (int i = 0; i < w; i++)
                {
                    for (int j = 0; j < w; j++)
                    {
                        if (arr[i * w + j] == 1)
                            map.SetPixel(i, j, Color.White);
                        else
                        {
                            map.SetPixel(i, j, Color.Black);
                        }
                    }
                }
                return map;
            }
    
            public Bitmap Magnifier(Bitmap srcbitmap, int multiple)
            {
                if (multiple <= 0) { multiple = 0; return srcbitmap; }
                Bitmap bitmap = new Bitmap(srcbitmap.Size.Width * multiple, srcbitmap.Size.Height * multiple);
                BitmapData srcbitmapdata = srcbitmap.LockBits(new Rectangle(new Point(0, 0), srcbitmap.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                BitmapData bitmapdata = bitmap.LockBits(new Rectangle(new Point(0, 0), bitmap.Size), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                unsafe
                {
                    byte* srcbyte = (byte*)(srcbitmapdata.Scan0.ToPointer());
                    byte* sourcebyte = (byte*)(bitmapdata.Scan0.ToPointer());
                    for (int y = 0; y < bitmapdata.Height; y++)
                    {
                        for (int x = 0; x < bitmapdata.Width; x++)
                        {
                            long index = (x / multiple) * 4 + (y / multiple) * srcbitmapdata.Stride;
                            sourcebyte[0] = srcbyte[index];
                            sourcebyte[1] = srcbyte[index + 1];
                            sourcebyte[2] = srcbyte[index + 2];
                            sourcebyte[3] = srcbyte[index + 3];
                            sourcebyte += 4;
                        }
                    }
                }
                srcbitmap.UnlockBits(srcbitmapdata);
                bitmap.UnlockBits(bitmapdata);
                return bitmap;
            }
    
    运行效果:
    0

    总结:
    c++使用的 undesign char* 最好是作为接口的返回参数,C#端用IntPtr接收,
    接收后,通过Marshal.PtrToStructure(i);转为结构体。
    结构体里的指针也是对应c++里的 undesign char*,这样接收:
    int size = qCode.width * qCode.width + qCode.width - 1;
    byte[] managedArray = new byte[size];
    Marshal.Copy(qCode.data, managedArray, 0, size);
    需要注意,需要知道接收数组的大小,这里根据源码得知大小是这样算的,其他的话就需要在返回参数里给明白了。
    getPngArr,是把数据转为二维码字节数组。
    GetMap,原始二维码图像大小
    Magnifier,方法二维码图片尺寸。网上抄的。
  • 相关阅读:
    【深入理解JAVA虚拟机】第一部分.走进Java
    【设计模式最终总结】桥接模式 VS 外观模式
    【设计模式最终总结】组合模式:树形结构的处理
    【设计模式最终总结】桥接模式(接口模式):处理多维度变化
    【设计模式最终总结】适配器模式
    深入编解码:ASCII,UNICODE,UTF8等
    好妈妈【第四章】培养良好的学习习惯
    【设计模式最终总结】建造者模式:复杂对象的组装与创建
    上火流鼻血
    Spring Data Jpa 学习笔记
  • 原文地址:https://www.cnblogs.com/HelloQLQ/p/16364888.html
Copyright © 2020-2023  润新知