• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 357
  • Last Modified:

String class internal structure

I want to build a Delphi string class in C, and then send it to a Delphi DLL. I also want to be able to read returned strings. How can this be done? - What is the internal structure of the Delphi string class?
0
obg
Asked:
obg
  • 7
  • 6
  • 4
  • +2
1 Solution
 
dwwangCommented:
You don't need to do that, you can use C strings, in Delphi, it is called Pchar. You can manipulate them in Delphi DLLs and return them. In Delphi, there are many functions can process NULL terminated strings, all begin with "str", such as strCopy,...

Need any further information, drop me a comment.
0
 
obgAuthor Commented:
Sorry. I don't have the DLL source. I know it's "bad manners" to use other types of strings in Win32 environment than Pchar, c-type, but it's not within my control.

0
 
viktornetCommented:
Hello there...

I think that dwwang's answer was correct.... I have no idea why you rejected it, but anyway... here is a more detailed explanation...

in C you'd declare the strings like this...

char *str = "Whatever";  //or
char str[100];

This in Delphi would be declared like so...
var
  str : PChar;

then you can pass the C str to the Delphi str...

here is an example...

C function...

char *foo(char *str)
{
  return str;
}

In Delphi you could do the following in order to receive the string,..

var
  pStr : PChar;
  Str : string;
begin
  pStr := foo('whatever');
  str := strpas(pStr); //Now you have an original STRING type variable...
  ShowMessage(str);
end;

Hope this helps...

-Viktor
--Ivanov
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
dwwangCommented:
Hi, vik, thanks. But I understand obg's problem, he does not have the DLL source! :-)

