zoukankan      html  css  js  c++  java
  • C#调用汇编dll (载)

    汇编语言有性能优势,C#有灵活性,组织结构优势。两者结合使用是我的理想。
    想法是大的组件和类层次使用C#;关键子程序使用汇编DLL。
    可以从网上下载MASM32工具包。版本可以是8.2或者9.0。
    我用汇编写了一个DLL。功能是求和整数数组。

    .386
    .model flat, stdcall
    option casemap:none
    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\user32.inc
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib

    .code
    LibMain proc hInstDLL:DWORD, reason:DWORD, unused:DWORD
        .if reason == DLL_PROCESS_ATTACH
            MOV EAX,TRUE
            ret
        .endif
        ret
    LibMain Endp

    SumArray proc StdCall point:DWORD,len:DWORD
        push esi
        push ebx
        mov esi,point
        mov ebx,len
        mov eax,[esi]

        dec ebx
        .if ! zero?
            .repeat
                add esi,4
                add eax,[esi]
                dec ebx
            .until zero?
        .endif

        pop ebx
        pop esi
        ret
    SumArray endp

    End LibMain

    我也是刚学的汇编,如果有什么失误的话,就请多指教了。
    保存为dll.asm之后,点project->build all菜单。已经生成了dll.obj。
    之后写dll.def文件:

    LIBRARY dll
    EXPORTS SumArray

    运行masm32/bin目录下的命令link /subsystem:windows /dll /def:d:/project/asm/dll.def d:/project/asm/dll.obj
    这样在bin目录下就有了dll.dll文件。(不是很熟,勿笑)

    在C#里调用这个dll并不复杂。
    1.将那个dll.dll拷贝到bin/debug目录下。
    2.加上using System.Runtime.InteropServices;
    3.声明外部方法
        [DllImport("dll.dll")]
        public static extern Int32 SumArray(Int32* point, Int32 length);
    4.调用
        sum = SumArray(point, source.Length);
    5.因为使用了指针,所以需要把类设为unsafe;
        public unsafe partial class Form1
    6.设定项目的unsafe属性。

    我编了段程序测试它的性能:

                int[] source = new int[100000];
                Random random 
    = new Random();
                
    for (int i = 0; i < source.Length; i++)
                
    {
                    source[i] 
    = random.Next(100);
                }


                
    int sum=0;
                
    long start = Environment.TickCount;
                
    for (int time = 0; time < 1000; time++)
                
    {
                    sum 
    = 0;
                    
    foreach (int v in source)
                    
    {
                        sum 
    += v;
                    }

                }

                
    long cost = Environment.TickCount - start;
                Console.WriteLine(
    "MSIL result={0};cost={1}", sum, cost);

                start 
    = Environment.TickCount;
                
    for (int time = 0; time < 1000; time++)
                
    {
                    sum 
    = 0;
                    
    fixed(int* pstart = source, pend = &source[source.Length-1])
                    
    {
                        
    for (int* pnow=pstart; pnow < pend; pnow++)
                        
    {
                            sum 
    += *pnow;
                        }

                    }

                }

                cost 
    = Environment.TickCount - start;
                Console.WriteLine(
    "CSP result={0};cost={1}", sum, cost);

                
    fixed (int* point = source)
                
    {
                    start 
    = Environment.TickCount;
                    
    for (int time = 0; time < 1000; time++)
                    
    {
                        sum 
    = CalArray(point, source.Length);
                    }

                    cost 
    = Environment.TickCount - start;
                    Console.WriteLine(
    "MASM result={0};cost={1}",sum,cost);
                }

    跑下来的结果,C#遍历求和平均630毫秒,C#指针求和420毫秒,汇编求和180毫秒。这还没用MMX。

    原文地址:http://www.cnblogs.com/fujingqiu/   作者应该是:fujingqiu  

  • 相关阅读:
    SpringBoot表单验证
    新创建的maven项目,显示的jdk版本与使用的不一致
    maven常用的构建命令
    maven 配置说明
    springmvc 初始化参数绑定(使用属性编辑器) 来处理类型转换问题
    【LOJ#10180】烽火传递 单调队列+dp
    【洛谷P1854】花店橱窗 线性dp+路径输出
    【CF1076D】Edge Deletion 最短路+贪心
    【洛谷P5020】货币系统 完全背包
    【洛谷P5018】对称二叉树
  • 原文地址:https://www.cnblogs.com/tuyile006/p/583702.html
Copyright © 2011-2022 走看看