Is there a way within an Intel Visual Fortran project to get a string representing the Visual Studio Solution Directory?
Get_Environment_Variable doesn't seem to have that ability as far as I can tell.
Intel Fortran 2017 and VS 2015.
From your other comments, it seems to me that you're possibly more interested in the directory containing the executable. If you know your solution directory structure you can work out the solution location from that.
You do this in two steps. First you call the Windows API routine GetModuleHandle, passing NULL as the argument. This returns a handle to the current executable. Then you pass this handle to GetModuleFileName which returns the path to the executable as a NUL-terminated string.
If you wanted to separate out just the path, you could use the Intel library routine SPLITPATHQQ.
Example:
program whereami
use kernel32
use, intrinsic :: ISO_C_BINDING
implicit none
integer(HANDLE) :: h
character(MAX_PATH) :: f
integer(DWORD) :: ret
h = GetModuleHandle (NULL)
ret = GetModuleFileName (h,f,len(f))
print *, f(1:index(f,C_NULL_CHAR)-1)
end program whereami
Within the property pages for an Intel Fortran project you can use the $(SolutionDir) macro to query the solution directory.
There are a number of ways to then incorporate the value of this macro into Fortran source when it is compiled (e.g. define a preprocessor symbol on the compiler command line and then reference that preprocessor symbol in the source), or pass the value of that macro to a runtime instance of your program (e.g. through a command line argument, specified via the relevant project property) when the program is started from within Visual Studio.
Related
I have defined a DLL-export as follows:
__declspec(dllexport)
DWORD WINAPI DllBootstrap(LPVOID addr) {
return 0;
}
Now, using DUMPBIN, the symbol is displayed as follows:
1 0 0001100A ?DllBootstrap##YGKPAX#Z = #ILT+5(?DllBootstrap##YGKPAX#Z)
And this is how the memory looks in Visual Studio:
ยก}....ReflectDLL.dll.?DllBootstrap##YGKPAX#Z..........................................
when inspecting PIMAGE_EXPORT_DIRECTORY.AddressOfNames.
What I need is a clean symbol, i.e., DUMPBIN should output something like:
1 0 0001100A DllBootstrap
and PIMAGE_EXPORT_DIRECTORY.AddressOfNames should point to:
DllBootstrap..........................................
How can I achieve this?
WIN32 BUILDS:
As #RbMm indicated, to retain your function name as-is and get no name decoration, you must use a .DEF file (and remove the __declspec(dllexport) specifier). Then create a DEF file with the line below and either specify it with the /DEF linker option or add it to your Visual Studio project and it will be picked up automatically by the linker:
EXPORTS DllBootstrap
If you don't want to deal with an external .DEF file and you will be using the Visual C++ compiler, the simplest way to limit decoration using just code is to declare your function with 'extern "C"'. This results in decoration including a preceding underscore and appends an "#" along with the argument's byte count in decimal. The following code for example:
extern "C" __declspec(dllexport)
DWORD WINAPI DllBootstrap(LPVOID addr) {
return 0;
}
produces an exported name of:
_DllBootstrap#4
This is how stdcall functions are decorated when C++ name-mangling is disabled with 'extern "C"'. NOTE: WINAPI maps to __stdcall. Retaining 'extern "C"' and changing the convention to __cdecl, you won't get any decoration whatsoever, but module entrypoints should generally remain stdcall as you have it listed in your sample.
If you still want to avoid a .DEF file, there is one last hack you can employ. Add the following line to your code:
#pragma comment(linker,"/EXPORT:DllBootstrap=_DllBootstrap#4")
This will pass an argument to the linker creating a new undecorated name symbol which maps to the decorated name. This isn't very clean as the original name will still exist in your DLL, but you will get your clean exported name.
WIN64 BUILDS (UPDATE):
As Hans Passant commented, for anyone using the Visual C++ 64-bit compiler, there is only the 64-bit calling convention (stdcall, cdecl, etc. keywords are ignored). While C++ mangling will still occur under this compiler, no additional decoration is made to the exported names. In this case, 'extern "C"' would be enough when the sample is compiled as C++ code; if compiled as C, no modifications would be necessary.
While attempting to use fftw3 libraries in VS2008 with Intel Fortran, I encountered a problem with the data types defined by the iso_c_binding.
Considering that fftw3 defines in fftw3.f03:
integer, parameter :: C_FFTW_R2R_KIND = C_INT32_T
When compiling a code with the line
integer(C_FFTW_R2R_KIND), dimension(*), intent(in) :: kind
I get the following error:
error #6684: This is an incorrect value for a kind type parameter in this context. [C_FFTW_R2R_KIND]
To understand the problem, I tried the following code
program test
implicit none
call sub()
contains
subroutine sub()
use, intrinsic :: iso_c_binding
implicit none
write(*,*) C_INT, C_DOUBLE , C_INT32_T, C_INT_FAST32_T, C_INT_LEAST32_T
end subroutine sub
end program test
After running, the following result is displayed:
4 8 -2 -2 -2
As -2 is not a valid data type, I assumed that was the problem and looking in https://software.intel.com/en-us/node/678431, I replaced the line in fftw3.f03 by this:
integer, parameter :: C_FFTW_R2R_KIND = 4 !C_INT32_T
And I can run the program without errors.
If anybody could confirm that this alternative is correct or how to solve the original problem I would appreciate it.
Your approach will work fine for Intel Fortran, although using SELECTED_INT_KIND(8) instead of 4 would be safer and more portable.
Intel Visual Fortran apparently uses Visual C++ as a companion C compiler. And apparently a version that does not supports these C99 types yet. AFAIK Visual C++ is more oriented towards C++ than C and does not bring new C standard features too fast. They are supported in recent versions though https://msdn.microsoft.com/en-us/library/323b6b3k.aspx
In my opinion it would be more useful for Intel Fortran to define the c_ kind values anyway even if the C compiler does not define those constants, but maybe it is not completely standard conforming. But I think it would be a useful extension.
You simply need a newer version of Intel Fortran. If you are using VS2008, you would be at most using version 14; the current version is 18 and your test program there produces the result:
4 8 4 4 4
As I see, extern WinAPI functions in assembly code have names like _ExitProcess#4.
What is the meaning of the #4 part, and how to determine what number to use after # ?
I know that this has something to do with DLL we are linking against, but in many cases it's not known what number to use after the #, and this leads to many nasty undefined reference errors.
As Andreas H answer said the number after the # is the number of bytes the function removes from stack before the function returns. This means it should be easy to determine that number, as it's the also number of bytes you need push on the stack to correctly call the function. It should be the number of PUSH instructions before the call multiplied by 4. In most cases this will also be the number of arguments passed to the function multiplied by 4.
If you want to double check that you've gotten the right number and you have Microsoft Visual Studio installed you can find the decorated symbol name from the Developer Command Prompt like this:
C:\> dumpbin /headers kernel32.lib | find "ExitProcess"
Symbol name : _ExitProcess#4
Name : ExitProcess
If you're using the MinGW compiler tools to link your assembly code, you can do this instead:
C:\> nm C:\MinGW\lib\libkernel32.a | find "ExitProcess"
00000000 I __imp__ExitProcess#4
00000000 T _ExitProcess#4
You'll need to replace C:\MinGW with the directory you installed MinGW.
Since not all Windows APIs reside in the kernel32 import library you'll need to replace kernel32 with the name of the import library given in the Windows SDK documentation for the API function you want to link to. For example, with MessageBoxA you'd need to use user32.lib with Visual Studio and libuser32.a with MinGW instead.
Note there are few rare Windows APIs that don't use the stdcall calling convention. These are functions like wsprintf that take a variable number of arguments, which the stdcall calling convention doesn't support. These functions just have an underscore _ before their names, and no # or number after. They also require that the caller remove the arguments from the stack.
The # symbol is, as the leading underscore, part of the function name when the stdcall calling convention is specified for the function.
The number specifies the number of bytes the function removes from the stack.
The compiler generates this number.
The suffix is added so that the function is not accidentally called with the wrong calling convention or the prototype in the source code specifies the wrong number or size of arguments. So the intention is to provide a means to avoid program crashes.
See also https://msdn.microsoft.com/de-de/library/zxk0tw93.aspx
If you want to get the number to use, make sure you have _NT_SYMBOL_PATH defined to the correct value.
Like:
srv*https://msdl.microsoft.com/download/symbols
or
srv*c:\MyServerSymbols*https://msdl.microsoft.com/download/symbols
For example (in cmd.exe, windows command line):
set _NT_SYMBOL_PATH=srv*https://msdl.microsoft.com/download/symbols
Then use:
dumpbin /exports /symbols kernel32.lib | findstr _ExitProcess#
You'll have to be in the directory where kernel32 is and you'll have to have grep.
Probably is a way to use built in find command. You could also redirect it to a file and then view it in your editor.
Googling for an windows example of a recursive search i found this but trying to compile this with cl (and the MSVC++ tool chain) the compiler states error over error. Do I need to include some extra libraries directly as soon as i am not using the usual setup done by the MSVC++ GUI.
The posted example error codes are translated and therefore might not look exactly like they would in English.
"*": This referencing cannot be done for System::String the compiler substitutes "*" by
"^" to continue analysis
and
System::String ^ a system-owned array cannot contain this managed type
both those errors are on this line
String* directories[] = Directory::GetDirectories(dir.c_str()); //dir is a usual string
and therefore are not my coding.
What am I messing up?
The compile-line was:
cl /w /c /clr file.cpp
Directory::GetDeirectories is a .net call so it will return a .net object. You are trying to cast it to a c++ pointer. Your best bet is to declare a .net string array instead. The type is like so
array<String^>^ directories = Directory::GetDirectories(dir.c_str());
I have a dll that I need to make use of. I also have a program that makes calls to this dll to use it. I need to be able to use this dll in another program, however previous programmer did not leave any documentation or source code. Is there a way I can monitor what calls are made to this dll and what is passed?
You can't, in general. This is from the Dependency Walker FAQ:
Q: How do I view the parameter and
return types of a function?
A: For most functions, this
information is simply not present in
the module. The Windows' module file
format only provides a single text
string to identify each function.
There is no structured way to list the
number of parameters, the parameter
types, or the return type. However,
some languages do something called
function "decoration" or "mangling",
which is the process of encoding
information into the text string. For
example, a function like int Foo(int,
int) encoded with simple decoration
might be exported as _Foo#8. The 8
refers to the number of bytes used by
the parameters. If C++ decoration is
used, the function would be exported
as ?Foo##YGHHH#Z, which can be
directly decoded back to the
function's original prototype: int
Foo(int, int). Dependency Walker
supports C++ undecoration by using the
Undecorate C++ Functions Command.
Edit: One thing you could do, I think, is to get a disassembler and disassemble the DLL and/or the calling code, and work out from that the number and types of the arguments, and the return types. You wouldn't be able to find out the names of the arguments though.
You can hook the functions in the DLL you wish to monitor (if you know how many arguments they take)
You can use dumpbin (Which is part of the Visual Studio Professional or VC++ Express, or download the platform kit, or even use OpenWatcom C++) on the DLL to look for the 'exports' section, as an example:
dumpbin /all SimpleLib.dll | more
Output would be:
Section contains the following exports for SimpleLib.dll
00000000 characteristics
4A15B11F time date stamp Thu May 21 20:53:03 2009
0.00 version
1 ordinal base
2 number of functions
2 number of names
ordinal hint RVA name
1 0 00001010 fnSimpleLib
2 1 00001030 fnSimpleLib2
Look at the ordinals, there are the two functions exported...the only thing is to work out what parameters are used...
You can also use the PE Explorer to find this out for you. Working out the parameters is a bit tricky, you would need to disassemble the binary, and look for the function call at the offset in the file, then work out the parameters by looking at the 'SP', 'BP' registers.
Hope this helps,
Best regards,
Tom.