Variant in DLL.

I have written DLL ("normal" one not a COM) which exports some functions with Variant parameters and/or result types. When first calling those functions everything goes nice and smooth but second function call fails, I recive EAcccessViolation error in nnn.dll.
What's goinig on? why first call is successfull but next calls fails ,are there any restrictions in using Variants in DLLs?
Thanks, ziolko.
LVL 21
ziolkoAsked:
Who is Participating?
 
EpsylonConnect With a Mentor Commented:
There are restrictions when using pascal strings. Not with variants as far as I know...

Please show some code.
0
 
ziolkoAuthor Commented:
EXE side:
type
TFuncInDLL = function(Params: Variant):Variant;stdcall;
var
  funaddr: TVariantFuncInDLL;
  ret, prms: Variant;
.
.
.
@funaddr:=GetProcAddress(LibHandle,EFN);
ret:=funaddr(prms);
.
.
.
DLL side:
function SomeFunc(Params: Variant):Variant;stdcall;
begin
  // anything here like:
  Result:='Hello World';
end;
0
 
ziolkoAuthor Commented:
Ooops of Course : funaddr: TFuncIsDLL
ziolko.
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

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.

 
EpsylonCommented:
Try removing all stdcall directives...
0
 
ziolkoAuthor Commented:
I got it!, yep it's pascal string problem.
function on DLL side was a little bit different and looked like that:

function SomeFunc(Params: Variant):Variant;stdcall;
var s: string; <- that's my problem
begin
 // anything here like:
 s:='Hello World';
 Result:=s;
end;
change declaration s: string -> s: WideString and there is no problem.
But anyway why it worked first time, and only first time?
ziolko.
0
 
SChertkovCommented:
Try add ShareMem to uses section of you dll & EXE projects.
Delphi variant support varString type as native pascal
string and so if you not use ShareMem you dll have
separate memory manager that destroy after dll unload.
If you use WideString variant type is BSTR and Delphi
memory manager not used.
0
 
ziolkoAuthor Commented:
I know about ShareMem, I tried it several times but it causes many errors, also I've tried ShareMem written by Madshi works better, but still I prefer WideStrings.
Anyway I;m still wondering why it worked first time? it's not accident it always works first time.
ziolko.  
0
 
EpsylonCommented:
Did you try removing stdcall????
0
 
SChertkovCommented:
What errors cause ShareMem ?
I think this is accident.
Access violation caused while finalyze variant
variable in main program.
Probably you not set this variable until
second call.
0
 
ziolkoAuthor Commented:
Epsylon > stdcall makes no difference
SChertkov > about ShareMem I'm not able to post any sample erros from ShareMem I haven't use for quite long time, with variants situation is clear for me (I think so) errors comes only when trying something likt this:
Result:=s; where Result is variant and s is pascal string.
I think my question should be: Why pascal strings cannot be passed to DLLs?
ziolko.
0
 
SChertkovCommented:
Pascal string allocated dynamically on delphi heap.
Each string contain extra 12 bytes
(see StrRec in System.pas): block size, ref count
and string length. When assign variable changed ref count.
When ref count = 0 the string dispose. If you use DLL
without ShareMem you have two separate heap: main
process and DLL heap. Then heap
manager try dispose string it can not determinate
that string own another heap. So, pass process
string to DLL destroy heap of main application
and return string destroy DLL heap.
This errors are imperceptible and can cause later
or not cause at all.
So then you use string shared between application and
library you must use shared memory manager in
application and library.
Another way use PChar like Win32 or WideString
like OLE.

0
 
EpsylonCommented:
Try OleVariant instead of Variant.
0
 
ziolkoAuthor Commented:
Epsylon > it's not stdcall also not OleVariant like I said earlier problem was useing string instead WideString, You will get points as You pointed that there is no restrictions with Variants.
SChertkov > Meanwhile I've  changed My Q and You answered it so look for Q with title: "Points for SChertkov" post there any comment and You will get points You deserve.

I hope that both of You will be satisfied with my solution
ziolko.
0
 
ziolkoAuthor Commented:
Comment above :-))
ziolko.
0
 
EpsylonCommented:
No problem. Thanks.

Only I have second thoughts about the solution.

I tried something similar and I can use really large strings inside the DLL. I even got an 'out of memory' once but i can use strings that are 100 MB in size. I can even parse them to the DLL and get as a result back from the DLL as long as I use OleVariant. When I use Variant I get an 'Invalid pointer operation'.
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.

All Courses

From novice to tech pro — start learning today.