• .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);
                }

            }
  • 相关阅读:
    Silverlight 学习笔记(二)silverligth 界面布局
    (C#)WinForm窗体间传值
    软件开发所需要的十三个文档
    XP下安装SQL2000企业版本(转载)
    .net 框架下快速Web开发(一)——纠结的里程
    .net MVC 框架调试过程中,产生大量的临时文件
    认识NHitenate
    如何循序渐进向.Net架构师发展[转载]
    核桃煲鸡汤
    .NET获取客户端信息 (C#)
  • 原文地址:https://www.cnblogs.com/fuyingke/p/189869.html
Copyright © 2020-2023  润新知