Solved

C++-DLL and Delphi 3

Posted on 1998-11-09
9
493 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
  • 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
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
LVL 1

Accepted Solution

by:
TheGrinch earned 200 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

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

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

Suggested Solutions

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
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 learn how to clear a vector as well as how to detect empty vectors in C++.

813 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

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now