• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 577
  • Last Modified:

link bc++4.5 dll + obj of masm6.11 in VC++4.2

How can i link a borland C++4.5 32 bits dll and object file
made with masm 6.11 in a Microsoft Visual C++ 4.2 project without getting unresolved link errors in object file? The problem is that Microsoft doesn't support good implib.exe  programms which work with VC++4.2 or 5.0. So how can I do it anyway?

futher detailed:

In Borland C++ 4.5 was the 32 bits dll made with declaration like this:

extern "C"
      int _stdcall _export Name1(HWND hWnd);

and function declaration in the same Borland C++ 4.5

int _stdcall _export Name1(HWND hWnd)

    // code who also use another 32 bit dll (also orginal borland)

The code in MASM 6.11calls Name1 like:

Name1 proto stdcall  HWND:WORD

Hwnd1 word 0

INVOKE Name1,Hwnd1

After compiling in MASM6.11 I  have a object file which should be
linked in MSVC++4.2 or 5.0.

Now I get: filename.obj error LNK2001 a unresolved external symbol _Name1@2

I make my lib file with def headers like this:

library   filename1.dll    //(borland dll)
description 'export function'

       Name1  @1

(MS-dos prompt, using the lib.exe of  MSVC++4.2 : lib  /def:filename.def  /machine:IX86)
(This normally works correct for builded Delphi 2.0/3.0 DLL's)

  • 8
  • 4
1 Solution
Unless all your procedures were declared extern "C" you can't do this anyway.  Borland and Microsoft use different schemes for name decorating so their object code can't be linked together.
Can you provide more details as to what the problem is.  What symbols were unresolved and where were they declared (Borland, Microsoft, or ASM).  Are the symbols, C++ procedures, extern C procedures, C++ objects?
danny2Author Commented:
Edited text of question
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

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.

This probably won't help but...

when you define the Name1 procedure in the C++ DLL, do you use the extern "C" there?  Is see that you use it when the procedure is declared, but maybe it should also be used when the procedure is defined.

If that doesn't help.  What is your MASM assembly and link command line?  what files are you linking with and what command line options are you using?

Wait a second.

The error you reported LNK2001 is a MS linker error.  That actually makes no sense. You should be using the Borland C++ linker.  You should compile the assembly stuff but should not link it at that time.  This gets rid of the error.  Then you should link it in with the C++ stuff when the C++ stuff is compiled.  This is because C++ must do the linking to insure that the proper run-time libaries get linked in.  Theoretically masm can do the linking, but you would have to specify all the necessary run-time libraries.
Note:  If you use the /c option MASM will assemble but not link.  This produces a .obj file that should be passed to the C++ linker.
danny2Author Commented:
more futher detailed:

To produce my masm object file I use:

ml -c -Zi -coff filename.asm

To link with VC++ I use a .rsp file

link @filename.rsp

filenam.rsp contains:

-entry:DllMain  -incremental:NO -out:filename.xxx -dll
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib
advapi32.lib shell32.lib comctl32.lib

special.lib // made with VC++
borland.lib // made with lib.exe (to access borland dll)


As you can see I can't use the Borland linker because of the

To nietod : as you see mr. nietod I did already use the way you told me.. but thank for your support anyway!
I can't tell if you have a solution or you are giving up.  It seems like you might be giving up.  If so, I don't think you need to give up yet.  

If you still need help, it seems to me that the problem is not related to the MASM part, but to the fact that you have two libraries (Borland.dll and special.lib) that are produced by different C++ compilers.  What are these libraries?  Is it possible to recompile one of them for the other compiler? (you would have to have the source code for either of them.)  If you don't have source code for the libraries, it may be possible to create a Dll to bridge from one library to the other.  Realistically this could be done only if one of the libraries contained a minimal number of functions that you want to use.  (a few dozen at most).  I could explain how to do this if other options are not available.
danny2Author Commented:
to mr. nietod:
I need still help and I don't want to give up!
You are right about the fact that I have two libraries
that are produced by different C++ compilers.

Of the special lib (made with VC++) I don't have the source code.
(So I am sticked with VC++)

Of the Borland DLL I do have the source. But in that borland
dll am I using functions of other Borland DLL which of I don't
have the source. With implib.exe I make a lib file so can I use
these functions in my Borland dll.

I did already recompile my Borland DLL for VC++ 4.2 but I get the
same problem again of Link Error Unresolved Symbols with the functions out of that borland DLL (other dll) which of I don't have the source.
That's why I said at the beginning of my question that MSVC++4.2 or 5.0 do not have good tools to make a lib file (implib.exe in Borland C++).

(I do know the names of the functions in the borland dll and with that I make a def file and made a lib file to link it VC++. But I think personally lib.exe is not entirely correct.)    

I do actually know a bit about bridging because I studied the ideas of using Win32 dll in a 16-bit programm or win16 dll in a 32-bit programm. In that case you have to build communication dll's which send messages (API) between them.

I'm not sure if you are aware of this or not, but the problems has nothing to do with implib.  It is simply the fact that borland and Microsoft use different schemes for decorating names.
  If you write a function like

X(int x,char ch)

in you source code it does not appear with the name X to the linker, or to importlib, or to other EXE's or DLL's.  This is because C++ decorates the names (adds on to it) to express information about the parameters, return value, and calling convention.  The procedures might be called something like X@int@char;  The problem is that Borland and Microsoft use different schemes for generating these names.  If you export a fnction from a library produced by Borland it gets exported using a name with there decorating system.  If you import it into a library writen in Microsoft, it takes the simple name you told it to import and determines a decorated name to look for and actually import.  Of course it doesn't find it.

There is a way around this.

Functions declared as "extern c" don't get decorated.  They appear using their simple names.  However, using extern C means that a function can't be overloaded (that is, have more than one version with the same name but different parameters).  That is because name decorating is used to give trully different names to overloaded functions that only appear to have the same name.

How to fix this?  That may depend.  The approach that I'm going to describe will work, but can get tedious if the Borland library is huge (lots of functions) or get messy, if you've got lots of classes.

I'm going to produce a simple example here.

Im goings to say you have a Borland library called B.lib file for which you have no source, but for which the function
X(int,char) is exported and is needed in Visual C.  What you would do is create a DLL in Borland that interfaces between Vissual C and the Borland library.  We'll call the DLL Int.Dll.
What Int.Dll needs to do is to export a function that Visual C can call.  Since Int.Dll is written in Borland, Visual C can't call its functions, unless they are declared extern c.  So Int.dll with need the following function

extern "c" void XInt(int x, char ch)

that's all there is to the Dll (in this case, you will probably have another function or two, or thousand)

Now you have to use this in visual C.  This could be in an EXE or DLL.  The file needs to know about the extern c function so it would be declared something like

DllImport extern 'c' XInt(int x,char ch);

Then in visual c, you would call XInt, not X and everything will be fine.

There are three sources of problems.  classes (structures), Overloaded functions, and class functions.

Classes and structures:  
you may have problems if class or structure is represented differently by Borland or Microsoft.  i.e. if given the same C++ definition of a class, they might produce different layouts in memory.  This will not happen in simple cases, but COULD happen with derived classes, or classes with virtual functions.  I'don't know if this will be a problem.  Even if it is, it could be gotten around in simple cases.

overloaded functions:
If there is an overlaoded function in B.lib, say X(int) and X(char), you will have to create two non-overloaded functions in Int.Dll, say XIntInt() and XIntChar().  You will have to call the appropriate function in visual C.  If that is a pain, you could create a pair of overloaded functions in visual c that simply call the appropriate interface function, like

X(int i)
X(char ch)

then you could just use X() again.

Member functions:
If you have member functions you will have to pass the object (*this) as a parameter.  So given

Cls::Mem(int i)

in B.lib.

you will need

ClsMemInt(Cls *ObjPtr,int i)

in the interface dll (Int.DLL).

this means you have to call the member function as a regular function in visual c. Instead of


you have to use


If that is too messy, you can declare a class derived from this one in vissual C with no extra members, but that redefines all the member functions.  Each redefined member function just calls the interface function.

Wow.  hope that helps.
danny2Author Commented:
o.k. thank you so much... Your answer sounds excited, within a few days I will work on it again, and I will let know if it
finally succeeded!
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

  • 8
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now