Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29279 Discussions

error LNK2019: unresolved external symbol when "linking" to a VB6 Active X DLL

Timothy_Harned
Beginner
2,650 Views
Hi,

I'm having a problem "linking" to an Active X DLL.

The attached Word Doc details the issue and contains embedded source code.

Thanks.

0 Kudos
14 Replies
Steven_L_Intel1
Employee
2,650 Views
In the project you converted from CVF, right click on the project, select properties, External Procedures. Change Calling Convention to "Default" and String Length Argument Passing to "After All Arguments". Rebuild and see if that takes care of it.
0 Kudos
Timothy_Harned
Beginner
2,650 Views

I have to do this in the main program and all the FORTRAN libraries between the Main and the Axtive X DLL, correct?

0 Kudos
Steven_L_Intel1
Employee
2,650 Views
Yes, though if all the projects had the CVF option set it should have been ok.
0 Kudos
Timothy_Harned
Beginner
2,650 Views
Hi Steve,

I believe they all did. All were CVF projects and converted by IVF

I will check and rebuild to verify.

Thanks, Tim
0 Kudos
Timothy_Harned
Beginner
2,650 Views
Hi Steve,

This did not fix my problem. I will admit, I'm not an expert on all the calling conventions and specifically the various options the Module Wizard creates.

I've played with the calls in Function PDD_FINITT to test things without luck.

