?
Solved

DLL call doesn't work

Posted on 2004-08-09
9
Medium Priority
?
245 Views
Last Modified: 2010-04-05
Hi all,

I have a problem with a call to a DLL apparently written in C.
(It's Fastlook 11 if anyone knows it and has experienced similar problems)

The DLL is initialized correctly and other functions all work as expected.
It's just the function below that doesn't work.


In the help file there is the function prototype written as:

BOOL FAR PASCAL GetDwgName(int Channel, char FAR * DwgName)


So I wrote the following code to call this function:

===========================================
type
   TGetDwgName = function( Channel: Longint; FileName: PChar ): Longint; pascal;

var
   fnFileName  : TGetDwgName;


------------------------------------------
in some init func:


      @fnFileName := GetProcAddress( m_uiLibHandle, 'GetDwgName' );


-------------------------------------------
some other func:

var
   A: array[0..MAX_PATH] of Char;
begin
   if( m_uiLibHandle <> 0 ) then
   begin
      fnFileName( ci_Channel, A );
      ViewFile( A, true );
   end;
end;


There is no error when the function is called, but it doesn't change anything
in the array! A has the same content as before.

I don't think that it is a problem in the DLL. I guess I have an error in my code
but I just can't find it. Any suggestions?

regards
Wyverex


0
Comment
Question by:Wyverex
[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
  • 4
  • 3
  • 2
9 Comments
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 11751772
As I can see the function's result is BOOL, you declare it as LongInt... But frankly ... I don't think this is a problem...
0
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 11751782
BTW, what happens after this line:

@fnFileName := GetProcAddress( m_uiLibHandle, 'GetDwgName' );

what is the address of fnFileName???
0
 
LVL 17

Accepted Solution

by:
Wim ten Brink earned 1000 total points
ID: 11751813
Try
  type TGetDwgName = function( Channel: Longint; FileName: PChar ): Longint; cdecl;
Instead. Or play with the other calling conventions. (Register, Safecall, etc.)

But that should not be the real problem. What does suprise me in the C declaration is the use of FAR. AFAIK, in Windows 32 there are no NEAR or FAR pointers anymore. It seems you're looking at a 16-bits definition of the DLL. Is it a 16-bits DLL?

Do you also check if GetProcAddress assigns a value? If GetProcAddress cannot find a procedure, it doesn't raise an exception. It just returns nil. But then you'd tget an access violation...

Btw... Try calling it as: fnFileName( ci_Channel, @A );
Thus, you pass along the pointer to A, not A itself. It could be that Delphi is a bit confused about this and passes the wrong thing...
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!

 

Author Comment

by:Wyverex
ID: 11751878
Thx for the fast answers :-)

fnFileName contains a valid function address after the call to GetProcAddress.
So the function is indeed called.

Workshop_Alex wrote:
>> Btw... Try calling it as: fnFileName( ci_Channel, @A );
>> Thus, you pass along the pointer to A, not A itself. It could be that Delphi is a bit confused about this and passes the
>> wrong thing...

Tried that before. Doesn't work either the content is still unchanged.

>> What does suprise me in the C declaration is the use of FAR. AFAIK, in Windows 32 there are no NEAR or FAR
>> pointers anymore. It seems you're looking at a 16-bits definition of the DLL. Is it a 16-bits DLL?

I don't think so. I guess it is just a remnant, if anyone still uses 16-Bit windows and wants to use Fastlook.
As I said before I don't have any problems with other function calls in the same DLL. Even where there
is a string as a parameter.
But there was no other function yet that returns a string instead of just taking it. So I guess it has
something to do with a call-by-reference that goes wrong here.
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 11752292
Okay, I think the definition should be:
  TGetDwgName = function( Channel: Longint; var FileName: PChar ): WordBool; pascal;

Tried that already?
0
 

Author Comment

by:Wyverex
ID: 11752413
I tried that and there is a compiler error in the function call.
After adding the "var" to the parameter list you can no longer pass
an array of char into the function.

But I don't know what other data type I should use than
A: array[0..MAX_PATH] of Char


0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 11752526
Use this:

A: Array[0..MAX_PATH] of Char;
PA: PChar;
begin
  PA := @A;
  fnFileName( ci_Channel, PA );

It is likely though that fnFileName will return a new string instead of overwriting the old value. Perhaps fnFileName just wants a pointer to a char array and fills it with a new pointer. Anyway, Check after the call if (PA=@A) to see if I'm right or not. If I'm right, the fnFileName function might be allocating the memory for the string by itself... (Which might or might not cause a memory leak somewhere...)
0
 

Author Comment

by:Wyverex
ID: 11753339
That didn't work either.

But I have found the problem now...
I had to use stdcall as a calling convention. I remember that I tried
this before but I got an exception everytime I called the function.
I guess there was some other error but now it works like this:

====================================
type
   TGetDwgName = function( Channel: Longint; FileName: PChar ): Longint; stdcall;

var
   fnFileName  : TGetDwgName;


------------------------------------------
in some init func:


      @fnFileName := GetProcAddress( m_uiLibHandle, 'GetDwgName' );


-------------------------------------------
some other func:

var
   A: array[0..MAX_PATH] of Char;
begin
   if( m_uiLibHandle <> 0 ) then
   begin
      fnFileName( ci_Channel, A );
      ViewFile( A, true );
   end;
end;


So you've pointed me in the right direction Workshop_Alex.
thx alot!

Wyverex
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 11757397
You're welcome. I knew it should be something like that and just didn't understand why it didn't work. :-)

I had similar problems myself in the past, where parameters weren't changed correctly and in all cases I solved it by changing the calling convention.

But you might want to use WordBool as return code. It does seem to return a boolean and WordBool should be compatible...
0

Featured Post

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.

Question has a verified solution.

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

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…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Suggested Courses
Course of the Month15 days, 14 hours left to enroll

743 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