?
Solved

DLL call doesn't work

Posted on 2004-08-09
9
Medium Priority
?
247 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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

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

[Webinar] Lessons on Recovering from Petya

Skyport is working hard to help customers recover from recent attacks, like the Petya worm. This work has brought to light some important lessons. New malware attacks like this can take down your entire environment. Learn from others mistakes on how to prevent Petya like worms.

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…
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…
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…
Suggested Courses

650 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