Vega 向.NET 移植的第一次尝试

.NET的各种优点,使我无法将之束之高阁. .NET丰富的类库,功能强大,使用方便.终于进行了把VEGA向.NET移植做了第一次尝试.下图是用C#写的程序.运行速度比想像中的要好多了.仿真强调的重要的一点就是实时性.CLR没让我失望,运行得很流畅.

很多其它平台.NET平台移植后,名前加了一N.如NUnit, NHhibernate,Ndoc等,因此我把它命名为NVega.Frameword.由于仅是第一次小小尝试,我们仅仅用了几个必备函数.

//NativeMethod.cs

using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.Runtime.InteropServices;
using  System.Threading;
using  Microsoft.Win32;
using  System.Diagnostics;

namespace  NVega.Framework
{
    
internal class NativeMethod
    
{
        [DllImport(
"psvgd.dll")]
        
public static extern void vgInitWinSys(IntPtr AppInstance, IntPtr winHandle);

        [DllImport(
"psvgd.dll", CharSet = CharSet.Ansi)]
        
public static extern void vgDefineSys(string fileName);

        [DllImport(
"psvgd.dll")]
        
public static extern void vgConfigSys();

        [DllImport(
"psvgd.dll")]
        
public static extern void vgSyncFrame();

        [DllImport(
"psvgd.dll")]
        
public static extern void vgFrame();

        [DllImport(
"psvgd.dll")]
        
public static extern void vgDrawEnabled(int enable);
    }

}

经过尝试,vgDefineSys(string fileName)函数的DLLIMPORT属性CharSet只能设为Ansi,这说明,VEGA的字符串处理方式是ANSI的而非UNCODE,即在UNCODE的操作系统上,进行仿真的

//VegaThread.cs

using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.Runtime.InteropServices;
using  System.Threading;
using  Microsoft.Win32;
using  System.Diagnostics;

namespace  NVega.Framework
{
    
public class VegaThread
    
{
        
public delegate void VegaHandler();

        
private bool terminate;
        
private string fileName;
        
private Thread vgThread;
        
private IntPtr winContainer;
        
private bool vgPause;
        
private static bool started;

        
static VegaThread()
        
{
            started 
= false;
        }


        
public VegaThread(IntPtr winContainer)
            : 
this(winContainer,string.Empty)
        
{
        }


        
public VegaThread(IntPtr winContainer,string fileName)
            : 
this(winContainer, fileName, true)
        
{
        }


        
public VegaThread(IntPtr winContainer, string  fileName, bool suspend)
        
{
            
this.fileName = fileName;
            
this.winContainer = winContainer;
            
this.vgPause = this.terminate = false;
            
this.vgThread = new Thread(new ThreadStart(new VegaHandler(this.RunVegaApp)));
            
            
if(!suspend) this.Start();
        }


        
public void Start()
        
{
            
if(started) 
                
throw new RerunVegaException("Vega thread run only one time in an application instance.");

            
if(this.fileName == string .Empty)
                
throw new ArgumentNullException("ADF file name can't be null.");

            
if (this.winContainer == IntPtr.Zero)
                
throw new  ArgumentNullException("The vega  handle of windows container can't be null.");
            started 
= true;
            
this.vgThread = new Thread(new ThreadStart(new VegaHandler(RunVegaApp)));
            vgThread.Start();
        }


        
protected virtual void RunVegaApp()
        
{
            Process process 
= Process.GetCurrentProcess();
            IntPtr hInstance 
= process.Handle;

            NativeMethod.vgInitWinSys(hInstance, 
this.winContainer);
            NativeMethod.vgDefineSys(
this.fileName);
            NativeMethod.vgConfigSys();
            
while (!terminate)
            
{
                NativeMethod.vgSyncFrame();
                NativeMethod.vgFrame();
            }

            NativeMethod.vgSyncFrame();
        }


        
public void Stop()
        
{
            
this.terminate = true;
        }


        
private void Pause()
        
{
            
if (this.terminate || started) return;

            
if (vgPause)
                NativeMethod.vgDrawEnabled(
1);
            
else
                NativeMethod.vgDrawEnabled(
0);

            vgPause 
= !vgPause;
        }


        
public string  FileName
        
{
            
get
            
{
                
return this.fileName;
            }

            
set
            
{
                
this.fileName = value;
            }

        }


        
public bool Terminate
        
{
            
get
            
{
                
return this.terminate;
            }

            
set
            
{
                
this.terminate = value;
            }

        }

    }

}

我们知道在,VEGA中它自已很多处理线程.在这里它必须要与主线程分开.所以我在VegaThread类里面封装了一个线程对像.需要注意的是vgInitWinSys(hINSTANCE, HANDLE)函数,它有两个参数.第一个参数是应用程序的实例的句柄和一个父窗口的句柄. 应用程序的实例句柄,可以从Process.GetCurrentProcess().Handle;

vega在一个应用程序实例中只能运行一次.(这一点很不爽,等有空再研究这个问题,看看能否解决.)

定义了一个重运行的异常类.

//RerunVegaException.cs

using  System;
using  System.Collections.Generic;
using  System.Text;

namespace  NVega.Framework
{
    
public class RerunVegaException:Exception
    
{
        
public RerunVegaException(string message):base(message)
        
{
        }

    }

}

这样一个基本的类库就实现完了.下面就可以进行试用了.

//frmMain.cs

using  System;
using  System.Collections.Generic;
using  System.ComponentModel;
using  System.Data;
using  System.Drawing;
using  System.Text;
using  System.Windows.Forms;
using  NVega.Framework;

namespace  VegaTranslation
{
    
public partial class frmMain : Form
    
{
        
/// <summary>
        
/// Required designer variable.
        
/// </summary>

        private System.ComponentModel.IContainer components = null;

        
/// <summary>
        
/// Clean up any resources being used.
        
/// </summary>
        
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>

        protected override void Dispose(bool disposing)
        
{
            
if (disposing && (components != null))
            
{
                components.Dispose();
            }

            
base.Dispose(disposing);
        }


        
Windows Form Designer generated code

        
private System.Windows.Forms.Button btnStart;
        
private System.Windows.Forms.Panel vgContainer;
        
private System.Windows.Forms.Button btnStop;
        
private System.Windows.Forms.OpenFileDialog dlgOpen;
        
private System.Windows.Forms.Button btnBrowser;

        
my self code
    }

}

使用很简单.这里我把一个PANEL控件作为父窗口.但用的是它的句柄.

总结:这个小试验里面,一.是要注意VEGA里的字符处理是ANSI的而非UNICODE.二.应用程序的实例句柄的获取方式.三.VEGA线程封装. 这里可能读者你也感觉到了,我们没有使用VEGA的任何一个类型.的确,现在我们连VEGA显示窗口都无法用代码来最大化.这个就是下一步要做的..NET不能"直接"使用本地类型库.也许你会说用VC++.NET呀,我只想说用这个,前面的代码我们都可以不用写了.那是另外一个主题了.

我决定用COM先把一些简单的类型封装起来,再使用COM包装器.看能否成功把VEGA类型移植过来...

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值