Board index » cppbuilder » Using VCL in a DLL

Using VCL in a DLL


2005-12-02 04:19:52 AM
cppbuilder56
I apologize if what I need is "obvious" but every time I search for this
anywhere, I find only references about using already existing DLL's in a
new Builder project and not the other way around. What I'm trying to do
is build a utility DLL for use with a legacy Visual FoxPro 6 application
that the client doesn't want to upgrade right now so as to add a few
stop-gap features. Which means I'm trying to do this with minimal effort
on my part.
When I used the BCB5 Pro DLL Wizard (Selecting C++ Source, Use VCL and
not VC++ Style) I basically ended up with this (removed some comments
and whitespace)...
//--------------------------------------------------------------
#include <vcl.h>
#include <windows.h>
#include "Unit2.h"
#pragma hdrstop
#pragma argsused
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID
lpvReserved)
{ return 1; }
//--------------------------------------------------------------
I then added a new form to the project and dropped some non-visual
components on it (NMHTTP and NMSMTP from the FastNet tab). Then I added
an include for the unit2.h to the unit1.cpp
Using this version of the function I can get back what I put in.
extern "C" _declspec(dllexport) char* getweb(char* Url)
{
return Url;
}
Using this version I get an error from FoxPro when I call the function
extern "C" _declspec(dllexport) char* getweb(char* Url)
{
Form2->NMHTTP1->Get(Url);
return Form2->NMHTTP1->Body.c_str();
}
I /assume/ that this is because I'm not instantiating the form that
contains the non-visual component. Not that I want to instantiate the
form for this function (I will for other functions which is a different
issue...)
Any pointers on how I can get this done would be GREATLY appreciated!
Thanks in advance!
Matt Neimeyer
 
 

Re:Using VCL in a DLL

"Matt Neimeyer" < XXXX@XXXXX.COM >wrote in message
Quote
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID
lpvReserved)
Given the settings you specified, you should have gotten a DllEntryPoint()
function, not DllMain().
Quote
extern "C" _declspec(dllexport) char* getweb(char* Url)
You should be using the __stdcall calling convention for all exported
functions, ie:
extern "C" _declspec(dllexport) char* __stdcall getweb(char* Url)
Quote
Using this version I get an error from FoxPro when I call the function
There are two problems with that code:
1) You are likely not instantiating Form2 before accessing it.
2) You are calling c_str() on an AnsiString that will go out of scope
immediately, thus you are returning a pointer that is pointing to invalid
memory.
Gambit
 

Re:Using VCL in a DLL

"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote
There are two problems with that code:

1) You are likely not instantiating Form2 before accessing it.

2) You are calling c_str() on an AnsiString that will go out of scope
immediately, thus you are returning a pointer that is pointing to invalid
memory.
Also, you should not be returning a char* anyway, since FoxPro won't know
how the handle the memory properly. It would be better if the DLL accepts a
memory block that FoxPro itself allocates and then simply fill in the
memory. Then FoxPro can free the memory when it is done with it.
Also, make sure that your DLL's exported functions are using adequate error
handling. FoxPro won't be able to handle VCL exceptions and such.
For example:
#include <memory>
extern "C" _declspec(dllexport) int __stdcall getweb(char* Url, char*
buffer, int size)
{
try
{
std::auto_ptr<TForm2>Form(new TForm2(NULL));
Form->NMHTTP1->Get(Url);
strncpy(buffer, Form->NMHTTP1->Body.c_str(), size);
return 1;
}
catch(const Exception &)
{
return 0;
}
}
Then you can do the following in FoxPro:
DECLARE INTEGER getweb IN my.dll DllGetWeb STRING, STRING, INTEGER
lcBuffer = REPLICATE(" ", 1024)
lnReturned = DllGetWeb(lcBuffer, LEN(lcBuffer))
IF lnReturned>0
...
Gambit
 

{smallsort}