Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

C++-DLL and Delphi 3

Posted on 1998-11-09
9
Medium Priority
?
500 Views
Last Modified: 2008-02-01
Hello,

I've written a DLL in Borland C++ 5.0.  One of the functions is a simple
concatenation function :

char* __stdcall _export StringTest(char* Str1, char* Str2)
{
   char* tmp;

   int l1 = strlen(Str1);
   int l2 = strlen(Str2);

   tmp = (char*) malloc(l1+l2+1);
   strcpy(tmp, Str1);
   strcat(tmp,Str2);
   return tmp;
}

This function works fine, but it has a memory leak : the memory
allocated for tmp is not released.

This function is called from a Delphi 3 application.  Can anyone tell me
how I can release the allocated memory, prefarably from the Delphi
application ?
I've tried freeing the memory just before the return instruction, but it
doesn't work.

Thanks in advance,

Johan

0
Comment
Question by:ppr
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 2
  • +1
9 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 1177318
No way. You cannot release memory in a Delphi app that was allocated by a C++ DLL - they use different heaps for this. The only reliable way is to pass in a buffer allocated by the application, e.g.


char* export WINAPI StringTest(char* Str1, char* Str2, char *res)
{
   char* tmp
   strcpy(res, Str1);
   strcat(res,Str2);
   return res;
}

(NOTE the WINAPI modifier!)
0
 
LVL 22

Expert Comment

by:nietod
ID: 1177319
Even if were possible (which it pretty much isn't ), these sort of designs where a procedure allocates memory for a return value and expects the caller to delete it, are notoriously dangerious.  You would ussually get a memory leak anyways because the calling code would probably forget to do the delete anyways, at least in some cases.
0
 

Author Comment

by:ppr
ID: 1177320
Thanks to AndersWP I was able to solve it the way I like it.  In the DLL, I use the GlobalAlloc API function and in the application I use the GlobalFree API.

But thank you for your reaction.

Johan
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 1

Accepted Solution

by:
TheGrinch earned 400 total points
ID: 1177321
I had a similar problem, and couldn't depend on the user of the function doing the "free" for me. So I did something like this...

char* export WINAPI StrTest(char* Str1, char* Str2, char *res)
{
  enum  { nstring = 100, stringl = 2000 };
  static  int  n = -1;
  static  char cbuf[nstring][stringl] = { '\0' };
          char *tmp = cbuf[n=(n+1)%nstring];

  strcpy(tmp, Str1);
  strcat(tmp, Str2);
  return tmp;
}

This function uses a set of 'nstring' "wraparound buffers" of length 'stringl' to hold the return values. After 'nstring' calls, it re-uses an old buffer.

This approach imposes two limitations: The maximum length of the result can't exceed 'stringl' and the maximum number of outstanding return values can't exceed 'nstring'. Depending on how your function is used, this might be a good solution.

You can change 'nstring' and 'stringl' to large values, but they are now on the stack. To make them VERY large, use...

  static char cbuf = (char*)calloc ( nstring, stringl );

After all, it's only virtual memory...

0
 
LVL 22

Expert Comment

by:nietod
ID: 1177322
>>Depending on how your function is used, this might be a
>> good solution.
This could never be a good solution.  For the few cases where you might be able to argure that it is safe, you could easily find better solutions.

If you need powerful string manipulation, use a string class.  It is far safer and far more powerful.

Besides, ppr already has a solution.  ready the question history.
0
 
LVL 1

Expert Comment

by:TheGrinch
ID: 1177323
nietod:

The approach I gave both solves the leakage problem, and allows clients of the DLL to continue to use the function WITHOUT BEING MODIFIED. That was the problem I had (an inability to modify the clients of the DLL).

Incidentally, I agree that there are limitations with my approach, which I clearly stated.

The approach chosen by ppr doesn't do this, nor does the use of a string class do this. Only my approach does this. But maybe this wasn't the problem. ppr wasn't clear whether the clients of the DLL could be changed. I assumed they couldn't. That is a fairly common problem when changing DLLs that are widely used.

I fully agree that a string class is the preferred approach, but your comment that "This could never be a good solution" is not only dead wrong, it reflects a "better than thou" attitude. I'm not taking any offense, but do suggest that you moderate your attitude just a bit :-)
0
 
LVL 1

Expert Comment

by:TheGrinch
ID: 1177324
nietod:

The approach I gave both solves the leakage problem, and allows clients of the DLL to continue to use the function WITHOUT BEING MODIFIED. That was the problem I had (an inability to modify the clients of the DLL).

Incidentally, I agree that there are limitations with my approach, which I clearly stated.

The approach chosen by ppr doesn't do this, nor does the use of a string class do this. Only my approach does this. But maybe this wasn't the problem. ppr wasn't clear whether the clients of the DLL could be changed. I assumed they couldn't. That is a fairly common problem when changing DLLs that are widely used.

I fully agree that a string class is the preferred approach, but your comment that "This could never be a good solution" is not only dead wrong, it reflects a "better than thou" attitude. I'm not taking any offense, but do suggest that you moderate your attitude just a bit :-)
0
 
LVL 22

Expert Comment

by:nietod
ID: 1177325
My thought was that you should never purposefuly write code like that.  If you are backed into it from another programmer's mistake then I guess I might be okay to. . . No it still wouldn't be okay, find the programmer, kill him, steel his code and fix it.  That would be acceptible  : - )
0
 

Author Comment

by:ppr
ID: 1177326
It's not exactly what I was looking for, but I think it will be usefull in the future.
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

715 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question