if i don't want dllexport all the type bound procedure, how should i do?

if i don't want dllexport all the type bound procedure, how should i do?

First, I apologize for my poor English.

Second, This is the code in Dll1

module testmod

    implicit none
           
    type :: basetype
        
        integer :: i
    contains
    
        procedure :: foo1
        procedure :: foo2
        
    end type basetype

contains

    subroutine foo1(this)
    
        class(basetype) :: this
        
    end subroutine foo1    

    subroutine foo2(this)
    
        !DEC$ ATTRIBUTES DLLEXPORT :: foo2
        class(basetype) :: this
        
    end subroutine foo2
    
end module testmod

3. This is the code in Dll2

module callmod
    use testmod
    implicit none
    
    type :: calltype
    
    contains
    
        procedure :: callfoo2
        
    end type calltype
    
contains

    subroutine callfoo2(this)
    !DEC$ ATTRIBUTES DLLEXPORT :: callfoo2
        class(calltype) :: this
        
        type(basetype) :: tBase
        !call tBase.foo2()          ! #1
        tBase.i = 2                 ! #2
        
    end subroutine callfoo2
end module callmod

4. I Promise the Dll2 can find the *.lib , *.mod and *.dll of the Dll1. The compile will success, When the Dll2 link,

1) if #1 is commeted, #2 is not. link will sucess

2) if #1 not, #2 is commented, link will fail. Output contains "error LNK2001: unresolved external symbol_TESTMOD_mp_FOO1"

5. I don't want to dllexport all the procedure bounded in the basetype, how should i do?

Thank you!

9 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

I may not have guessed correctly your compile commands. With the current compiler
Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 13.0.1.119 Build 20121008
dumpbin /symbols shows
002 00000000 SECT1 notype () External | TESTMOD.
003 00000010 SECT1 notype () External | TESTMOD_mp_FOO1
004 00000020 SECT1 notype () External | TESTMOD_mp_FOO2
005 00000030 SECT1 notype () External | CALLMOD.
006 00000040 SECT1 notype () External | CALLMOD_mp_CALLFOO2

so it seems you should not have difficulty. Prior to Fortran 2003, exporting an internal subroutine was an Intel extension, so it's possible that past compilers varied in their treatment.

The issue here has to do with DLLEXPORT. You must DLLEXPORT any procedure that may be needed when a generic or type-bound reference is made. If i understand your #2 case, you don't get an error because there is no reference (at least here) to callfoo2 from outside module callmod - but there might be from other parts of the application.

Unless you're going to make sure that a particular type-bound procedure is never referenced from outside the DLL, then you must add a DLLEXPORT directive for it.

Steve - Intel Developer Support

I really appreciate your help. Thank you!

1. Hi, TimP. My Intel Fortran version is Intel Parallel Studio XE 2011. In your platform, if you comment #2 line and uncomment #1 line, will the link success? Please do me a favor and have a try :P

2. Hi, Steve. I thought you are the expert in this forum. I view a lot of threads in this forum, your answer always hit the nail on the head. However, I have some opinion in this dllexport issue.
Assuming I have a type bounded with procedure, some of the procedure are called only by the other type bounded procedure and I don't want them to be called from outside. So I don't want dllexport them.
According to your reponse, I cann't achieve this goal, can I?

Thank you for all your help again!

Yes, you can do this. As I said, if an individual procedure is not called from outside the DLL, it doesn't need to be DLLEXPORTed. The DLLEXPORT is needed if the procedure is called from outside the DLL.

Steve - Intel Developer Support

Hi Steve, May be you can check the code below. Dll1 didn't call a type bounded procedure in Dll2, but when I link Dll1, it poped error "unresolved external symbol"

Dll2


module calledmod
    implicit none
    type :: basetype
    contains
        procedure :: foo1

        procedure :: foo2
    end type basetype
contains
    subroutine foo1(this)
        !DEC$ ATTRIBUTES DLLEXPORT :: foo1

        class(basetype) :: this

        write(*,*) "foo1"
    end subroutine foo1
    subroutine foo2(this)
        class(basetype) :: this

        write(*,*) "foo2"
    end subroutine foo2
end module calledmod

Dll1


module callmod
    use calledmod

    implicit none
    type :: calltype
        type(basetype) :: tBase
    contains
        procedure :: foo
    end type calltype
contains
    subroutine foo(this)

        !DEC$ ATTRIBUTES DLLEXPORT :: foo

        class(calltype) :: this
        call this.tBase.foo1()
    end subroutine foo
end module callmod

Interesting - I would not have expected that. I see some other strange things here and will investigate.

Steve - Intel Developer Support

I have escalated this to the developers as issue DPD200239418. I don't know a workaround other than DLLEXPORTing FOO2. You shouldn't have to do that....

Steve - Intel Developer Support

thank you!

Leave a Comment

Please sign in to add a comment. Not a member? Join today