Bold indicates my text. Normal is code/error messsages. (But it didn't seem to always work when I previewed it.)

Here are the error messages of the IVF build:

1>------ Rebuild All started: Project: BH_PLOT, Configuration: Release Win32 ------

1>Deleting intermediate files and output files for project 'BH_PLOT', configuration 'Release|Win32'.

1>Compiling resources...

1>BH_PLOT.rc

1>Microsoft Windows Resource Compiler Version 6.1.7600.16385

1>Copyright (C) Microsoft Corporation. All rights reserved.

1>Compiling with Intel Visual Fortran Compiler XE 12.0.0.104 [IA-32]...

1>BH_PLOT.FOR

1>Linking...

1>TEKTRONIX_WIN.LIB(TD_TCSDD_WIN.obj) : error LNK2019: unresolved external symbol _TEKPRINTLIB_TEKRELEASE referenced in function _PDD_FINITT

1>TEKTRONIX_WIN.LIB(TD_TCSDD_WIN.obj) : error LNK2019: unresolved external symbol _TEKTRONIX_VB_TEKPRINTLIB_TEKMODPRINTER referenced in function _PDD_INITT

1>TEKTRONIX_WIN.LIB(TD_TCSDD_WIN.obj) : error LNK2019: unresolved external symbol _TEKTRONIX_VB_TEKPRINTLIB_TEKINITIALIZE referenced in function _PDD_INITT

1>TEKTRONIX_WIN.LIB(TD_TCSDD_WIN.obj) : error LNK2019: unresolved external symbol _TEKTRONIX_VB_TEKPRINTLIB_TEKNEWPAG referenced in function _PDD_NEWPAG

1>TEKTRONIX_WIN.LIB(TD_TCSDD_WIN.obj) : error LNK2019: unresolved external symbol _TEKTRONIX_VB_TEKPRINTLIB_TEKSETCOLOR referenced in function _PDD_SETCLR

1>TEKTRONIX_WIN.LIB(TD_TCSDD_WIN.obj) : error LNK2019: unresolved external symbol _TEKTRONIX_VB_TEKPRINTLIB_TEKMOVE referenced in function _TDD_PCHAR

1>TEKTRONIX_WIN.LIB(TD_TCSDD_WIN.obj) : error LNK2019: unresolved external symbol _TEKTRONIX_VB_TEKPRINTLIB_TEKCHAR referenced in function _TDD_PCHAR

1>TEKTRONIX_WIN.LIB(TD_TCSDD_WIN.obj) : error LNK2019: unresolved external symbol _TEKTRONIX_VB_TEKPRINTLIB_TEKDRAW referenced in function _TDD_PDRAW

1>Release/BH_PLOT.exe : fatal error LNK1120: 8 unresolved externals

1>

1>Build log written to "file://D:\T_HARNED\Software_Development\FEA_Code\Work\BH_PLOT\Release\BuildLog.htm"

1>BH_PLOT - 9 error(s), 0 warning(s)

========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========


To recap, under CVF the following worked:

This call :Call Tektronix_VB_TekPrintLib_TekRelease(Object)
With a module created by CVF:

SUBROUTINE Tektronix_VB_TekPrintLib_TekRelease($OBJECT, $STATUS)

!DEC$ ATTRIBUTES DLLEXPORT :: Tektronix_VB_TekPrintLib_TekRelease

IMPLICIT NONE

INTEGER*4, INTENT(IN) :: $OBJECT ! Object Pointer

!DEC$ ATTRIBUTES VALUE :: $OBJECT

INTEGER*4, INTENT(OUT), OPTIONAL :: $STATUS ! Method status

!DEC$ ATTRIBUTES REFERENCE :: $STATUS

INTEGER*4 $$STATUS

INTEGER*4 invokeargs

invokeargs = AUTOALLOCATEINVOKEARGS()

$$STATUS = AUTOINVOKE($OBJECT, 1610809346, invokeargs)

IF (PRESENT($STATUS)) $STATUS = $$STATUS

CALL AUTODEALLOCATEINVOKEARGS (invokeargs)

END SUBROUTINE Tektronix_VB_TekPrintLib_TekRelease


There are 3 check boxes in the IVF Module wizard. I've created modules with all possible combinations. (I shortened the names to make things easier during debug.) Included all in the project. No good. Here is typical module code:

MODULE Tektronix_4

USE IFWINTY

USE IFAUTO

IMPLICIT NONE

! CLSIDs

TYPE (GUID), PARAMETER :: CLSID_VB_TekPrintLib = &

GUID(#433F9025, #B49F, #11D3, &

CHAR('A2'X)//CHAR('1B'X)//CHAR('00'X)//CHAR('A0'X)// &

CHAR('24'X)//CHAR('9C'X)//CHAR('A9'X)//CHAR('17'X))

! Module Procedures

CONTAINS

SUBROUTINE $VB_TekPrintLib_TekRelease($OBJECT, $STATUS)

!DEC$ ATTRIBUTES DLLEXPORT :: $VB_TekPrintLib_TekRelease

IMPLICIT NONE

INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! Object Pointer

!DEC$ ATTRIBUTES VALUE :: $OBJECT

INTEGER(4), INTENT(OUT), OPTIONAL :: $STATUS ! Method status

!DEC$ ATTRIBUTES REFERENCE :: $STATUS

INTEGER(4) $$STATUS

INTEGER(INT_PTR_KIND()) invokeargs

invokeargs = AUTOALLOCATEINVOKEARGS()

$$STATUS = AUTOINVOKE($OBJECT, 1610809346, invokeargs)

IF (PRESENT($STATUS)) $STATUS = $$STATUS

CALL AUTODEALLOCATEINVOKEARGS (invokeargs)

END SUBROUTINE $VB_TekPrintLib_TekRelease

I've tried several calls, here is an example:
Call TekPrintLib_TekRelease(Object)

I would love any help.

Thanks,
Tim

0 Kudos
Steven_L_Intel1
Employee
2,650 Views
Tim,

I can't figure it out based on fragments of the application. Can you attach a ZIP of the project (after a Clean is done)? Or file through Intel Premier Support if you would prefer - ask that it be assigned to me.
0 Kudos
IDZ_A_Intel
Employee
2,650 Views
Make sure your .DLL is 'COM visible'.
Have you correctly generated and registered your type library on Windows? e.g.

REGASM /TLB /CODEBASE yourlibrary.dll

Then use the IVF Module Wizard on the Type library to generate the necessary modules required to define interfaces to the DLL code. You appear to be using Automation and creating Compiler EXPORT directives.
I would recommend trying generating COM interfaces and using those in your library calls and see what happens.

By registering the DLL Windows should be able to find it when required.

On further reading, it would appear that you are generating a FORTRAN library TEKTRONIX_WIN.LIB containing wrapper functions that call the Module functions and you call this Fortran library from your console program using functions with names such as _PDD_FINITT, and _PDD_INITT, is that correct? What is with the DLLEXPORT directives?

If you use the IVF-generated module interfaces, then you must call procedures with the names as given in that module, for example

INTEGER(4) FUNCTION $$VB_TekPrintLib_TekBorder($OBJECT)

which in turns calls a FUNCTION $VB_TekPrintLib_TekBorder($OBJECT) whose Interface
is given in the same module and the pointer to which is generated by the module procedure code from the pointer to the object, $OBJECT.

INTEGER(4) FUNCTION $$VB_TekPrintLib_TekMove($OBJECT, Xnew, Ynew)
which in turn calls $VB_TekPrintLib_TekMove($OBJECT, Xnew, Ynew) etc.

I also note that you are CALLing SUBROUTINES such as Call Tektronix_VB_TekPrintLib_TekNewpag(Object),
when your module creates FUNCTION $VB_Tektronix_VB_TekPrintLib_TekNewpag($Object) interfaces. Unless you are using wrapper routines such as
Tektronix_VB_TekPrintLib_TekNewpag(Object) to reference FUNCTIONs such as
$$VB_Tektronix_VB_TekPrintLib_TekNewpag($Object), perhaps there is your problem?

0 Kudos
Timothy_Harned
Beginner
2,650 Views
Steve,

I already realized I need to make a simple stripper program that jumps to the heart of the problem. (Skips the numerous libraries etc.) I will try that and hopefully be able to send you something much simpler in a day or two.

Thanks for yor help,

Tim
0 Kudos
Timothy_Harned
Beginner
2,650 Views
Hi,

I did not use REGASM. The DLL was created in VB6 under XP. I had created a setup package using VB6's deployment tool. I have run that setup on my Windows 7 machine I'm currently working on (withVS2010 and IVF 12).

The IVF12 Module Wizard does find the DLL in question. I have generated the modules. 6 of them in fact using all the various combinations of check boxes in the Module wizard.


Here is the call the worked in CVF:
Call Tektronix_VB_TekPrintLib_TekRelease(Object)
With the module CVF created: (Module named Tektronix_VB_TekPrintLib)

SUBROUTINE Tektronix_VB_TekPrintLib_TekRelease($OBJECT, $STATUS)

!DEC$ ATTRIBUTES DLLEXPORT :: Tektronix_VB_TekPrintLib_TekRelease

IMPLICIT NONE

INTEGER*4, INTENT(IN) :: $OBJECT ! Object Pointer

!DEC$ ATTRIBUTES VALUE :: $OBJECT

INTEGER*4, INTENT(OUT), OPTIONAL :: $STATUS ! Method status

!DEC$ ATTRIBUTES REFERENCE :: $STATUS

INTEGER*4 $$STATUS

INTEGER*4 invokeargs

invokeargs = AUTOALLOCATEINVOKEARGS()

$$STATUS = AUTOINVOKE($OBJECT, 1610809346, invokeargs)

IF (PRESENT($STATUS)) $STATUS = $$STATUS

CALL AUTODEALLOCATEINVOKEARGS (invokeargs)

END SUBROUTINE Tektronix_VB_TekPrintLib_TekRelease



Here is the call I'm trying to use with IVF: (I've tried several variations without sucess)
Call TekPrintLib_TekRelease(Object)
With the module IVF created:(Module maned Tektronix_4)

SUBROUTINE $VB_TekPrintLib_TekRelease($OBJECT, $STATUS)

!DEC$ ATTRIBUTES DLLEXPORT :: $VB_TekPrintLib_TekRelease

IMPLICIT NONE

INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! Object Pointer

!DEC$ ATTRIBUTES VALUE :: $OBJECT

INTEGER(4), INTENT(OUT), OPTIONAL :: $STATUS ! Method status

!DEC$ ATTRIBUTES REFERENCE :: $STATUS

INTEGER(4) $$STATUS

INTEGER(INT_PTR_KIND()) invokeargs

invokeargs = AUTOALLOCATEINVOKEARGS()

$$STATUS = AUTOINVOKE($OBJECT, 1610809346, invokeargs)

IF (PRESENT($STATUS)) $STATUS = $$STATUS

CALL AUTODEALLOCATEINVOKEARGS (invokeargs)

END SUBROUTINE $VB_TekPrintLib_TekRelease

Because I used the wizard to migrate the projects from CVF to IVF I was using CVF calling convention. I've also tried "default"

Thanks,
Tim

0 Kudos
Timothy_Harned
Beginner
2,650 Views
Hi,

I did not use REGASM. The DLL was created in VB6 under XP. I had created a setup package using VB6's deployment tool. I have run that setup on my Windows 7 machine I'm currently working on (withVS2010 and IVF 12).

The IVF12 Module Wizard does find the DLL in question. I have generated the modules. 6 of them in fact using all the various combinations of check boxes in the Module wizard.


Here is the call the worked in CVF:
Call Tektronix_VB_TekPrintLib_TekRelease(Object)
With the module CVF created: (Module named Tektronix_VB_TekPrintLib)

SUBROUTINE Tektronix_VB_TekPrintLib_TekRelease($OBJECT, $STATUS)

!DEC$ ATTRIBUTES DLLEXPORT :: Tektronix_VB_TekPrintLib_TekRelease

IMPLICIT NONE

INTEGER*4, INTENT(IN) :: $OBJECT ! Object Pointer

!DEC$ ATTRIBUTES VALUE :: $OBJECT

INTEGER*4, INTENT(OUT), OPTIONAL :: $STATUS ! Method status

!DEC$ ATTRIBUTES REFERENCE :: $STATUS

INTEGER*4 $$STATUS

INTEGER*4 invokeargs

invokeargs = AUTOALLOCATEINVOKEARGS()

$$STATUS = AUTOINVOKE($OBJECT, 1610809346, invokeargs)

IF (PRESENT($STATUS)) $STATUS = $$STATUS

CALL AUTODEALLOCATEINVOKEARGS (invokeargs)

END SUBROUTINE Tektronix_VB_TekPrintLib_TekRelease



Here is the call I'm trying to use with IVF: (I've tried several variations without sucess)
Call TekPrintLib_TekRelease(Object)
With the module IVF created:(Module maned Tektronix_4)

