Cretar DLL

Cretar DLL

Postby lailton.webmaster » Mon Mar 16, 2009 12:12 am

Hi,

in the website xharbour.com i found it
How to create a DLL
The "how do I create code which is accessible in other applications" question is asked pretty often when you browse newsgroups, faq's and forums. This is no different with xHarbour. In this article we'll explain how to create a DLL which holds code that you can easily use in other applications and thus creating less work for the time-driven developers out there.

First things first. How do we make our xHarbour code available for applications written in for example Visual Basic? The answer is easy: by posing our code as an OLE object. OLE (Object Linking and Embedding) is a technology that allows embedding and linking to other objects. The nice thing about OLE is that you can use it to achieve something (execute a piece of xHarbour code) in an environment which is not able to do it on it's own.

Ok, but how do we do this in the real world?

With the OleServer.lib from xHarbour.com, you basically just add 5 lines of code to the top of your program:

#pragma BEGINDUMP
#define CLS_Name "MyOleServer"
#define CLD_ID "{D385CFF0-01BE-42ea-8272-336CDE8ABA5A}"
#include "OleServer.h"
#pragma ENDDUMP

The GUID used in this example can be randomly generated by Microsoft's GuidGen tool to generate GUID's. It's also possible to generate GUID's via the website http://www.guidgen.com/. By adding this code, your functions, classes, methods and properties will be available as OLE methods. Below is a complete sample demonstrating this working method.

#pragma BEGINDUMP
#define CLS_Name "SampleOleServer"
#define CLS_ID "{D385CFF0-01BE-42ea-8272-336CDE8ABA5A}"
#include "OleServer.h"
#pragma ENDDUMP

#include "hbclass.ch"

/*
OPTIONAL FUNCTION - if it exists, it will set the Server to a specific Object Instance or you may return the same Object previously created if you want all OLE intanaces to refer to just one Object.
*/
FUNCTION CreateInstance
LOCAL oOleServer := MyOleServer()

// Transfer all errors to the Client
ErrorBlock( {|e| Break(e) } )

/*
If you return an Object, it becomes *the* Server, otherwise the non
ststic PROCEDURES and FUNCTIONS
of this module will be the exported Methods, and PUBLICS MEMVARS will
be the exported Properties.
*/
RETURN oOleServer

CLASS MyOleServer
PUBLIC:

DATA MyProperty

METHOD MyMethod( x )
ENDCLASS

METHOD MyMethod( x ) CLASS MyOleServer
::MyProperty := x

IF HB_IsByRef( @x )
SWITCH ValType( x )
CASE 'C'
x := "Modified!"
EXIT

CASE 'D'
CASE 'N'
x++
EXIT

CASE 'A'
x := { "Modified!" }
EXIT
END
ENDIF

RETURN Self
And a sample to test our OleServer:

PROCEDURE Main()

LOCAL oServer, xByRef

oServer := CreateObject( "SampleOleServer" )

oServer:MyMethod( "test" )
? ValToPrg( oServer:MyProperty )
RETURN
Please note that you should always distribute the xHBDll.dll (or xharbour.dll if using the .org distributions) together with your own .dll and they must be located in the same directory.

Also, your installer should register your DLL using the following command: RegSvr32 <YourPrgOleServer.dll>

And building the DLL can be done with: xBuild YourPrgOleServer.dll YourPrgOleServer.prg or by using the xBuild wizard with the "DLL" option checked.




So i´m trying use it..


dll.prg

Code: Select all  Expand view
#pragma BEGINDUMP
#define CLS_Name "SampleOleServer"
#define CLS_ID "{D385CFF0-01BE-42ea-8272-336CDE8ABA5A}"
#include "OleServer.h"
#pragma ENDDUMP

#include "hbclass.ch"

/*
OPTIONAL FUNCTION - if it exists, it will set the Server to a specific Object Instance or you may return the same Object previously created if you want all OLE intanaces to refer to just one Object.
*/

FUNCTION CreateInstance
LOCAL oOleServer := MyOleServer()

// Transfer all errors to the Client
ErrorBlock( {|e| Break(e) } )

/*
If you return an Object, it becomes *the* Server, otherwise the non
ststic PROCEDURES and FUNCTIONS
of this module will be the exported Methods, and PUBLICS MEMVARS will
be the exported Properties.
*/

RETURN oOleServer

CLASS MyOleServer
PUBLIC:

DATA MyProperty

METHOD MyMethod( x )
ENDCLASS

METHOD MyMethod( x ) CLASS MyOleServer
::MyProperty := x

IF HB_IsByRef( @x )
SWITCH ValType( x )
CASE 'C'
x := "Modified!"
EXIT

CASE 'D'
CASE 'N'
x++
EXIT

CASE 'A'
x := { "Modified!" }
EXIT
END
ENDIF

RETURN Self


and..
My progman menu.prg

Code: Select all  Expand view

PROCEDURE Main()

