6
votes

My company provides a third party with a DLL which provides them with API functions they can use to connect to our application. The DLL was written in VC9, and the API functions used VC's default calling convention (__cdecl). The third party has built their application around this interface.

I have now been tasked with writing an updated version of the DLL. We want the DLL to have exactly the same interface as the old one so they can be used interchangeably. Unfortunately, our development environment is now CodeGear RAD Studio 2007, so I have to write the DLL using that.

The best solution would be to make both the old and new DLLs export their functions as __stdcall. The third-party application could then be re-linked to expect __stdcall functions and everyone would be happy. Unfortunately, for various reasons this is unlikely to happen.

Alternatively, I can declare the functions in my DLL as __cdecl. The third-party expects __cdecl functions so this would seem to be a good solution. Unfortunately CodeGear insists on appending an underscore ('_') to the name of __cdecl functions. This means that the third-party application would have to make conditionally call MyApiFunction(...) or _MyApiFunction(...), depending on which DLL they use.

So my question is, how can I export the API functions from my new DLL in such a way that they are __cdecl and are not prefixed with an underscore ('_')?

3
What's a calling convention worth when a compiler decides to not obey them?orlp
VC9's __cdecl and Borland's __cdecl work the same way (Right-to-left parameter order, Caller cleans up, Parameters passed on the stack), they will work together ok if it were not for the name decoration.Hoppy
Hoppy: Is the name decoration not defined in the convention?orlp
What convention are you referring to? VC9 and Borland have their own implementations of __cdecl, which differ (only) in the way they decorate the exported function names.Hoppy
@nightcracker The concept you're looking for here is referred to as an ABI -- something that makes binary images produced by different compilers interoperable. C, unfortunately, lacks a standardized ABI.Conspicuous Compiler

3 Answers

7
votes

You should use .DEF file:

EXPORTS
    HTMLayoutClassNameA = HTMLayoutClassNameA
    HTMLayoutClassNameW = HTMLayoutClassNameW
    HTMLayoutClipboardCopy = HTMLayoutClipboardCopy
    ...

Here we have

externalname = internalname 
0
votes

The Borland C/C++ compiler has an option to turn underscore generation on symbols on and off. -u (the default) generates underscores on symbol names. Add -u- to the command line and see if that helps. (I'm not sure where to do this in CodeRad, but I'm pretty much sure to remember that it could be done somewhere in the IDE).

0
votes

use -vu compiler option to not prefix underbars to exported symbol names in bcc