Dll C # in Delphi 7

6

I need to generate a "ini" file in the "C: \ Windows \ Temp \ USB.ini" folder containing printer information installed for another pre- historic consume. I created the following (gambiarra) dll in C #:

    [ClassInterface(ClassInterfaceType.None),     
     Guid("C92C5DDA-7766-4CBC-8141-6817DDE97B6F")]    
public class Solucoes 
{
    public Solucoes()
    {
    }

    public void getPrinters()
    {
        string line = "";
        string passaDireto = "";

        FileIOPermission f2 = new FileIOPermission(FileIOPermissionAccess.AllAccess, @"C:\Windows\Temp\");

        if (File.Exists(@"C:\Windows\Temp\USB.ini"))
        {
            System.IO.StreamReader file = new System.IO.StreamReader(@"C:\Windows\Temp\USB.ini");
            while ((line = file.ReadLine()) != null)
            {
                if ((line.ToUpper().Contains("PASSADIRETO="))) passaDireto = line;
            }
            file.Close();
            File.Delete(@"C:\Windows\Temp\USB.ini");
        }
        File.Create(@"C:\Windows\Temp\USB.ini").Close();
        TextWriter arquivo = System.IO.File.AppendText(@"C:\Windows\Temp\USB.ini");
        arquivo.WriteLine("[Porta]");

        ManagementObjectSearcher printers = new ManagementObjectSearcher("SELECT * from Win32_Printer");
        foreach (ManagementObject item in printers.Get())
        {
            string print = "", port = "";
            if ((bool)item.GetPropertyValue("Shared"))
            {
                print = (string)item.GetPropertyValue("ShareName");
            }
            else print = (string)item.GetPropertyValue("Name");
            port = (string)item.GetPropertyValue("PortName");

            if (print.Length > 44) arquivo.WriteLine(string.Concat(print.Substring(0, 43), "=", port));
            else arquivo.WriteLine(string.Concat(print, "=", port));
        }

        if (!string.IsNullOrEmpty(passaDireto))
        {
            arquivo.WriteLine("[Opcoes]");
            arquivo.WriteLine(passaDireto);
        }
        arquivo.Close();                            
    }
}

I left the dll as COM visible and registered as well. To register I used regasm.exe SolucoesClassLibrary.dll /tlb /codebase

I created the unit of it in Delphi 7 and tried to make the call:

var
    Impressora: ISolucoes;

begin
    Impressora.getPrinters();
end;

When I run it it throws this exception well at the time I call the dll routine done in C #. Exception EAccessViolation in module USB.exe at 0006B3BA. Access violation at address 0046B3BA in module 'USB.exe'. Read of address 000000 00.

Does anyone know how to help me?

    
asked by anonymous 05.03.2014 / 15:17

2 answers

5

I use a "cake recipe" that always works for me.

Follows:

Create an interface:

namespace EscreveINI
{
    using System.Runtime.InteropServices;

    [InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("80911B7A-608D-4A54-B51B-CF09E512CAD4")]
    public interface IEscreveIniClass
    {
        void Escrever();
    }
}

And a class:

namespace EscreveINI
{
    using System.IO;
    using System.Runtime.InteropServices;

    [ClassInterface(ClassInterfaceType.None), Guid("C77906F8-59A9-4187-B818-2F6CABF1A2AF")]
    public class EscreveIniClass : IEscreveIniClass
    {
        public void Escrever()
        {
            File.Create(@"C:\Windows\Temp\USB.ini").Close();
        }
    }
}

Mark in the ClassLibrary Assembly Information the "Make COM-Visible assembly"

And in the build check the "Register for COM interop" option

After this, copy the DLL to the desired location along with the tlb file and run the following command:

set path="%path%";C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319
regasm /tlb:EscreveINI.tlb EscreveINI.dll /codebase

Then in Delphi go to Project, Import Type Library and search for the tlb and click Create Unit.

Then just use it like this:

procedure TForm1.Button1Click(Sender: TObject);
var
  lEscreveArquivo: IEscreveIniClass;
begin
  lEscreveArquivo := CoEscreveIniClass.Create();
  lEscreveArquivo.Escrever;
end;
    
06.03.2014 / 20:37
0

Once I needed to work with Delphi 5 XML I gave a C # dll and created a unit in Delphi to serve as the interface.

I'll give you a paste of the code, it's kind of great, and it has many functions to call the metadata that was created in my .Net class

I basically load the dll and keep it in memory in a static class. You can ignore 90% of the code that is to manipulate an array (of arrays) of strings and "simulate" a pseudo xml.

Take a look at the part where you have ProgID of the dll!

//****************************************************************************//
//***  Unit para servir de interface para                                  ***//
//***  a DLL útil implementada em .Net                                     ***//
//***                                                                      ***//
//***  28/04/2010                                                          ***//
//***  by Jean Charles Bulinckx                                            ***//
//****************************************************************************//
unit uUtil;

interface
uses
  ComObj, ComCtrls;

type
  // XML serializado retornado pela DLL
  tArrayNos = Array of Array of String;

  // estrutura que representa o XML DEsSerializado pelo Delphi
  tNo = class
     nome:String;
     valor:String;
     id:String;
     idPai:String;
     filhos:Array of tNo;
  end;

  tArrNo = Array of tNo;

