Using module (.mod) files

Using module (.mod) files

I wanted to use the .mod files to other projects which are created ina project . I followed the steps described in this link(examples too, actually). However, Igot linking errors (error LNK2019: unresolved external symbol...). I also tried to put the .mod files in another directory using /module:path option andlocating itwith /I compileroption in another project, but no avail. Surprisingly, I was successful to compile and run the second project atonce using the above approach.I think it was successful when both .mod and .obj filesof the moduleswere there. Later, I didn't find .obj files, andthat could be reason ofthe error LNK2019, I think.

Would appreciate your suggestions.

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

When a source file containing module declaration is compiled, a .MOD file and a .OBJ file are produced. The .MOD files are used by the compiler when compiling other subprograms that USE the modules. At link time, the .OBJ files produced earlier must be included. If some of the .MOD files and .OBJ files are from another project, you have to tell the compiler where to find the .MOD files (during compilation) and you have to tell the linker which .OBJ files to link.

Merely including .MOD files in the project does not tell the linker to use the corresponding .OBJ files; it complicates matters that the count and names of .MOD files and .OBJ files may not match.

Thank you mecej4. I understand it,butthe .OBJ files from modules are missing from project ONE now ( I don't see them). Before, I can see both the generated .MOD and .OBJ files (of module) in project ONE.The project ONE still compiles and runs fine; project TWO fails.I also tried to linkthe project TWO directly with DEBUG/RELEASE directory of project ONE and removing the /module:path option from project ONE. There are only .MOD files in both the DEBUG/RELEASE folder of project ONEthat I can see now.

In another case, there are both .MOD and .OBJ files from modules in project ONE, yet the second project in another directory shows LNK2019 errors upon using USE modules assocation. One thing I didnot understand is that the second project compiled/linked fine for a few initial runs. Afer I made some changes in the code, CLEANed the BUILD and REBUILD, the LNK2019 errors started to appear.

Did you change the output or intermediate directory of one project to be that of the other? If so, don't do that and put it back.

My recommended way of using modules from a separate project is to make the "module" project a static library (or DLL) and then make the library project a dependent of the executable project. In version 11.1 and earlier you would also need to add the output directory of the library project to the "Additional Include Paths" of the parent, but as of version 12 that is done automatically.

Retired 12/31/2016

Dear Steve,

No, I didn't touch the output or intermediate directory. However, I tried both options with module path to a new separate folder (NOT to the second project) and without specifying it in the first project. In the second project, I had used "Additional Include Directories" to the directory where .MOD files of the first project exist.

That means, would you say that if I needed to pass a part of the source codeto the third person, but I do not want to disclose the source code to him/her, the recommended way is only the DLL?

You can provide the DLL, the export .LIB that gets created with it and the .MOD files. You don't need to provide source.

Retired 12/31/2016

DLL and .LIB are fine. I have worked withDLL before. But, .MOD is causing problems; hence, I am not that comfortable with it.Ok, I'll try.

Thank you.
Krishna

MOD files need to be provided to the users of your code only if the code that they write to call your DLL will include USE statements for those modules. If the modules contain only interface declarations and no public variables, your users can be told to avoid USE statements, but they will have to write subroutine calls and function invocations with the correct calling sequence.

If any of the routines arguments are allocatable or optional, they will need to provide correct interfaces to the DLL routines. I don't see why you would object to giving them source code to only the interfaces to your routines that they are supposed to call.

Thank you mecej4. Appreciate your advice. Will reportyou (or forum) later if I get any trouble.

Many thanks to you and Steve!

I'm having trouble with this as well. I have a project where I have a static library called by a console app (two separate projects in the same solution). I'm getting the same link error 2019. I've tried the following:

Added the static library debug directory to the Fortran general properties "Additional Include Directories" field of the console app project.
Added the static library debug directory to the Linker generalproperties "AdditionalLibrary Directories" field of the console app project.
Added the static library file name to the Linker input properties "Additional Dependencies" field of the console app project.

The static library was written by someone else and has only .FOR files and no module declarations. So I don't include any modules with a USE statement in my console app project.

Is how I should be including the static library in my console app? Does anyone have any ideas of why I'm getting a link error?

Thanks
Craig

Craig,

What you've done should work, though there is an easier approach - making the library project a "dependent" of the executable. However, if you are still getting unresolved symbol references, there is more at issue. Please shoe the full text of at most three of these messages. Could it be that your project and the library project have different settings under "External procedures", such as one using CVF conventions and one not?

Retired 12/31/2016

Steve
Actually I have declared the static library as a dependent of the .exe. This didn't seem to change anything other than the order they are compiled in and it alone didn't work so that's why I tried the approach mentioned above. Is there anything in the properties it shouldhave changed? I'm pretty new to these linking and compiler settings so I'm sure I just don't know what all to look at. I created both projects in IVF and they both have default settings under the"external procedures" properties. As I said I didn't write the static library source files so I don't know if there could be some preprocessor directives that would cause problems.

Below are two errors. The others are the similar just for different function calls.

Error 3 error LNK2019: unresolved external symbol __imp__SETMIX referenced in function _TRANSCOREFIG TRANSCOR2.obj

Error 4 error LNK2019: unresolved external symbol __imp__SATP referenced in function _TRANSCOREFIG TRANSCOR2.obj

Thanks for the help.
Craig

Specifying "Additional Include Directories" only tells the compiler where to look for include and module files. Unless there is an INCLUDE or USE statement that cannot be satisfied by looking in the standard places, there is no need for the compiler to use the information provided, as is true in your case, since the source for that static library does not declare any modules.

If you can show the contents of the build log produced by a failed (because of linker errors) build, we could pin down the problem; without the necessary information, there are many different reasons for the link to fail, which we need not go into. In essence, was the library built before the linking attempt, and does the library contain all the external symbols needed?

Providing more information helps. Your main program is trying to call routines it thinks are in a DLL - that have been declared (in the caller) with !DEC$ ATTRIBUTES DLLIMPORT. If what you have is actually a static library and not a DLL export library, that would explain the errors.

Retired 12/31/2016

There are no !DEC$ ATTRIBUTES DLLIMPORT statements in my code. There are however !DEC$ ATTRIBUTES DLLEXPORT statements.

The following might be a clue from the build log. Why is it trying to create a .lib file? This is from my console app build log?

Link: executing 'link'

Creating library C:\Documents and Settings\chickman2\My Documents\Visual Studio 2005\Projects\MCCCv2.1\MCCCv2.1\debug\mcccv2.1.lib and object C:\Documents and Settings\chickman2\My Documents\Visual Studio 2005\Projects\MCCCv2.1\MCCCv2.1\debug\mcccv2.1.exp

MC3MAIN.obj : warning LNK4217: locally defined symbol _MC3CALC imported in function _COIL_FILE

TRANSCOR2.obj : error LNK2019: unresolved external symbol __imp__SETMIX referenced in function _TRANSCOREFIG

There are more errors that are similar to this error.

Do I need include statements for the .lib file in my console app? Does the .lib file need to be added to my console app project somewhere or should adding it in the properties as an additional dependency be enough?
Thanks
craig

If you have a module with DLLEXPORT directives and then USE that module, they turn into DLLIMPORT directives. Your "static library" project is in fact a DLL project, which makes more sense. This will create an export library which should then be linked into the parent executable. This should happen if it is a dependent project.

The LNK4217 warning can be ignored.

Please attach the buildlog.htm from the executable project after a failed build.

Retired 12/31/2016

Attached is my buildlog.

Thanks
Craig

Attachments: 

AttachmentSize
Downloadtext/html BuildLog.htm8.58 KB

You have two different (I think) refpropv9.0.lib files listed in the link step. One of them appears to be one you added as a "source file" to the project. Not entirely sure where the other one comes from. Is this the library that is supposed to resolve these symbols? Can you attach the library to a reply here? It should be relatively small if it is DLL export library.

Retired 12/31/2016

Unfortunately the library was purchased and I don't think I should post it here. I wouldn't want to get my company into any legal issues. It's about 27 source files. Not sure how many lines of code.

That might make since becasue I think at one point I had added the .lib file to the project not in the source files folder but just a general file.It has been removed from the poject so I'm not sure why it would still be trying to link to both.

I guess I'm trying to figure out the correct way of doing this. Would that have been an ok way of doing it? What's the technically correct way or does it matter? And is there a way I can get the linker to stop looking at both? Is there any other information that would help short of providing the entire library?

One other question. Is there documentation on theprepocessor directives such as !DEC$ ATTRIBUTES DLLIMPORT? I've seen several of them in examples but haven't found documentation for all the options.

Thanks
Craig

Steve
Here's the source of the two REFPROPv9.0.lib references in the buildlog. I tried compiling with different options and looked at the buildlog to figure this out.

1st instance
From adding the static library file name to the Linker input properties "Additional Dependencies" field of the console app project

2nd instance
From changing the Project Dependencies

I've tried compiling with different combinations of these with no luck. What are your thoughts?

Thanks
Craig

I don't see the sources. Can you just zip up the whole solution and attach it? Do a Build > Clean Solution first.

Retired 12/31/2016

Oh sorry my message wasn't clear. I meant that I found the reason the static lib is in there twice and where they come from (source). Oneis in there becasue of adding the static library file name to the Linker input properties and the other from changing the Project Dependencies.

I can't attach the source code because it is proprietary. I understand if this isn't enough info to diagnose the problem but let me know if there's anything else I might be able to provide that would help.

Even if there isn't enough info could you try to answer my general questions in post 19?
Thanks
Craig

All of the !DEC$ directives are documented in the Language Reference part of the on-disk documentation. Read the chapter on "Directive Enhanced Compilation". (That's what we tell the Intel VPs that DEC stands for...) You can also look at ATTRIBUTES under the "A-Z Reference" section. Or perhaps even better, place the cursor on an ATTRIBUTES directive and press F1.

Retired 12/31/2016

Let me restate a few things to see if it helps.

There are two types of "library" projects, static libraries which ONLY output a .LIB, and dynamic (DLL) libraries which output a .DLL, a .EXP (which you can ignore) and a .LIB. This .LIB is an "export library" which contains no code but provides the linker something to connect to.

When building a DLL, you must "export" one or more names, or else nobody can call the routines in the DLL. This is done, in Fortran, with an ATTRIBUTES DLLEXPORT directive in the scope where the thing to be exported is declared (usually inside routines, though variables and COMMON blocks can also be exported.

Each name that is exported gets a corresponding entry in the export library with a __imp_ prefix supplied by the linker.

When you want to call a routine in a DLL, the normal way is to have a corresponding ATTRIBUTES DLLIMPORT directive which says "this name comes from a DLL". This makes the linker look for the __imp_ name in an export library. As it happens, you don't HAVE to do this for routines. You can omit the DLLIMPORT and the linker will find the entry in the export library, but each time you call there will be a few extra instructions executed. (For variables, you must have the directive.)

We do a useful thing with Fortran modules - if you have a module that contains things with DLLEXPORT directives, and then USE the module, we convert those into DLLIMPORTs. So the caller doesn't need to explicitly add DLLIMPORT directives if they USE the module. If you also use the module in the process of building the DLL, the linker will gripe about a locally defined symbol that was imported, but that is harmless and can be ignored.

Does this help at all?

Retired 12/31/2016

Yes this definitely helped explain things. So is the problemthat I have dllexport statements but am trying to create a static library and since I don't have dllimport statements it has trouble with the __imp_ prefix symbols?

It also sounds like if I was using modules with a USE statement it might take care of the issue. Is that what you are getting at with the last paragraph?

Is there a way to get the code to work as a static library without removing the dllexport statements or adding module declarations? I would prefer not to edit this 3rd party library.

Can / Should I use dllimport statements in myexecutableeven though I'm calling a static library?

Thanks again for all the help. I feel if I was a more experienced programmer this would probably be resolved by now.
Craig

If you are linking to a static library, then you should not use DLLIMPORT directives, nor should the modules you are USEing have DLLEXPORT directives. A common way of dealing with this is to conditionalize the DLLEXPORT directives based on a preprocessor symbol such as DLL that you add only to configurations that build a DLL. Note that the compiler-provided _DLL symbol isn't useful for this as it refers to which run-time libraries are being used.

Retired 12/31/2016

Steve
Thanks again for all the help and sorry to drag this out. I think I'm starting to understand the problem now regarding the dllexport directives. I have a few more questions then hopefully this will be wrapped up.

There are quite a few dllexport statements in the .lib I'm trying to make and as I mentioned this code wasn't written by me. So is there a way to make the preprocessor not look at these without adding the DLL symbol and conditional statements to each instance of dllexport?

I've gotten the .exe to compile by adding the .lib file to the project (as in right click on .exe project then select add file and select the .lib file). This as opposed to adding the library in the properties linker options.
Is there anything wrong with doing it this way?
Have you ever heard of doing this?
Do you know what is being done differently in terms of how the compiler sees it? It seems like it might be, in a way, handled more similar to just adding the source files to the .exe project rather than creating a separate .lib or .dll?

Again thanks for all the help. I think I've learned quite a bit.
Craig

Adding the .lib to the project is fine. There's no difference in how it is handled by the linker (the compiler doesn't look at .lib files). Even though you have it as a "source file" it is properly dealt with. If the .lib comes from a subproject, my usual preference is to let it be dealt with as a project dependency but that may not meet everyone's needs.

There is not an option to disable recognition of DLLEXPORT/DLLIMPORT directives.

Retired 12/31/2016

Leave a Comment

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