Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

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

Posted on 1998-01-19
12
Medium Priority
?
547 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 4
12 Comments
 
LVL 22

Expert Comment

by:nietod
ID: 1178482
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
ID: 1178483
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
ID: 1178484
Edited text of question
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 22

Accepted Solution

by:
nietod earned 600 total points
ID: 1178485
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
ID: 1178486
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
ID: 1178487
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
 
LVL 22

Expert Comment

by:nietod
ID: 1178488
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
ID: 1178489
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
ID: 1178490
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
ID: 1178491
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
ID: 1178492
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
ID: 1178493
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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

721 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