Solved

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

Posted on 1998-01-19
12
499 Views
Last Modified: 2008-02-01
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
file

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:

.const
Name1 proto stdcall  HWND:WORD

.data
Hwnd1 word 0

.code
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'

exports
       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)







0
Comment
Question by:danny2
  • 8
  • 4
12 Comments
 
LVL 22

Expert Comment

by:nietod
Comment Utility
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.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
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?
0
 

Author Comment

by:danny2
Comment Utility
Edited text of question
0
 
LVL 22

Accepted Solution

by:
nietod earned 200 total points
Comment Utility
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.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
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.
0
 

Author Comment

by:danny2
Comment Utility
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
filename.obj
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)

/export:_DllMain@12


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

To nietod : as you see mr. nietod I did already use the way you told me.. but thank for your support anyway!
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 22

Expert Comment

by:nietod
Comment Utility
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.
0
 

Author Comment

by:danny2
Comment Utility
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.


0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
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.


0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
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)
{
  X(x,ch);
}

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

0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
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)
{
   XIntInt(i);
};
X(char ch)
{
   XIntChar(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)
{
   ObjPtr->Mem(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

Obj.Mem(1)

you have to use

ClsMemInt(&Obj,i);

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.
0
 

Author Comment

by:danny2
Comment Utility
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!
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

728 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now