Are exports in dll case sensitive? - windows

I was working on win7 and delphi 2010. Here is my code.
library CFGFunc;
uses
sysUtils
Un_ExFuncDll in "base\Un_ExFuncDll.pas"
...
exports
LoadExFuncsInDLL,
...
and Un_ExFuncDll.pas is here
unit Un_ExFuncDll;
interface
uses
Classes;
procedure LoadexfuncsIndll(); stdcall;
...
After compiled, the dll doesn't work. However I replaced LoadexfuncsIndll() with
LoadExFuncsInDLL()(exactly match what is in exports) in Un_ExFuncDll.pas. It then worked.
Delphi is case-insensitive. But it seems that exports in dll are case sensitive.
So, what's the deal with them?

Importing/exporting DLL functions IS case-sensitive, and always has been. That behavior is tied to the OS DLL loader, which is case-sensitive. That is one of the only areas of the Delphi language that is case-sensitive. This is documented behavior, at least in part:
Writing Dynamically Loaded Libraries
A name specifier consists of the directive name followed by a string constant. If an entry has no name specifier, the routine is exported under its original declared name, with the same spelling and case. Use a name clause when you want to export a routine under a different name.
Procedures and Functions (Delphi)
In your importing declaration, be sure to match the exact spelling and case of the routine's name. Later, when you call the imported routine, the name is case-insensitive.

Related

Compiling Fortran external symbols

When compiling fortran code into object files: how does the compiler determine the symbol names?
when I use the intrinsic function "getarg" the compiler converts it into a symbol called "_getarg#12"
I looked in the external libraries and found that the symbol name inside is called "_getarg#16" what is the significance of the "#[number]" at the end of "getarg" ?
_name#length is highly Windows-specific name mangling applied to the name of routines that obey the stdcall (or __stdcall by the name of the keyword used in C) calling convention, a variant of the Pascal calling convention. This is the calling convention used by all Win32 API functions and if you look at the export tables of DLLs like KERNEL32.DLL and USER32.DLL you'd see that all symbols are named like this.
The _...#length decoration gives the number of bytes occupied by the routine arguments. This is necessary since in the stdcall calling conventions it is the callee who cleans up the arguments from the stack and not the caller as is the case with the C calling convention. When the compiler generates a call to func with two 4-byte arguments, it puts a reference to _func#8 in the object code. If the real func happens to have different number or size of arguments, its decorated name would be something different, e.g. _func#12 and hence a link error would occur. This is very useful with dynamic libraries (DLLs). Imagine that a DLL was replaced with another version where func takes one additional argument. If it wasn't for the name mangling (the technical term for prepending _ and adding #length to the symbol name), the program would still call into func with the wrong arguments and then func would increment the stack pointer with more bytes than was the size of the passed argument list, thus breaking the caller. With name mangling in place the loader would not launch the executable at all since it would not be able to resolve the reference to _func#8.
In your case it looks like the external library is not really intended to be used with this compiler or you are missing some pragma or compiler option. The getarg intrinsic takes two arguments - one integer and one assumed-sized character array (string). Some compilers pass the character array size as an additional argument. With 32-bit code this would result in 2 pointers and 1 integer being passed, totalling in 12 bytes of arguments, hence the _getarg#12. The _getarg#16 could be, for example, 64-bit routine with strings being passed by some kind of descriptor.
As IanH reminded me in his comment, another reason for this naming discrepancy could be that you are calling getarg with fewer arguments than expected. Fortran has this peculiar feature of "prototypeless" routine calls - Fortran compilers can generate calls to routines without actually knowing their signature, unlike in C/C++ where an explicit signature has to be supplied in the form of a function prototype. This is possible since in Fortran all arguments are passed by reference and pointers are always the same size, no matter the actual type they point to. In this particular case the stdcall name mangling plays the role of a very crude argument checking mechanism. If it wasn't for the mangling (e.g. on Linux with GNU Fortran where such decorations are not employed or if the default calling convention was cdecl) one could call a routine with different number of arguments than expected and the linker would happily link the object code into an executable that would then most likely crash at run time.
This is totally implementation dependent. You did not say, which compiler do you use. The (nonstandard) intrinsic can exist in more versions for different integer or character kinds. There can also be more versions of the runtime libraries for more computer architectures (e.g. 32 bit and 64 bit).

Should use "__imp__ApiName#N" or "_ApiName#N"?

I have dumped a Windows SDK .lib file (kernel32.lib) with DUMPBIN, the output show me that there are two "versions" for every API name, for example:
_imp_ExitProcess#4
and
_ExitProcess#4
So, why there are two of the same with different name mangling? .
Let say i want to call ExitProcess from NASM, wich of them should i use when declare EXTERN?, mi practice shows me that i can call any of them but i don't know which one is the "correct" or the "prefered" to stick with it.
I think the _imp_ version is meant to be used with __declspec(dllimport) on Visual C++ compilers to prevent potential conflicts with code in the same module.
You're not supposed to use that fact explicitly in your code -- just use the original function, i.e. _ExitProcess#4.

