Login
`
Templates, Tools and Utilities
|
||
Add a comment to an Icetips ArticlePlease add your comments to this article.
Please note that you must provide both a name and a valid email address in order
for us to publish your comment. Comments are moderated and are not visible until they have been approved. Spam is never approved!
Back to article list Search Articles Add Comment Printer friendly Direct link Windows API: Basic C++ and Clarion integration 2003-04-04 -- Dan Gorrell Hello all,
A number of you have contacted me and asked how to make C++ dlls which can
talk to Clarion. I intended to post the solution on a webpage that I'm
putting together, however it will still be some time before that's ready to
go so I thought I'd just post it here. This is one way of interfacing with
C++ objects from Clarion. It is by no means the only way, or even the best
way, but it does work -- and it's pretty simple if you've had any experience
in prototyping Windows API calls. If anyone is interested in posting
alternative solutions, I'd love to see them!
The C++ stuff was compiled into a standard Win32 DLL using Visual Studio
.NET edition, and it works perfectly. I'm not interacting directly with the
C++ objects in the Clarion code... instead I've created a set of very simple
C++ procedures that talk to the objects for me. (Would you call this
"unwrapping"?) I'm not sure if there's a way to get around this or not.
Everything I've read so far indicates that Clarion cannot directly
instantiate C++ objects... but then neither can VB, Delphi, or anything else
except C++. Apparently each language handles OOP in a different way, which
is pretty much ignorant of the DLL standard. (This is what I've read... I
could be wrong.) So prior to COM, there was no real "standard" for handling
objects across different compilers.
Please bear in mind that my C++ skills are rudimentary. Also, this example
is intentionally VERY simple and is quite useless. (It adds 69 to any number
you pass to it) It does, however, demonstrate the basic things you would
want to do with C++ objects. I can instantiate and dispose of them, I can
"put" data to their properties, "get" data back, and run any methods that I
need. (Each of these is demonstrated seperately.)
If you want to test this solution, put the .h, .cpp, & .def files into a
Win32 DLL project in C++ and compile the DLL. Clarion's LibMaker.exe will
see all of the procedures that you list in the .def file and will build an
appropriate .lib for you, which you can link into your Clarion project, just
as you would with any DLL.
// Spiffy.h
typedef void* ADHandle;
ADHandle newadder();
void deleteadder(ADHandle myHandle);
void sbnadder(ADHandle myHandle,long myNum);
void daadder(ADHandle myHandle);
long gradder(ADHandle myHandle);
class adder
{
long begnum;
long endnum;
public:
void setBegNum(long myNum);
void doAddition();
long getResult();
adder(); //Constructor
~adder(); //Destructor
};
// Spiffy.cpp
#include "Spiffy.h"
//Functions to interface with Adder Class
ADHandle newadder()
{
return (ADHandle) new adder;
};
void deleteadder(ADHandle myHandle)
{
delete (adder*)myHandle;
};
void sbnadder(ADHandle myHandle,long myNum)
{
adder *A = (adder*)myHandle;
A->setBegNum(myNum);
};
void daadder(ADHandle myHandle)
{
adder *A = (adder*)myHandle;
A->doAddition();
};
long gradder(ADHandle myHandle)
{
adder *A = (adder*)myHandle;
return A->getResult();
};
//Adder Class Implementation
adder::adder(){
};
adder::~adder(){
};
VOID adder::setBegNum(LONG myNum){
begnum = myNum;
};
VOID adder::doAddition(){
endnum = (begnum + 69);
};
LONG adder::getResult(){
return endnum;
};
// Spiffy.def
LIBRARY Spiffy
EXPORTS
newadder
deleteadder
sbnadder
daadder
gradder
That's it, so far as C++ is concerned. The first parameter that each of the
C++ procedures takes is a pointer to an adder object - except for newadder()
which returns one. Put those in your Visual Studio project, build a DLL,
and use libmaker.exe to create a .LIB file for you. Then, add the LIB to
"Library, object, and resource files" in your Clarion project and put the
following in your global map. (Assuming you named the .LIB Spiffy.LIB)
MODULE('Spiffy.LIB')
newadder(),LONG,RAW,PASCAL
deleteadder(LONG),RAW,PASCAL
sbnadder(LONG,LONG),RAW,PASCAL
daadder(LONG),RAW,PASCAL
gradder(LONG),LONG,RAW,PASCAL
END
Now, create a basic window with in input field, and output field, and a
button marked "add 69 using c++ object". Add the following variables to the
procedure,
myCPClass LONG
begnum LONG
endnum LONG
Link begnum to the input field, endnum to the output field, and then put the
following code in the accepted embed of your button.
!Instantiate a new "adder" class
myCPClass = newadder()
!Set the beginning number property
sbnadder(myCPClass,begnum)
!Tell the class to perform the addition
daadder(myCPClass)
!Get the resulting data from the class
endnum = gradder(myCPClass)
!Dispose of the class
deleteadder(myCPClass)
DISPLAY
The latent-power of C++ can now be harnessed by your Clarion programs to add
69 to any number you should choose. ;) If you wanted to get fancy, you
could "re-wrap" the procedures into an object on the Clarion side so that
they still looked like methods, but whether you do or don't you are
interacting with C++ objects and it's a piece of cake.
Best,
Dan Gorrell
Today is November 21, 2024, 7:00 am This article has been viewed 35332 times. Google search has resulted in 491 hits on this article since January 25, 2004.
|
|