How to link Fortran exe with Fortran DLL? - dll

I want to link my Fortran code with this Fortran made DLL.
In simple way...
Fortran program (editable code) --LINK-- Fortran DLL (uneditable) (linking method via Fortran program code??)
I want to make a program where I do not want to show my codes (this part will be in DLL form).
For example:
i have a code for DLL in intel fortran that is
SUBROUTINE TWICE(x,y)
IMPLICIT NONE
!DEC$ ATTRIBUTES DLLEXPORT::TWICE
REAL, INTENT(IN) :: x
REAL, INTENT(OUT) :: y
y=2*x
END SUBROUTINE TWICE
now I want to use this DLL in another program .
The new program is separate program and I want to use this DLL in the
Intel fortran written below.
PROGRAM TestToCallDLL
IMPLICIT NONE
!DEC$ ATTRIBUTES DLLIMPORT::TWICE
REAL :: x,y
WRITE(*,*)'x?'
READ(*,*)x
CALL Twice(x,y)
WRITE(*,*)'x twice = ',y
END PROGRAM TestToCallDLL
The error is:
Error 1 error LNK2019: unresolved external symbol __imp__TWICE referenced in function _MAIN__ twiceTEST.obj
Error 2 fatal error LNK1120: 1 unresolved externals Debug\twiceTEST.exe

The .LIB file generated by the compiler when creating the .DLL must be used during linking. Add it as a dependency. You can also copy it to the new project directory.
See Calling Fortran DLL from C++ using Visual Studio 2008 in the Intel Fortran for Windows support forum for more.

Related

MPLAB X XC8 Error: (500) Undefined Symbols