LOCAL oServer, xByRef

oServer := CreateObject( "SampleOleServer" )

oServer:MyMethod( "test" )
? ValToPrg( oServer:MyProperty )
RETURN
 



while i will compile dll.prg show me that dont have oleserver.H
i´m searching for this file more don´t have in my computer...

it´s possible create with fivewin or need something ?

thanks so much.
lailton.webmaster
 
Posts: 603
Joined: Sun May 04, 2008 8:44 pm

Re: Cretar DLL

Postby Antonio Linares » Thu Mar 19, 2009 10:46 am

Lailton,

We don't recomment to use a feature that it is not supported in the free and open source versions of Harbour/xHarbour.

You can always build a DLL that can be accessed from any EXE. This is fully documented and full source code is available.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41328
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Cretar DLL

Postby lailton.webmaster » Thu Mar 19, 2009 3:30 pm

Antonio,

Code: Select all  Expand view
You can always build a DLL that can be accessed from any EXE. This is fully documented and full source code is available.


Where i found ?
Can u show me a exemple for version free xharbour ?


gracias maestro
lailton.webmaster
 
Posts: 603
Joined: Sun May 04, 2008 8:44 pm

Re: Cretar DLL

Postby Antonio Linares » Mon Mar 23, 2009 8:19 am

Lailton,

First you have to decide what kind of DLL you need. Please read this explanation from the Harbour docs:
Windows 32-bit DLLs with Harbour code
=====================================

Programs created with Clipper or Harbour are traditionally a
monolithic EXE containing all executable code. This includes
the Virtual Machine (VM) and the RunTime Library (RTL) as well as
your own code. Running under Windows with Harbour, you
can now also create and use Windows DLLs that contain PRG code.

Harbour supports Windows DLLs in 3 ways.

1) Self-contained DLLs containing functions from any platform.
(These are not what we call a "harbour.dll", although they may
be named that. The DLL entry points are different.)
These have the VM/RTL inside them and can be used by any other
Windows program. You can create a .lib for static linking,
or use GetProcAddress as in any standard Windows DLL.
Calling Harbour/Prg functions directly is limited to
those that take no parameters unless you include C functions
in the DLL that take parameters and then call the PRG-level
code.

To do static linking, do this to create the .lib:
implib harbour.lib harbour.dll
For the Borland C platform, use that library and import32.lib
and cw32.lib from Borland, and you are ready to go.

See contrib\delphi\hbdll for an example of a Delphi program that can
use all of Harbour's functionality by accessing a self-contained DLL.
bld_sdll.bat is used there to create the DLL.


2) PCode EXEs using a Harbour.dll

A Harbour.dll is designed to be called from a Harbour app.
A pcode EXE is a small Harbour executable that does not contain the
VM/RTL. To execute its functions, it must load and access a
Harbour.dll.
If you want dynamic linking, then use this to execute a Harbour
dynamically loaded pcode DLL function or procedure:
HB_DllDo( <cFuncName> [,<params...>] ) --> [<uResult>]

This lets you have all your common code in a DLL, and have lots
of small EXEs that use it. Realize however that, even though this
may be a nice way to manage your code, each EXE may
load its own image of the Harbour.dll into memory at runtime.
In terms of Windows memory, there may not be a benefit to using pcode
EXEs over monolithic EXEs. But it may be a worthwhile maintenance
benefit to have lots of replaceable small exes.

3) PCode DLLs used from traditional EXEs
A pcode DLL does not contain the VM/RTL.
It is a library of Harbour-compiled PRG code that uses the VM/RTL
of the EXE that calls it. This has the benefit of having
replaceable modules in DLLs that don't necessarily require updating
your EXE.


The following is clipped from a msg by Antonio Linares to the Harbour
developer list explaining some of the details:

Please notice that there are three different Windows DLL entry points:
+ source/vm/
* maindll.c Windows self-contained DLL entry point
* maindllh.c Windows Harbour DLL entry point (harbour.dll)
* maindllp.c Windows pcode DLL entry point and VM/RTL routing functions

> * maindll.c Windows self-contained DLL entry point
To produce Harbour code, as DLLs, that may be used
from other programming languages applications (as VB,
Delphi, C++, etc...)

> * maindllh.c Windows Harbour DLL entry point (harbour.dll)
To produce Harbour.dll, to be just used from small pcode Harbour EXEs

> * maindllp.c Windows pcode DLL entry point and VM/RTL routing
To produce small pcode DLLs, to be used just from Harbour EXE apps.
maindllp.c is the entry point for the Harbour pcode DLLs. pcode DLLs
are quite small DLLs, that just contain pcode and/or C (using extend
api) functions.

mainwin.c is the entry point for Windows EXEs, not for DLLs.

You may use maindll.c, maindllh.c or maindllp.c based on
your needs.

If you are looking to build a Harbour.dll, then you must use
maindllh.c
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41328
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: nageswaragunupudi and 16 guests