Hi,obg: I think the problem might not be so easy, you can view system.pas in Delphi source, there is some conversion between PWideChar and string(don't know whether convertion from PChar is the same or not).

Regards,
Wang
0
 
obgAuthor Commented:
Thanks for your answer, viktornet, but again - I don't have the DLL source...

Thanks for the tip, dwwang. I'll have a look at my Delphi installation at work...

0
 
obgAuthor Commented:
Adjusted points to 300
0
 
MadshiCommented:
O-oohhh. I guess, you'll have problems with what you want to do. If I understand you right, you've a Delphi dll that imports functions with Delphi strings as parameter, right?
In such cases Borland/Inprise claims, that you import the unit ShareMem in both the dll and the program that uses the dll. The unit ShareMem does the following: Delphi strings are automatically allocated/deallocated by Delphi's memory manager. Your program would probably crash, if Delphi tries to handle a string that is allocated from another memory manager. So the unit ShareMem makes sure that both the program and the dll use the same memory manager.
If you want to write a C program that allocated Delphi strings and give these strings to a Delphi dll, you'll have to use the same memory manager in C that the Delphi dll uses.
Hmmm, did you understand this? Any questions?
Or did I misunderstand your problem?

Regards, Madshi.
0
 
MadshiCommented:
Of course I mean a Delphi dll that EXPORTS functions width Delphi strings as parameter...
0
 
dwwangCommented:
Madshi's comment sounds reasonable, anyway, you can find what you want the descriptions in Delphi's help, see the topic of "Long string types", it describes how a string is internally stored in memory.
0
 
MadshiCommented:
Hmmm. In "system.pas" you'll find this declaration:

type
  StrRec = record
             allocSiz: Longint;
             refCnt:   Longint;
             length:   Longint;
           end;

This record is stored in front of the string data itself. So a string "test" would probably allocated with the length of 12+4=16 bytes, where the allocSiz and the length would be set to 4 and the refCnt to 1.

But as you can read in my last comment, I think you'll get problems if you just allocate this string structure in your C program, since the Delphi dll needs the string to be allocated by it's own memory manager...

Regards... Madshi.
0
 
obgAuthor Commented:
Gee... Lots of comments. - Thanks!

Ok. What is refCnt? - The number of references, for garbadge collect...? What if I can settle with reading returned strings, whould that be possible? Would not allocSiz be set to 16 (or maybe more) in the example above?
0
 
hustchCommented:
A Delphi string (long string) is a pointer, which is used in the following way:

When the pointer is nil (null), the string is empty.
Otherwise, the pointer holds the address of the string data :

  32-bit   : Refererence count
  32-bit   : Length
  1-x byte : String data, zero terminated.

The reference count is used by Delphi for deallocating memory. Delphi don't copy the data unless it is nessecary. If the data is changed when the reference count is > 0, the data is copied to a new location before they are changed.
When a string variable goes out of scope (or is assigned a new value), it is decreased. When it reaches zero, the memory is deallocated.
If you don't use it, you should just set it to one, to prevent Delphi to attempt to deallocate it.

The Length field is the length of the data, not counting the zero at the end of the data.

The actual string data has the same format as a PChar. When you typecast a string to a PChar, Delphi simply gives you the address of the data-part. That is why, you can normally use string variables, where PChar parameters are required. This makes it easy to pass string data to non-Delphi functions, like the Win32 api.
0
 
obgAuthor Commented:
Thanks for your answer, hustch, but what about allocSiz? Otherwise it was almost the same explanation as Madshi gave me, apart from the zero termination.
0
 
MadshiCommented:
Grfpgfpffgd##dfgg#@$§&$, you're right, it was almost the same explanation as mine. So why (dam...) give you the points to him and not to me????????
And you should always test answers before accepting them! As I said before: I think you'll get problems with the memory manager...
0
 
hustchCommented:
The allocSiz is for Delphi memory administration, which is quite complex. It looks as if Delphi allocates mery in 4-byte bloks, and it uses different strategies for bloks smaller than 4kb, than for larger blocks.
Do you need to deallocate strings allocated in the dll ?
parameters, If you only passes input you don't.

By the way, I did a little test, and the pointer value, that Delphi passes for parameters is the address of the 1st character in the string, not the address of any of the preceding fields.
0
 
obgAuthor Commented:
First of all: I am so sorry Madshi, but he posted it as an answer, and you did not. I was also tired of rejecting peoples answers, as I think that I know most of what I have to know. I think that this might take to much work, for which my client can't pay... Again I'm sorry, but be pissed at him - not me.

Hustch: I probably ought to deallocate the strings. Or maybe not... Don't they get free'd when I do FreeLibrary?
0
 
MadshiCommented:
obg, I didn't post an answer because Wang and Viktor already helped you. So I chose the polite way and wanted to give you the possibility to decide which comment helped you the most. Unfortunately I often get punished for this kind of politeness...     :-(
However, I can't buy something with the points, so forget it...
0
 
hustchCommented:
FreeLibrary doesn't free allocated memory, because it belongs to application, not the dll. A dll and the exe shares memory, and when a dll is used by more than one application, only the code is shared, so if the dll has a global variable, it has a copy for each process that uses the dll.

If the amount of lost memory (or number of lost memory-blocks) is acceptable, you can ignore it, it will be free'd when the application terminates.
Otherwise, if you have Deplhi at work, you could create a small dll, with a function for allocation, and one for deallocation.

To Madshi:
I think most of your answer is inaccurate, and while correct in some situations, it is plain wrong in other situations. If you knew that, you should have written someting about it.
0
 
MadshiCommented:
hustch,

don't think my answer is inaccurate. What are you talking of? Ok, if I look again at what I've written, the allocSiz is wrong, but that's surely not "most of my answer".

BTW, your idea with the second Delphi dll is nice. But it should be added that obg has to import the unit ShareMem. It seems that you totally ignore the memory manager problems...

Regards... Madshi.
0
 
hustchCommented:
Madshi.

You also says, that "the Delphi dll needs the string to be allocated by it's own memory manager". That is only true, if it tries to deallocate it, which I have described how to avoid.

The ShareMem issues has already beed described (by you I think).

Grüße
0
 
viktornetCommented:
Hey guys...

Doesn't the word "Grüße" w/o the quotes means not polite or something?

btw- No need to fight anyway. It's Christmas y'all, but if i need to take a side i agree with Madshi mostly... Most of the time there is no such a thing as right answer.. There are many ways to accomplish things so chill out y'all...

-Viktor
--Ivanov
0
 
MadshiCommented:
Hi Viktor, thanx for your support...  :-)

"Grüße" is just the german word for "Regards".

hustch, the problem is, that we don't know, what the Delphi dll does with the strings. Perhaps one function takes a "var string" as a parameter and internally tries to empty/change the string and then you can't avoid that the dll tries to deallocate/reallocate the string. However with a second Delphi dll obg should be able to solve this allocation problem.

Regards/Grüße, Madshi.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

  • 7
  • 6
  • 4
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now