Solved

Variant in DLL.

Posted on 2001-07-03
15
291 Views
Last Modified: 2010-04-04
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.
0
Comment
Question by:ziolko
  • 7
  • 5
  • 3
15 Comments
 
LVL 13

Accepted Solution

by:
Epsylon earned 50 total points
Comment Utility
There are restrictions when using pascal strings. Not with variants as far as I know...

Please show some code.
0
 
LVL 21

Author Comment

by:ziolko
Comment Utility
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
 
LVL 21

Author Comment

by:ziolko
Comment Utility
Ooops of Course : funaddr: TFuncIsDLL
ziolko.
0
 
LVL 13

Expert Comment

by:Epsylon
Comment Utility
Try removing all stdcall directives...
0
 
LVL 21

Author Comment

by:ziolko
Comment Utility
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
 
LVL 2

Expert Comment

by:SChertkov
Comment Utility
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
 
LVL 21

Author Comment

by:ziolko
Comment Utility
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
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 13

Expert Comment

by:Epsylon
Comment Utility
Did you try removing stdcall????
0
 
LVL 2

Expert Comment

by:SChertkov
Comment Utility
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
 
LVL 21

Author Comment

by:ziolko
Comment Utility
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
 
LVL 2

Expert Comment

by:SChertkov
Comment Utility
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
 
LVL 13

Expert Comment

by:Epsylon
Comment Utility
Try OleVariant instead of Variant.
0
 
LVL 21

Author Comment

by:ziolko
Comment Utility
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
 
LVL 21

Author Comment

by:ziolko
Comment Utility
Comment above :-))
ziolko.
0
 
LVL 13

Expert Comment

by:Epsylon
Comment Utility
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

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

771 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

10 Experts available now in Live!

Get 1:1 Help Now