Connecting Tech Pros Worldwide Forums | Help | Site Map

Problems linking a BCB-DLL (.lib) under MSVC

Uli
Guest
 
Posts: n/a
#1: Nov 17 '05
Hello,

I'm trying to use a DLL (by static linking) which was compiled with Borland
C++Builder (BCB) in Visual C++ (Visual-Studio 2003).

All functions are declared with the directive 'extern "C"' so that a
cross-compiler-usage must be possible.

I created an import library (.lib) for MSVC by using the LIB function and
using a .DEF file (as described in KB131313 -
http://support.microsoft.com/default...b;en-us;131313)

My DUMPBIN showed the following exports:
ordinal hint RVA name
2 0 000012E4 @SayHello2
1 1 000012D0 SayHello1
3 2 000012F8 _SayHello3
4 3 0000130C _SayHello4
5 4 000090F8 ___CPPdebugHook

So I created a .DEF as follows:
EXPORTS
@SayHello2
SayHello1
_SayHello3
_SayHello4

The .lib and .exp generation succeeded so far.

The declaration (.h) used in BCB and included in MSVC later on is as follows:
#ifndef __BCB2VC_DLL_H
#define __BCB2VC_DLL_H

#ifdef __BUILD_DLL__
#define __DECL_SPEC__ __declspec(dllexport)
#else
#define __DECL_SPEC__ __declspec(dllimport)
#endif //#ifdef __BUILD_DLL__

extern "C" __DECL_SPEC__ void __stdcall SayHello1(void);
extern "C" __DECL_SPEC__ void __fastcall SayHello2();
extern "C" __DECL_SPEC__ void __cdecl SayHello3();
extern "C" __DECL_SPEC__ void SayHello4();

#endif //#ifndef __BCB2VC_DLL_H

In my MSVC application I simply try to call the functions:
int _tmain(int argc, _TCHAR* argv[])
{
SayHello1();
SayHello2();
SayHello3();
SayHello4();
}

This lead to the result, that I received the following linker errors:
Test.obj : error LNK2019: Nicht aufgelöstes externes Symbol
'__imp__SayHello4', verwiesen in Funktion '_main'
Test.obj : error LNK2019: Nicht aufgelöstes externes Symbol
'__imp__SayHello3', verwiesen in Funktion '_main'
Test.obj : error LNK2019: Nicht aufgelöstes externes Symbol
'__imp_@SayHello2@0', verwiesen in Funktion '_main'
Test.obj : error LNK2019: Nicht aufgelöstes externes Symbol
'__imp__SayHello1@0', verwiesen in Funktion '_main'
Debug/USE_BCB_DLL.exe : fatal error LNK1120: 4 unaufgelöste externe Verweise

---

when I create the .LIB with the .DEF like:
EXPORTS
SayHello2
SayHello1
SayHello3
SayHello4

and call the functions with (calling SayHello1 and SayHello2 doesn't succeed
at all):
int _tmain(int argc, _TCHAR* argv[])
{
//SayHello1();
//SayHello2();
SayHello3();
SayHello4();
}

then my application starts (which means linking succeeds). But while
starting, a MessageBox appears, which says:
'The entrypoint of "SayHello3" in "Test.dll" could not be found.'

So what is wrong here? How do I manage to get to get my DLL run without
changing the calling conventions (__stdcall / __fastcall) ?

Thanks,
Uli

Tamas Demjen
Guest
 
Posts: n/a
#2: Nov 17 '05

re: Problems linking a BCB-DLL (.lib) under MSVC


I think __fastcall is Borland specific, it uses registers to pass
function arguments, and it's not compatible with Microsoft. The two
others must work (__stdcall and __cdecl). I think in the DEF file you
just have to list the names, without underscores:

EXPORTS
SayHello1
SayHello3
SayHello4

the extern "C" keyword ensures that all mangling of function names is
turned off, so you just use the real name of the funciton, in plain
ASCII. No @, no _.

I usually use LoadLibrary and GetProcAddress, and this always works very
nicely between compilers (BCB and VC++), in both directions (VC++ DLL
and BCB app; BCB DLL and VC++ app).

Tom

Uli wrote:[color=blue]
> Hello,
>
> I'm trying to use a DLL (by static linking) which was compiled with Borland
> C++Builder (BCB) in Visual C++ (Visual-Studio 2003).
>
> All functions are declared with the directive 'extern "C"' so that a
> cross-compiler-usage must be possible.
>
> I created an import library (.lib) for MSVC by using the LIB function and
> using a .DEF file (as described in KB131313 -
> http://support.microsoft.com/default...b;en-us;131313)
>
> My DUMPBIN showed the following exports:
> ordinal hint RVA name
> 2 0 000012E4 @SayHello2
> 1 1 000012D0 SayHello1
> 3 2 000012F8 _SayHello3
> 4 3 0000130C _SayHello4
> 5 4 000090F8 ___CPPdebugHook
>
> So I created a .DEF as follows:
> EXPORTS
> @SayHello2
> SayHello1
> _SayHello3
> _SayHello4
>
> The .lib and .exp generation succeeded so far.
>
> The declaration (.h) used in BCB and included in MSVC later on is as follows:
> #ifndef __BCB2VC_DLL_H
> #define __BCB2VC_DLL_H
>
> #ifdef __BUILD_DLL__
> #define __DECL_SPEC__ __declspec(dllexport)
> #else
> #define __DECL_SPEC__ __declspec(dllimport)
> #endif //#ifdef __BUILD_DLL__
>
> extern "C" __DECL_SPEC__ void __stdcall SayHello1(void);
> extern "C" __DECL_SPEC__ void __fastcall SayHello2();
> extern "C" __DECL_SPEC__ void __cdecl SayHello3();
> extern "C" __DECL_SPEC__ void SayHello4();
>
> #endif //#ifndef __BCB2VC_DLL_H
>
> In my MSVC application I simply try to call the functions:
> int _tmain(int argc, _TCHAR* argv[])
> {
> SayHello1();
> SayHello2();
> SayHello3();
> SayHello4();
> }
>
> This lead to the result, that I received the following linker errors:
> Test.obj : error LNK2019: Nicht aufgelöstes externes Symbol
> '__imp__SayHello4', verwiesen in Funktion '_main'
> Test.obj : error LNK2019: Nicht aufgelöstes externes Symbol
> '__imp__SayHello3', verwiesen in Funktion '_main'
> Test.obj : error LNK2019: Nicht aufgelöstes externes Symbol
> '__imp_@SayHello2@0', verwiesen in Funktion '_main'
> Test.obj : error LNK2019: Nicht aufgelöstes externes Symbol
> '__imp__SayHello1@0', verwiesen in Funktion '_main'
> Debug/USE_BCB_DLL.exe : fatal error LNK1120: 4 unaufgelöste externe Verweise
>
> ---
>
> when I create the .LIB with the .DEF like:
> EXPORTS
> SayHello2
> SayHello1
> SayHello3
> SayHello4
>
> and call the functions with (calling SayHello1 and SayHello2 doesn't succeed
> at all):
> int _tmain(int argc, _TCHAR* argv[])
> {
> //SayHello1();
> //SayHello2();
> SayHello3();
> SayHello4();
> }
>
> then my application starts (which means linking succeeds). But while
> starting, a MessageBox appears, which says:
> 'The entrypoint of "SayHello3" in "Test.dll" could not be found.'
>
> So what is wrong here? How do I manage to get to get my DLL run without
> changing the calling conventions (__stdcall / __fastcall) ?
>
> Thanks,
> Uli[/color]
Uli
Guest
 
Posts: n/a
#3: Nov 17 '05

re: Problems linking a BCB-DLL (.lib) under MSVC


Hello Tom,

first thanks for your answer, but I'm not satisfied with the state I
actually reached. What I managed so far is:
- BCB-App <= MSVC-DLL (static, using .LIB via IMPLIB)
- BCB-APP <= MSVC-DLL (dynamic, using LoadLibrary, GetProcAddress)
- MSVC-APP <= BCB-DLL (dynamic, using LoadLibrary, GetProcAddress)
with functions of all the calling conventions (__cdecl, __stdcall,
__fastcall).

So I think there MUST be a way to make run
- MSVC-App <= BCB-DLL (static, using .LIB via LIB)
because when you're able to do so under BCB - I think you also must be able
to proceed like this under MSVC!

So, my question is still an open point ...

Uli.

Carl Daniel [VC++ MVP]
Guest
 
Posts: n/a
#4: Nov 17 '05

re: Problems linking a BCB-DLL (.lib) under MSVC


Tamas Demjen wrote:[color=blue]
> I think __fastcall is Borland specific, it uses registers to pass
> function arguments, and it's not compatible with Microsoft. The two
> others must work (__stdcall and __cdecl).[/color]

Only __stdcall must work, since that's the only ABI defined by Windows. All
other calling conventions are tool-specific and may or may not be
compatible.

Which of the techniques discussed in KB131313 did you (the OP) use? The
stub-generating technique should always work, and always produce the correct
exported names.

-cd


Tamas Demjen
Guest
 
Posts: n/a
#5: Nov 17 '05

re: Problems linking a BCB-DLL (.lib) under MSVC


I agree with you, Borland's implib is excellent. You just need to have a
DLL file, exporting pure C functions (usually via __stdcall), and you
don't need any LIB files, implib will create that automatically. I don't
know of such a tool for VC++.

The KB131313 article (http://support.microsoft.com/kb/q131313/) has a
fault. It can't work, because the VC++ compiler does not respect the
extern "C" with __stdcall, unless a DEF file is present. I think it's a
bug in every Microsoft compiler, but let's not discuss this now. The
bottom line is that if you want to use extern "C" with __stdcall, you
must have a DEF file, in order to prevent the name mangling.

So here's what you have to do. I assume that you use __stdcall, as
recommended by Carl in an earlier email. __cdecl may work with Borland,
but I'm not sure anymore. :-)

1. Create a file MyDll.c with the following:
__declspec(dllexport) int __stdcall MyFunction(void) { return 0; }
(Actually I found it easier to do it in C, because you don't need extern
"C" that way)

2. Make a DEF file called MyDll.def:
EXPORTS MyFunction

3. Type in from the command line:
cl /c /Ob0 MyDll.c
lib /def:a.def a.obj

And the mistake in the KB131313 article is that you must have a DEF file
with __stdcall, otherwise the name mangling will be on. That's why
you're getting runtimes errors that __imp__MyFunction@0 is missing, or
something like that.

I know it's tough, but it works in the end. Let me know if you need more
help. I just reproduced this with a Borland C++Builder 6 DLL and with
VC++ 2005 using a command line W32 project. It should work with other
versions of C++Builder and VC++ as well.

Good luck, and don't hesitate to ask if it's still not working, this
topic is not easy at all, and Microsoft didn't document this properly.

Tom


Uli wrote:[color=blue]
> Hello,
>
> as I described, I use the technique "Creating a .DEF file" from KB131313.
> (I don't want to use the stubbing technique because it means too much much
> in a subsequent migration process (for a lot of DLL with a lot of functions).
> And besides that, I can't image, why it is or should be <SO> complicated to
> port a BCB-DLL (of pure C-Sytle exported functions!) to MSVC. I mentioned,
> that the opposite way (MSVC-DLL => BCB-App) was quiet easy by simply using
> one single IMPLIB command! (I think MS products are innovative and it's
> promised that everything is easy ... :)[/color]
Tamas Demjen
Guest
 
Posts: n/a
#6: Nov 17 '05

re: Problems linking a BCB-DLL (.lib) under MSVC


Correcting

3. Type in from the command line:
cl /c /Ob0 MyDll.c
lib /def:MyDll.def MyDll.obj
Uli
Guest
 
Posts: n/a
#7: Nov 17 '05

re: Problems linking a BCB-DLL (.lib) under MSVC


Hello Tom,

thank you very much for your assistance - for my little "HelloWorld-Program"
it worked so far. It was a long and tedious way! Now I'll (have to) see, if
it's working in real life :)

Uli.

"Tamas Demjen" wrote:
[color=blue]
> [..]
>
> 1. Create a file MyDll.c with the following:
> __declspec(dllexport) int __stdcall MyFunction(void) { return 0; }
> (Actually I found it easier to do it in C, because you don't need extern
> "C" that way)
>
> 2. Make a DEF file called MyDll.def:
> EXPORTS MyFunction
>
> 3. Type in from the command line:
> cl /c /Ob0 MyDll.c
> lib /def:a.def a.obj
>
> [..][/color]

Closed Thread