Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Variant in DLL.

Posted on 2001-07-03
15
Medium Priority
?
332 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 5
  • 3
15 Comments
 
LVL 13

Accepted Solution

by:
Epsylon earned 100 total points
ID: 6247927
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
ID: 6247997
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
ID: 6248006
Ooops of Course : funaddr: TFuncIsDLL
ziolko.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 13

Expert Comment

by:Epsylon
ID: 6248058
Try removing all stdcall directives...
0
 
LVL 21

Author Comment

by:ziolko
ID: 6248086
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
ID: 6248739
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
ID: 6251310
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
 
LVL 13

Expert Comment

by:Epsylon
ID: 6251409
Did you try removing stdcall????
0
 
LVL 2

Expert Comment

by:SChertkov
ID: 6251488
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
ID: 6254308
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
ID: 6254401
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
ID: 6261785
Try OleVariant instead of Variant.
0
 
LVL 21

Author Comment

by:ziolko
ID: 6266739
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
ID: 6266746
Comment above :-))
ziolko.
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 6266898
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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
Suggested Courses

688 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