Using methods from a DLL

Asked

Viewed 5,356 times

9

I am in need of using methods from a DLL that was developed by third party. I only have the file ". DLL".

DLL documentation is scarce... there is an example of the method execution 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 obtain the following data from 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 me that there is the function DllGetClassObject which should be used to obtain the class instance, but I have not found examples of how to do this.

Any suggestions ?

2 answers

4


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

    regsvr32 "caminho para a dll"

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

Using the Wizard provided by the IDE

Which is located in Component->Import Component....

  • In it you must select Import a Type Library
  • Search the desired dll in the list
  • In the next screen you can select the location where the file with the definitions will be created and also if components will be created to encapsulate the dll classes.
  • In the last step you can select if
    • only a Unit will be created with the definitions
    • whether it will be installed in an existing package
    • in a new package
    • or whether it will be added to the project

Only the 2nd and 3rd add 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 TNomedaClasse

Using the function CreateObject

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

    I recommend always using the first option, because it generates a stub. It’s much easier to work with stub than with the Olevariant that Createobject creates.

0

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

First declare the type of function q vc you want to call

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

Then in your activation location you load the dll, map the method and run 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;

Case of creating 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;

Next create the class that maps

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 are apparently string and integer, but I kept the same from your example for you to validate.

  • 1

    Felipe, The problem is that it is not possible to obtain the method directly Gerar_MidiaTEDDat using GetProcAddress, because this method is not exported by the DLL. DllGetClassObject... from it I would get the class and from it I would have to seek the method Gerar_MidiaTEDDat.

  • 1

    Desulpe @Vinicius, I had misunderstood. These links may help you with this: [http://stackoverflow.com/questions/12954973/putting-classes-in-a-dll] or [http://talkdelphi.blogspot.com.br/2009/03/how-to-import-object-from-dll.html]

  • 1

    @Felipecaputo, the segndo link is broken displaying the message "Sorry, the page you Were Looking for in this blog does not exist. "

  • @Stribus he had gotten a ] at the end, thanks for the warning. The following is now correct: http://talkdelphi.blogspot.com.br/2009/03/how-to-import-object-from-dll.html

Browser other questions tagged

You are not signed in. Login or sign up in order to post.