  tUtil = class
  private
     // Mantém a DLL em memória
     DLL: Variant;
  public
     // Metódos que chamam a dll
     function Importar(servico, arquivo, login, senha: String):String;
     function LeXML(arquivo:String):tArrayNos;
     function Criptografar(dados:String; descriptar:Boolean):String;
     // Métodos para ler/montar árvore
     function EncontrarFilho(nome: String; raiz: tNo):tNo;
     function EncontrarFilhos(nome: String; raiz: tNo):tArrNo;
     function EncontrarRaiz(id: String; xml: tArrayNos):tNo;
     function MontarFilhos(raiz:tNo; xml: tArrayNos):tNo;
     function DeSerializarArvore(xml: tArrayNos):tNo;
     function ReSerializarArvore(no: tNo):tArrayNos;
  published
     Constructor Inicializar();
  end;

  // ProgId da DLL
Const
  NomeClasse:String = 'Xpto.Util';

implementation

function InstanciaClasse(strClasse: String):Variant;
begin
   result := CreateOleObject(strClasse);
end;

// Função que retorna uma instância da classe
Constructor tUtil.Inicializar();
begin
   inherited;
   self.DLL := InstanciaClasse(NomeClasse);
end;    

// ********************************
// *** Funções que chamam a DLL ***
// ********************************
function tUtil.Importar(servico, arquivo, login, senha: String):String;
begin
   result := self.DLL.ChamarWSB(servico,arquivo, login, senha, false);
end;

function tUtil.LeXML(arquivo:String):tArrayNos;
begin
   result := self.DLL.LerXML(arquivo);
end;

function tUtil.Criptografar(dados:String; descriptar:Boolean):String;
begin
   result := self.DLL.Criptografar(dados, descriptar);
end;
// ********************************
// *** Funções que chamam a DLL ***
// ********************************

// *****************************************************
// *** Funções para "ler" a árvore de nós (tags) xml ***
// *****************************************************

// Encontra o filho pelo nome
function tUtil.EncontrarFilho(nome: String; raiz: tNo):tNo;
var no:tNo;
 i:integer;
begin
   no := tNo.Create();
   for i := 0 to Length(raiz.filhos) - 1
   do begin
      if (raiz.filhos[i].nome = nome)
      then begin
         no := raiz.filhos[i];
      end;
   end;
   result := no;
end;

// Encontrar uma coleção de filhos pelo nome
function tUtil.EncontrarFilhos(nome: String; raiz: tNo):tArrNo;
var arrNo:tArrNo;
 i,l:integer;
begin
   for i := 0 to Length(raiz.filhos) - 1
   do begin
      if (raiz.filhos[i].nome = nome)
      then begin
         l := Length(arrNo);
         SetLength(arrNo,l+1);
         arrNo[l] := raiz.filhos[i];
      end;
   end;
   result := arrNo;
end;

// Acha quem é a raiz (quem não tem pai)
function tUtil.EncontrarRaiz(id: String; xml: tArrayNos):tNo;
var no:tNo;
 i:integer;
 id2:String;
begin
   no := tNo.Create();
   for i := 0 to Length(xml) - 1
   do begin
      id2 := xml[i,3];// id do pai
      if (id=id2)
      then begin
         no.nome := xml[i,0];
         no.valor := xml[i,1];
         no.id := xml[i,2];
         no.idPai := xml[i,3];
      end;
   end;
   result := no;
end;

// Monta um ramo de árvore recursivamente
function tUtil.MontarFilhos(raiz:tNo; xml: tArrayNos):tNo;
var
 no:tNo;
 i,l:integer;
 idPai:String;
begin
   for i := 0 to Length(xml) - 1
   do begin
      idPai := xml[i,3];//id do pai
      if (idPai = raiz.id)
      then begin
         no := tNo.Create();
         no.nome := xml[i,0];
         no.valor := xml[i,1];
         no.id := xml[i,2];
         no.idPai := xml[i,3];
         no := MontarFilhos(no,xml);
         l:=Length(raiz.filhos);
         SetLength(raiz.filhos,l+1);
         raiz.filhos[l]:=no;
      end;
   end;
   result := raiz;
end;

// Remonta numa estrutura em memória o .XML serializado pela DLL
function tUtil.DeSerializarArvore(xml: tArrayNos):tNo;
var raiz:tNo;
begin
   raiz := EncontrarRaiz('00000000-0000-0000-0000-000000000000', xml);

   // Monta os filhos recursivamente
   raiz := MontarFilhos(raiz, xml);

   // Retorna a árvore em memória
   result := raiz;
end;

// ReSerializa uma árvore para um Array of Arrays of String
function tUtil.ReSerializarArvore(no: tNo):tArrayNos;
var xml,ramo:tArrayNos;
i,j,lenPai,lenFilho,lenNeto:integer;
begin
   ramo := nil;
   if no <> nil
   then begin
      SetLength(xml,1,4);
      xml[0,0] := no.nome;
      xml[0,1] := no.valor;
      xml[0,2] := no.id;
      xml[0,3] := no.idPai;
      // recursão
      lenFilho := Length(no.Filhos);
      for i := 0 to lenFilho - 1
      do begin
         ramo := ReSerializarArvore(no.Filhos[i]);
         lenNeto := Length(ramo);
         lenPai := Length(xml);
         SetLength(xml,lenPai+lenNeto,4);
         for j := 0 to lenNeto - 1
         do begin
            xml[lenPai + j] := ramo[j];
         end
      end
   end;
   result := xml;
end;
// *****************************************************
// *** Funções para "ler" a árvore de nós (tags) xml ***
// *****************************************************
end.
    
05.03.2014 / 15:35