SUBROUTINE $VB_TekPrintLib_TekRelease($OBJECT, $STATUS)

!DEC$ ATTRIBUTES DLLEXPORT :: $VB_TekPrintLib_TekRelease

IMPLICIT NONE

INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! Object Pointer

!DEC$ ATTRIBUTES VALUE :: $OBJECT

INTEGER(4), INTENT(OUT), OPTIONAL :: $STATUS ! Method status

!DEC$ ATTRIBUTES REFERENCE :: $STATUS

INTEGER(4) $$STATUS

INTEGER(INT_PTR_KIND()) invokeargs

invokeargs = AUTOALLOCATEINVOKEARGS()

$$STATUS = AUTOINVOKE($OBJECT, 1610809346, invokeargs)

IF (PRESENT($STATUS)) $STATUS = $$STATUS

CALL AUTODEALLOCATEINVOKEARGS (invokeargs)

END SUBROUTINE $VB_TekPrintLib_TekRelease

Because I used the wizard to migrate the projects from CVF to IVF I was using CVF calling convention. I've also tried "default"

Thanks,
Tim

0 Kudos
IDZ_A_Intel
Employee
2,650 Views
If you are using the IVF-generated module, then surely your

unresolved external symbol _TEKTRONIX_VB_TEKPRINTLIB_TEKMOVE@12

is because you should either be calling the procedure $$VB_TEKPRINTLIB_TEKMOVE or referencing the FUNCTION $$VB_TEKPRINTLIB_TEKMOVE?
0 Kudos
Steven_L_Intel1
Employee
2,650 Views
Anthony, that is not correct. There is much more to the code than what has been posted so far. When I get a complete example, I'll be able to tell more.
0 Kudos
Timothy_Harned
Beginner
2,650 Views

Hi, Steve,

Im all set. I made a little small program that called the offending routines directly (no library) all in the same file. It made it much easier to debug. IVF module wizard uses a different naming convention compared to CVF for the wrapper problem. It turned out to be a simple issue but I had to get out the wire brush and take some rust off my brain.

I did not figure out why I couldnt use the module originally created by CVF.

Thanks,

Tim

0 Kudos
Timothy_Harned
Beginner
2,650 Views
Hi Anthony,

Please see my response to Steve. You did help point me in the correct direction. I was getting tangled up in the different naming conventions used by Module Wizards in CVF and IVF. A simple test case allowed me to focus on the actual problem. I never did figure out why I could not use the CVF created module in IVF. But there is more to the naming conventions than I completely understand.

Thanks for taking a look at it.

Tim

0 Kudos
Reply