Do I have to specify extern "C" when exporting symbols?

I am wondering if extern "C" is a must or not?
Only if you want to call your code from C (or a different C++ compiler, which you should treat like C).
It is to disable name-mangling.
See this article on the C++ FAQ: http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html
No, you use extern "C" to provide a C-linkage to your C++ functions, so they won't be 'decorated' like normal C++ functions and to allow them to be called from C (or Objective-C).
Function decoration is used to implement the C++ function overloading feature and gives each variation of the function a different signature while allowing the developer to use the name he assigned.
Your C++ functions will be exported automatically by simply not using the static keyword. However if you have implemented your C++ functions within a Windows DLL it's necessary to use the declspec dllexport/dllimport keywords to access them externally.
Use of extern "C" switches off name mangling. If you don't do this you may make if hard for a client of your DLL to import your symbols.
Remember that different C++ compilers have different name mangling rules and so your mangled exported names may differ from the names used on import.
However, since it is wrong to import a class from a DLL if you are using a different compiler than that used for the DLL, this is rather a moot point.
So, if you are exporting classes (usually a bad idea anyway) it is easier to leave mangling on. Otherwise switch it off with extern "C".

How to create a drop-in replacement for an existing dll?

Beyond creating a dll with all the same functions with the same interface and calling conventions, does the replacement dll need to exactly duplicate the export map including ordinal numbers of the original as well? So that not only explicit loading via GetProcAddress works, but implicit linking as well?
(edit: this is an unmanaged, c/c++ windows dll I'm talking about, not .net)
You will need to mimic every export that any other client is using, you don't need to mimic "dead" exports that no one is using. You need to keep the ordinals only if other clients are linked by using ordinal instead of export name (which is quite rare).
There a is something that you need to keep in mind: If the dll contains C++ classes and it is not using extern "C" then you need to maintain binary comparability, meaning the classes in the replacement dll needs to have the same fields in the same order as the original classes. If your using interfaces that you need to keep the vtable with the same arguments for each method.

Using GetProcAddress when the name might be decorated

What is the correct way to use GetProcAddress() on a 32 bit DLL? On win32, there are three calling conventions, cdecl, stdcall and fastcall. If the function in the DLL is foo they will decorate the name in the following ways _foo, _foo#N and #foo#N.
But if the author of the dll has used a .def file, then the exported name will be changed to just "foo" without any decoration.
This spells trouble for me because if I want to load foo from a dll that is using stdcall, should I use the decorated name:
void *h = LoadLibraryEx(L"foo.dll", NULL, 0);
GetProcAddres((HMODULE)h, L"_foo#16");
Or the undecorated one:
void *h = LoadLibraryEx(L"foo.dll", NULL, 0);
GetProcAddres((HMODULE)h, L"foo");
? Should I guess? I've looked at lots of 32 bit DLL files (stdcall and cdecl) and they all seem to export the undecorated name. But can you assume that is always the case?
There's really no shortcut or definitive rule here. You have to know the name of the function. The normal scenario is that you know at compile time the name of the function. In which case it does not matter whether the exported name is mangled, decorated, or indeed completely unrelated to the semantic name. Functions can be exported without names, by ordinal. Again, you need to know how the function was exported.
If you are presented with a header file for a library, and want to link to it with explicit linking (LoadLibrary/GetProcAddress) then you will need to find out the names of the function. Use a tool like dumpbin or Dependency Walker to do that.
Now, the other scenario which might lead to you asking the question is that you don't know the name at compile time. For instance, the name is provided by the user of your program in one way or another. Again, it is quite reasonable to require the user to know the exported name of the function.
Finally, you can parse the PE meta data for the executable file to enumerate its exported function. This will give you a list of exported function names, and exported function ordinals. This is what tools like dumpbin and Dependency Walker do.
If __declspec(dllexport) is used during compilation and __declspec(dllimport) in header file, as well as extern "c", then you do not need to decorate those functions. The __declspec helps in using the undecorated names, but function overloads, namespaces, and classes still require same way to distinguish them.
Usually, object oriented functions are exported using function ordinals instead of their decorated names. Cast the ordinal as (char*)(unsigned short)ordinal, thus, GetProcAddress(module, (char*)(unsigned short)ordinal);
Edit: while most of Windows use UTF-16, GetProcAddress uses UTF-8, so it cannot use a wide character string.
GetProcAddress(module, L"foo") is identical to GetProcAddress(module, "f");

Resources