Im using MPLAB X v5.25 and XC8 v2.10
When building my code, I encounter an error that says error: (500) Undefined symbols
and enumerates certain functions that are contained in other C files linked with headers.
*:0:: error: (500) undefined symbols:
_OneWireTemp(dist/default/production\firstpic.X.production.o)
_sending(dist/default/production\firstpic.X.production.o)
_USART_Init(dist/default/production\firstpic.X.production.o)
(908) exit status = 1*
The functions are from the one wire library, HTTP GPRS library and USART library.
Any help would be appreciated
[...] other C files linked with headers. [...]
Header files do not link C files - they simply declare symbols. You get undefined symbols when the linker cannot match the symbols referenced in the code it has been asked to link. The most likely cause being that you have not actually linked the object code for each C file that the compiler compiled.
That is to say, each C file must be separately compiled to create an object file. The purpose of the headers in this process is to make visible to the compiler the symbols that will be defined in separate object files.
The object files generated by separate compilation are then passed to the linker which resolves the external references in one object file with definitions provided in other object files (or static libraries included in the link).
It is the linker that is issuing the undefined symbols diagnostic, almost certainly because you have not separately compiled the C files and passed the generated object code to the linker.
In most IDEs (and I don't believe MPLAB X is any different), you add the C source files to a "project", and the IDE's project manager will manage the separate compilation and linking for you. So it is likely that you have simply omitted to add the C sources to your project. No amount of header file inclusion is going to solve this issue, header files are included by the pre-processor (before compilation and linking).

Including headers from an unmanaged C++ code inside C++/CLI code

I'm writing a CLR wrapper for an unmanaged C++ library.
There are two files I'm including from the unmanaged lib:
//MyCLIWrapper.h
#include "C:\PATH\TO\UNMANAGED\Header.h"
#include "C:\PATH\TO\UNMANAGED\Body.cpp"
Then I'm writing CLI implementations for the unmanaged library functions:
//MyCLIWrapper.h
// includes ...
void MyCLIWrapper::ManagedFunction()
{
UnmanagedFunction(); // this function is called successfuly
}
However, if my Unmanaged function contains calls to other functions that are defined in other unmanaged header files. This causes a compiler linkage error.
If I add includes to the unmanaged headers that define these functions, my errors get resolved. However, there is a lot of functions, and a lot of includes required.
Is there a different way to approach this?
EDIT:
P.S.
My managed code is in a separate Visual Studio project (output - DLL), and the compile settings are set to /CLR. Unmanaged code is in a separate Win32 project (output - DLL).
Also, after more research I concluded that theoretically I could set my Win32 unmanaged project to CLR and just add my managed classes and headers in there as an entry point, and then it would all compile into a single DLL file. That would probably solve (?) the linkage errors. However, I would prefer to preserve the loose coupling as well as the additional series of problems that can raise from setting my unmanaged project to CLR.
EDIT #2:
The unmanaged class that I'm referencing (body.cpp, header.h) contains includes to the required files that define the functions that are causing the problems. However, my managed code doesn't pick up on the includes that are in the unmanaged body.cpp and header.h.
Linker errors are a different kettle of fish from compiler errors. You forgot to document the exact linker errors you see, but a very common mishap when you compile code with /clr in effect is that the default calling convention for non-C++ member function changes. The default is __clrcall, a convention that's optimized for managed code. While functions compiled without /clr defaults to __cdecl. Which changes the way the function name is mangled. You see this back in the linker error message, is shows that it is looking for a __clrcall function and can't find it.
You'll need to either explicitly declare your functions in the .h file with __cdecl. Or tell the compiler that these functions are not managed code. Which is the best way to tackle it:
#pragma managed(push, off)
#include "unmanagedHeader.h"
#pragma managed(pop)
Solution was fairly simple:
I added both unmanaged and managed projects to a single solution in Visual Studio.
Set the unmanaged project's "Configuration Type" to "Static Library" (.lib).
Right click on the managed project -> References -> Add Reference -> Projects -> -> Add Reference.
Then in my managed class, I include the header.h (only) just like I did in my question.
Compiled successfully!
Thank you

Errors using the glut library with C++/CLI

I've been using OpenGL with glut for quite a while now and have never encountered this issue.
I've been trying to include the glut library in my c++/cli project for the use of it's library functions like glutMouseFunc etc. My project already uses gl.h and glu.h. However the moment I include:
#include <gl/glut.h>
I get the following string of error messages.
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\gl/glut.h(490): error C3641: 'glutInit_ATEXIT_HACK' : invalid calling convention '__stdcall ' for function compiled with /clr:pure or /clr:safe
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\gl/glut.h(490): error C2664: '__glutInitWithExit' : cannot convert parameter 3 from 'void (__cdecl *)(int)' to 'void (__cdecl *)(int)'
1> Address of a function yields __clrcall calling convention in /clr:pure and /clr:safe; consider using __clrcall in target type
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\gl/glut.h(507): error C3641: 'glutCreateWindow_ATEXIT_HACK' : invalid calling convention '__stdcall ' for function compiled with /clr:pure or /clr:safe
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\gl/glut.h(507): error C2664: '__glutCreateWindowWithExit' : cannot convert parameter 2 from 'void (__cdecl *)(int)' to 'void (__cdecl *)(int)'
1> Address of a function yields __clrcall calling convention in /clr:pure and /clr:safe; consider using __clrcall in target type
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\gl/glut.h(553): error C3641: 'glutCreateMenu_ATEXIT_HACK' : invalid calling convention '__stdcall ' for function compiled with /clr:pure or /clr:safe
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\gl/glut.h(553): error C2664: '__glutCreateMenuWithExit' : cannot convert parameter 2 from 'void (__cdecl *)(int)' to 'void (__cdecl *)(int)'
1> Address of a function yields __clrcall calling convention in /clr:pure and /clr:safe; consider using __clrcall in target type
I've read in a few other places that similar problems have been solved by switching the clr support in the project's properties (properties>configuration properties>general>common language runtime support) to anything that's not clr:safe or clr:pure.
I've in fact tried compiling with all 4 available versions of clr support:
Common Language runtime support (/clr)
Pure MSIL Common Language Runtime Support (/clr:pure)
Safe MSIL Common Language Runtime Support (/clr:safe)
Common Language Runtime Support, Old Syntax (/clr:oldSyntax)
However I still receive the same error message. I've no idea where this issue comes from. I've used glut in other projects (c++ only), and never encountered this problem until i started using c++/cli.
Any insight into what this could be would be greatly appreciated.
Thanks in advance,
Guy
(By the way, I'm using Visual Studio 2010 if it turns out to be of any relevance.)
The error message you're displaying will not occur if using /clr to compile a file, only /clr:pure or /clr:safe.
You definitely need to use /clr, and not use /clr:pure or /clr:safe, as the latter flags will not allow you to use native code at all within the .cpp file. Make sure you don't have a single file overriding the project settings for /clr, either, as this can cause the compiler to create errors such as you're displaying for those files.
You'll need to let the compiler know that glut.h is a header for unmanaged code. If it doesn't know then it will assume that is contains managed functions and it doesn't like what it sees. You do so like this:
#pragma managed(push, off)
#include <gl/glut.h>
#pragma managed(pop)
A more general way to keep out of trouble like this is by strictly separating the C++/CLI code from the native code. You can turn on the /clr option for individual source files, it doesn't need to be turned on for every source code file in your project. This also helps to get native code compiled to machine code instead of IL, it is faster that way.

Linker error when calling function in native C++ from a c++/cli project

I am trying to call functions in c++ from C# and to do this, I created a C++/CLI project to wrap C++ codes.
My code compiles, but during linkage, I am getting error that linker can not find methods which are defined in c++ code.
The c++ code is a static library and I add a reference to it in C++/CLI project (common properties -> framework and references -> add new reference)
My questions:
Is there anything else should I do?
is adding reference in this sections means that the reference is a .net assembly? Or could it be a reference to a static library.
Edit 1
I am sing VS 2012 on windows 7 64bit
Linker Error:
Error 3 error LNK2019: unresolved external symbol "public: static class MyFile __cdecl MyFile::ReadMyFile(char *)" (?ReadMyFile#MyFile##$$FSA?AV1#PAD#Z) referenced in function "public: static class MyFileWrapper::MyFileWrapper ^ __clrcall MyFileWrapper::MyFileWrapper::ReadMyFile(class System::String ^)" (?ReadMyFile#MyFileWrapper#1#$$FSMP$AAV11#P$AAVString#System###Z) MyFileWrapper.obj
You didn't post the linker error message, that makes it difficult to answer this question accurately. The most common causes:
Forgetting to tell the compiler that the function is a native function and not a managed one. You can tell from the linker error message when you see it using the __clrcall calling convention, native code normally uses the __cdecl calling convention. You fix that by putting #pragma managed(push, off) before the #include, #pragma managed(pop) after it.
Trying to link a static library that was compiled with /clr in effect. That's not supported without otherwise drawing a complaint about that when you build the library, unfortunately. The equivalent is already well supported by the CLR, it binds libraries at runtime. You fix that by creating a class library project instead so you'll get a DLL after building it. Use Add Reference to import the declarations from that assembly instead of using #include.
Forgetting to tell the linker that it needs to link an unmanaged static library or import library. Using Add Reference is supported in VS2010 and up, on earlier versions of VS you need to use the Linker, Input, Additional Dependencies setting or use #pragma comment(lib, "name") in your source code.
$$F part of the given mangled name is a marker of function modifier , that means managed function [Managed C++ or C++/CLI], according to "Visual C++ name mangling".
I faced very similar problem. I figured out that in my case there was:
<ProjectReference Include="ProjName\ProjName.vcxproj">
<ProjectReference Include="..\ProjName\ProjName.vcxproj">
I've just fixed that and made rebuild and it helped me.

Debugging VB6 dll from VB6 exe

I have a VB6 program that calls a VB6 DLL which in turn calls another VB6 DLL. When I execute the calling program there is an application error which I am unable to pinpoint so I researched how if it was possible to "see" the error in the dll.
I read Stackoverflow entry question about debugging VB6 dll
and followed the directions of Booji Boy to create a vbg. I also followed his directions and removed the two DLLs from he Reference list. The calling program takes a .txt file as input. When I executed the exe I received this error:
Error Number: 13Description: Type mismatch
The error isn't being generated by the application.
What does this mean? How can I debug this issue?
You must have all the source code for the EXE and the two DLLs. You add all the projects into single group file i.e. the VBG. You must have a reference in the EXE project to the first DLL. I have no idea why you have been told you have to remove them. You must have a reference in the first DLL project to the second DLL project. VB is clever enough to silently replace the DLL reference with the project reference. It is also clever enough to silently replace the project reference with the DLL reference if you remove a DLL project from the project group.
Make sure you have error handling set to "Break on All Errors" or "Break in Class".
The type mismatch error can occur from simple things like assign a non-numeric string to an numeric variable. It gets more complicated if you are passing object references around. If you see this error occurs on something like:
Set myObject = someOtherObject
... and it looks as if they should be the same type, this might get very complicated. But first, I'll let you do the debug.
You can use an open source project made in Visual Basic 6.0. It is called "Debuggy v2".This project has multiple roles:
-debugger
-disassembler
-Windows resource extractor
-file hex editor
-window sniffer
-API spy
all rolled into one. I may be useful for what you need.
When starting to work in a VBG a type mismatch can arise if the library references are inconsistent. One library may be referencing another IN the VBG; a second may be referencing the compiled version. Passing objects between them can result in this error.
Concrete example:
VBG contains code for: A.DLL, B.DLL, C.DLL
A references B in the VBG
C references B which is compiled
Code in A calls code in C passing an object defined by a class in B.
Type mismatch
C should have referenced B in the VBG.