?
Solved

From C++ to Delphi: several approaches to deal with pointer parameters

Posted on 2011-04-25
8
Medium Priority
?
274 Views
Last Modified: 2012-05-11
I'm writing a piece of code that will interact with a 3rd party C++ library.

In a particular function, for example, the header and function looks like this:
(There are several dozens funcions to call)


SOME_API int CPP_GetSomeValue(int* valueRet);


The function is defined like this:
int CPP_GetSomeValue(int* valueRet);
{
  GetSomeValue(valueRet);
  return 0;
}

Open in new window


Then the function it calls, is defined like this:
int GetSomeValue(int* valueRet)
{
  int val;
  SomeVal(val)
  *valueRet = val;
  return 0;
}

Open in new window


and finally SomeVal is defined like this:
int SomeVal(int& typeRet)
{
  typeRet = 255;	
  return 0;
}

Open in new window



Now, in Delphi, I have my header defined like this:

CPP_GetSomeValue: function (valueRet: PInteger): Integer stdcall;


And finally how should I define and send and get this value back which was filled by the C++

Library?

I found 3 ways to do the same, but I want to know what's the correct way to do it, what are the

difference between them, and possible problems:


1)
The easiest one, just declare an Integer, pass the address, read the value again.

ivalueRet : Integer; 

CPP_GetSomeValue(@ivalueRet);
Result := ivalueRet;

Open in new window


.. though I feel this "risky", doesn't seem safe. but I don't know



2)
Define a PInteger, New it, pass it, derreference it and dispose it      

pvalueRet : Pinteger;

New(pvalueRet); 
CPP_GetSomeValue(pvalueRet);
Result := pvalueRet^;
Dispose(pvalueRet);

Open in new window

(I found this also works to get the value: Result := PInteger(@pvalueRet)^;)




3)
Define a PInteger, but don't initialize it and pass the address:

pvalueRet : Pinteger; 
// Not "new", not "dispose"
CPP_GetSomeValue(@pvalueRet);
Result := Integer(pvalueRet);

Open in new window

(I found this also works to get the value: Result := PInteger(@pvalueRet)^;)

This also looks weird, like I'm just using the pointer to get the integer back.


Which one is the correct? The one that doesn't get me memory leaks, dangling pointers and ugly stuff like that.

0
Comment
Question by:fischermx
  • 5
  • 3
8 Comments
 
LVL 32

Accepted Solution

by:
Ephraim Wangoya earned 2000 total points
ID: 35467747

1.
The first method is the best, clear short and simple
CPP_GetSomeValue(@ivalueRet)
You are passing the address of the variable which is what is expected by the function. This is the method I would use.

2.
This method is also correct but not so user friendly. You allocate memory when you do not need to. You could have simplified this by pointing to an existing variable eg
var
  valueRet: Integer;
  pvalueRet : Pinteger
begin
  pvalueRet := @valueRet;
  CPP_GetSomeValue(pvalueRet);
  Result := valueRet;
end;

But this are just extra steps that make your code less readable

3.
Simply don't use this method


0
 
LVL 1

Author Comment

by:fischermx
ID: 35469933
Hi, Ewangoya:

Thanks for your reply.

I was using method 1 and 2 in different parts of this project (I'm implementing a dataset for a proprietary data format), but currently I'm getting weird AV's inside DB unit, so I was about to blame either of those for trashing Delphi memory and wanted to decide for one.

I guess the AV in my code are not related to these calls.

0
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 35470046

Right, its unlikely that this is what is causing the AV.

Why don't you run the program with debug options enabled, then set a break point where you suspect the AV happens then you can step through the code until you get the AV
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 1

Author Comment

by:fischermx
ID: 35476096
Yes, I did that.
The AV occurs in an assignment to true to a boolean member of TDataset that is only used as a simple flag... weird, very weird. Memory has been severely damaged.
I've just found out yesterday that the problem only exists when a DBGrid is present. If I just put DBEdit my dataset works fine.
I know a DBGrid causes a lot of "motion" inside the dataset, and somehow, some thing is getting overriden :(

0
 
LVL 1

Author Comment

by:fischermx
ID: 35480318
Ewangoya:

Let me ask you something more.
According to what you see in the C++ code and the way I'm calling it from Delphi... should the header be declared in Delphi as "stdcall" or "cdecl"?
0
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 35480427
That should be stdcall
0
 
LVL 1

Author Comment

by:fischermx
ID: 35497551
Hi, Ewangoya:

The AV I was talking about were fixed by changing "stdcall", as I had it, to "cdecl" !
I'm not understand why.

Well, this is was an additional question anyway, thanks for the answer on the parameter handling.
0
 
LVL 1

Author Closing Comment

by:fischermx
ID: 35497552
Great! Thank you!
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

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

This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
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.
Suggested Courses

839 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