Using methods from a DLL

9

I'm having to use methods from a DLL that was developed by third parties. I have only the ".DLL" file.

The DLL documentation is scarce ... there is an example of executing the method I need in VB

Private Const TamMsgErro As Long = 1000
Dim oTED As New clsGeraMidiaTed
Dim lResult As Long
Dim sMsgErroTED As String * TamMsgErro

'Chamada no Projeto
Set oTED = CreateObject("PRGerarMidiaTED.clsGeraMidiaTED")

lResult = oTED.Gerar_MidiaTEDDat(sListaArqEntrada, _
                                 sArqSaida, _
                                 sTipoDoc, _
                                 sMsgErroTED, _
                                 TamMsgErro)
If lResult <> 0 Then
  MsgBox sMsgErroTED
Else
  MsgBox "Arquivo [" & sArqSaida & "] gerado com sucesso !"
End If 

I need to develop in Delphi, and the problem I'm having is that the "Gerar_MidiaTEDDat" method is not exported by the DLL. This method is in a class in the DLL.

Using PE Explorer I was able to get the following data from the DLL:

//PRGerarMidiaTED
//Version: 1.0
PRGerarMidiaTED;
GUID = {DA0AA6B5-73AC-41B7-BBA5-DF03D6367C63};

Dispatch _clsGeraMidiaTed;
  GUID = {EEF15A9A-5C3E-45A0-B876-4E10381C7D2E};
  function QueryInterface(riid: ^GUID; out ppvObj: ^^VOID); stdcall;
  function AddRef: UI4; stdcall;
  function Release: UI4; stdcall;
  function GetTypeInfoCount(out pctinfo: ^UINT); stdcall;
  function GetTypeInfo(itinfo: UINT; lcid: UI4; out pptinfo: ^^VOID); stdcall;
  function GetIDsOfNames(riid: ^GUID; rgszNames: ^^I1; cNames: UINT; lcid: UI4; out     rgdispid: ^I4); stdcall;
  function Invoke(dispidMember: I4; riid: ^GUID; lcid: UI4; wFlags: UI2; pdispparams: ^DISPPARAMS; out pvarResult: ^Variant; out pexcepinfo: ^EXCEPINFO; out puArgErr: ^UINT); stdcall;
  function Gerar_MidiaTEDDat(sListaArqEntrada: BSTR; sArqSaida: BSTR; sTipoDoc: BSTR; out sMsgErro: ^BSTR; lTamMsgErro: I4): I4; stdcall;
  function Verificar_VersaoGerarMidiaTED(out sVersaoGerarMidia: ^BSTR; out sMsgErro: ^BSTR; lTamMsgErro: I4): Bool; stdcall;

CoClass clsGeraMidiaTed;
GUID = {664BF784-A2D6-477B-8022-1F32FDD90FD6};

In the exported functions, PE Explorer indicated that there is a DllGetClassObject function that should be used to get the class instance, but I have not found any examples of how to do this.

Any suggestions?

    
asked by anonymous 20.02.2014 / 19:49

2 answers

3

This dll should be a type library ( Type Library ). To use it first you must register it with the windows% utility%.

    regsvr32 "caminho para a dll"

After this you have two alternatives to use it in Delphi.

Using the Wizard provided by the IDE

That is located in regsvr32.exe .

  • In it you should select Component->Import Component...
  • Find the desired dll in the list
  • In the next screen you can select the location where the file with the settings will be created and also if components will be created to encapsulate the dll classes.
  • In the last step you can select
    • only one unit will be created with the definitions
    • Whether it will be installed in an existing package
    • in a new package
    • or will be added to the project

Only the 2nd and 3rd adds the component to the palette.

After that you should only add the unit uses of the desired file and create the class as it creates any other component.

The class names will be something like Import a Type Library

Using the TNomedaClasse

Similar to the example you posted.

const
  TamMsgErro : Integer= 1000
var
 oTED : Variant;
 lResult : Integer;
 sMsgErroTED : String;
 lResult : Integer;
begin

'Chamada no Projeto
oTED := CreateObject("PRGerarMidiaTED.clsGeraMidiaTED");

lResult = oTED.Gerar_MidiaTEDDat(.....);
    
21.02.2014 / 17:45
0

You can create a class of your own to map the dll or load it dynamically

First declare the type of function you want to call

type
    TTipoFuncao = function (sListaArqEntrada: BSTR; sArqSaida: BSTR; 
        sTipoDoc: BSTR; out sMsgErro: ^BSTR; lTamMsgErro: I4): I4;

Then in your activation site you load the dll, map the method and execute it

var
    Dll :THandle ; 
    funcao: TTipoFuncao;
    Retorno: I4;
begin 
    Dll := LoadLibrary(NomeDll);
    if DLL = 0 then
        //MostraMsgErro
    else
    begin 
        @funcao := GetProcAddress(Dll,´Gerar_MidiaTEDDat´);
        if @funcao nil then
            Retorno := funcao( ParâmetroDesejado );
        FreeLibrary(Dll);
    end;

    //Use o retorno :D
end;

If you create the class

First you should map the type of the function, as in the previous example

type
    TTipoFuncao = function (sListaArqEntrada: BSTR; sArqSaida: BSTR; 
      sTipoDoc: BSTR; out sMsgErro: ^BSTR; lTamMsgErro: I4): I4;

Then create the mapping class

type
  TMidiaTeD = class(TObject)
  private
    FTedMidia: TTipoFuncao;
    FDLL: THandle;
  public
    constructor Create;
    destructor Destroy; override;

    function Gerar_MidiaTEDDat(sListaArqEntrada: BSTR; sArqSaida: BSTR; sTipoDoc: BSTR; out sMsgErro: ^BSTR; lTamMsgErro: I4): I4;
  end;

implementation

constructor TMidiaTeD.Create;
begin
  Dll := LoadLibrary(NomeDll);
  if DLL = 0 then
      //MostraMsgErro

  @FTedMidia := GetProcAddress(Dll,´Gerar_MidiaTEDDat´);
end;

destructor TMidiaTeD.Destroy;
begin
  FreeLibrary(Dll);
  inherited;
end;

function TMidiaTeD.Gerar_MidiaTEDDat(sListaArqEntrada: BSTR; sArqSaida: BSTR; sTipoDoc: BSTR; out sMsgErro: ^BSTR; lTamMsgErro: I4): I4;
begin
  Result := FTedMidia(sListaArqEntrada, sArqSaida, sTipoDoc, sMsgErro, lTamMsgErro);
end;

PS: The types seem to be string and integer, but I kept the same as your example to validate.

    
20.02.2014 / 20:14