zoukankan      html  css  js  c++  java
  • .NET调用非托管程式(标准DLL篇)

    .NET调用非托管程式(标准DLL篇)

    Posted on 2005-06-25 12:23 Arping.Net探索 阅读(91) 评论(0)  编辑 收藏

    前端时间写了篇.Net调用Delphi写的COM接口,同一套算法在不同的环境下运行,但后来想了想写成COM,别的程序调用COM效率太低,如果写成标准的DLL也许高些,于是尝试把压缩加密算法写成标准的DLL.
    1.在Delphi6中新建一个Dll 扩展,把加密压缩单元引用进来,申明函数

    library CompressDll;

    { Important note about DLL memory management: ShareMem must be the
      first unit in your library's USES clause AND your project's (select
      Project-View Source) USES clause if your DLL exports any procedures or
      functions that pass strings as parameters or function results. This
      applies to all strings passed to and from your DLL--even those that
      are nested in records and classes. ShareMem is the interface unit to
      the BORLNDMM.DLL shared memory manager, which must be deployed along
      with your DLL. To avoid using BORLNDMM.DLL, pass string information
      using PChar or ShortString parameters. }

    uses
      SysUtils,
      Classes,
      DES in 'DES.pas',
      uSoapPacketComUnCompressor in 'uSoapPacketComUnCompressor.pas';

      procedure CompressData(const sSource : string;out sTarget : string) export; stdcall;
      begin
         sTarget := XTToCompressSoapPacket(sSource);
      end;

      procedure unCompressData(const sSource : string;out sTarget : string) export; stdcall;
      begin
         sTarget := XTToUnCompressSoapPacket(sSource);
      end;

      procedure DeCryptData(const sSource, aKey: string;out sTarget : string) export; stdcall;
      begin
         sTarget := DeCrypt(sSource,aKey);
      end;

      procedure EnCryptData(const sSource, aKey: string;out sTarget : string) export; stdcall;
      begin
         sTarget := EnCrypt(sSource,aKey);
      end;

      procedure ShowMe(const aStr :array of Byte ;out aData : array of Byte) export ;stdcall;
      var
        SysLogFilePath : string;
        NewLogFile: TFileStream;
        SysEventLogFile : TextFile;
        i : integer;
        a : Byte;
      begin
         SysLogFilePath := 'D:\1.log';
         if not FileExists(SysLogFilePath) then
         begin
            NewLogFile := TFileStream.Create(SysLogFilePath, fmCreate or fmShareDenyRead);
            if Assigned(NewLogFile) then
               FreeAndNil(NewLogFile);
         end;

         AssignFile(SysEventLogFile, SysLogFilePath);
         try
            try
              Append(SysEventLogFile);
              Writeln(SysEventLogFile,
                      DateTimeToStr(Now) + aStr);

              a := 'd';

              aData = aStr + a;


            finally
              CloseFile(SysEventLogFile);
            end;
         except
            on e : exception do
            begin
               //抛弃异常
            end;
         end;
          
      end;
    {$R *.res}

    exports
       CompressData,unCompressData,DeCryptData, EnCryptData,ShowMe;
    begin
    end.
    在Delphi中如下调用,可以通过
    procedure TForm1.BitBtn1Click(Sender: TObject);
    var
      sSource : string;
      sTarget : string;
      LibHandle: THandle;
      CompressData : TCompressData;
    begin
       sSource := self.Edit1.Text ;
       if( sSource  = '') then
       begin
          exit;
       end;
       LibHandle := LoadLibrary(PChar(UPDATE_DATA_DLL_PATH));

      try
        if LibHandle = HINSTANCE_ERROR then
           raise EDLLLoadError.Create('Unable to Load DLL');

        @CompressData := GetProcAddress(LibHandle, 'CompressData');
        if not (@CompressData = nil) then
        begin
           sTarget := CompressData(sSource);
           self.Edit2.Text  := sTarget;
        end;
      finally
        {unload the DLL}
        FreeLibrary(LibHandle);
      end;
    end;

    但是在C#中如下调用,通过查看日志,却把字符串截断了一部分,如果标准DLL返回的不是string类型而是Integer或者是procedure都可以调用成功。希望有高手能指点一二。
    [DllImport("CompressDll.dll",CharSet=CharSet.Unicode,SetLastError=true)]
            
    public static extern void CompressData(string sSource,ref string sTarget);

            [DllImport(
    "CompressDll.dll",CharSet=CharSet.Unicode,SetLastError=true)]
            
    public static extern void unCompressData(string sSource,ref string sTarget);


            [DllImport(
    "CompressDll.dll",CharSet=CharSet.Ansi,SetLastError=true)]
            
    public static extern void ShowMe(string aStr,ref string aData);



            
    private void button5_Click(object sender, System.EventArgs e)
            
    {
                
    if(this.textBox1.Text == string.Empty)
                
    {
                    MessageBox.Show(
    "null param");
                }


                
    try
                
    {
                    
    string aSource = this.textBox1.Text;
                    
    string aTarget = string.Empty;

                    ShowMe(aSource,
    ref aTarget);
                    
    //CompressData(aSource,ref aTarget);
                    
                    
    this.textBox2.Text = aTarget;
                }

                
    catch(Exception ex)
                
    {
                    MessageBox.Show(ex.Message);
                }

            }
  • 相关阅读:
    阿里云POLARDB荣膺2019中国数据库年度最佳创新产品
    实时大数据开发难、运维难、应用难?来,一站解决!
    阿里云应用实时监控 ARMS 再升级,支持 Prometheus 开源生态
    一线实践 | 借助混沌工程工具 ChaosBlade 构建高可用的分布式系统
    使用DataX同步MaxCompute数据到TableStore(原OTS)优化指南
    Twitter 宣布抛弃 Mesos,全面转向Kubernetes
    阿里云Kubernetes服务上使用Tekton完成应用发布初体验
    Knative Tracing 介绍
    不断被取代的传统职业:快速发展的智能交互
    bzoj1433: [ZJOI2009]假期的宿舍
  • 原文地址:https://www.cnblogs.com/fuyingke/p/189869.html
Copyright © 2011-2022 走看看