dll method call problem

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

dll method call problem

Jochen Riekhof-5
Hi...

for the first time I try to build a dll to access from Dolphin for speed
reasons. I use Visual Studio 6. As I have not too much of an idea about
Windows specialities to create dlls, I just created the sample dll
project; it compiled just fine.
Produced is a dll that exports a global variable, a class and a methos.
I am only interested in the method so far.
The method is defined:
JRSTIMAGING_API int fnJRSTImaging(void);

JRSTIMAGING_API is defined (I hope) as
__declspec(dllexport)

I assume this is as said, but JRSTIMAGING_API is defined depending on a
#define named JRSTIMAGING_EXPORTS. The latter seems to be properly
defined in the compiler parameters so i assume it is ok.

I built the dll, copied it to the Dolphin installation folder and
defined the class JRSTImagingLibrary as subclass of ExternalLibrary.
I defined the class method
fileName
        ^'JRSTImaging'

and the instance method

fnJRSTImaging
        " INT fnJRSTImaging(void);"
        <cdecl: dword fnJRSTImaging>
        ^self invalidCall

(I also tried stdcall: but I think its wrong, or?)

JRSTImagingLibrary default isOpen
returns true but
JRSTImagingLibrary default fnJRSTImaging
fails with "Procedure not found"

What am I doing wrong?

Ciao

...Jochen


Reply | Threaded
Open this post in threaded view
|

Re: dll method call problem

Chris Uppal-3
Jochen Riekhof wrote:

> fnJRSTImaging
> " INT fnJRSTImaging(void);"
> <cdecl: dword fnJRSTImaging>
> ^self invalidCall
>
> (I also tried stdcall: but I think its wrong, or?)

The choice of 'stdcall' vs. 'cdecl' should reflect how the DLL was compiled.
Both calling conventions can be used in DLLs.  I believe that 'stdcall' is the
most common, but I'm afraid I can't remember what the default is.

> JRSTImagingLibrary default fnJRSTImaging
> fails with "Procedure not found"

This is probably because the actual function name in the DLL is not the same as
you'd expect.  The C/C++ compiler 'mangles' names in various ways for various
reasons (mostly to do with C++).  If you force MSVC to compile the code as 'C'
rather than 'C++' (or to use C naming by using an
    extern 'C'
declaration) then the names will be /much/ less badly mangled.  You can see the
names in the DLL by using the 'dependency walker' tool, which is available at
http://www.dependencywalker.com/ (or an earlier version was included in MSVC6).
I recommend that you get a copy.

You have (at least) two options.  One is to tell Dolphin about the mangled
names.  The other option, which I prefer, is to use a .DEF file as part of the
project.  For instance, the following is the start of the .DEF file for one of
my DLLs:

LIBRARY
EXPORTS
    DiffusionHash=_DiffusionHash@12
    CaseInsensitiveDiffusionHash=_CaseInsensitiveDiffusionHash@12

the name 'DiffusionHash' is what appears in the C source for the DLL, and
that's what I want to use in the Dolphin code that links to it.  So my .DEF
file tells the linker to create a DLL where the 'C' function that is "really"
called by the mangled name: '_DiffusionHash@12' is also available under the
simple name 'DiffusionHash'.  The rest of the file just consists of more lines
like the above that create aliases for the rest of the functions.

If you like, I can send you the source for the simple library that the above
example is taken from.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: dll method call problem

Jochen Riekhof-5
Hi Chris...

what a nice and complete reply! You saved me days, thanks a lot!!

Dependency Walker I had installed already with Visual Studio 6 (simply
called Depends in the start menu), and indeed the shown names were
cryptic. I used extern "C" and voila, they look as the original ones. I
can call the methods now in Dolphin no problem! So far I did not need
the DEF file mechanism, as the names are ok, bt I will shure use it as
soon as I see problems.

> The choice of 'stdcall' vs. 'cdecl' should reflect how the DLL was compiled.
> Both calling conventions can be used in DLLs.  I believe that 'stdcall' is the
> most common, but I'm afraid I can't remember what the default is.

I looked up cdecl/stdcall in MSDN:
cdecl stands for c-style method call convention - the stack is cleaned
up by the caller. stdcall OTOH is pascal style, the stack is cleaned up
by the callee (method). While the first convention allows for easy
implementation of methods with variable number of arguments (the caller
knows what he is pushing on the stack), stdcall leads to maller code
size as the cleanup code is there only once (in the method) rather than
on all method calls. For the latter reason I think MS uses stdcall often
in its libraries.

When you do not specify stdcall, cdecl is the default in C/C++.

Have a good one!

Ciao

...Jochen