Due to specific needs i need to create a DLL which exports a function that is named in a specific way, it's also mangled.
?drawGdi#stop#234##Z
Is there anyway of accomplishing this?
You can do that, but you have to write a DEF file.
foo.h:
extern "C" declspec(dllexport) void foo(int);
foo.def:
EXPORTS
?drawGdi#stop#234##Z=_foo
(_foo is the exported name of the function).
Remember to specify the DEF file when linking the DLL, of course.
For more details see the documentation on DEF files.
Can't you declare your function like e.g.
class myclass;
extern "C" void my_function(int,myclass&);
Then it should be exported as my_function (at least on Posix systems; I guess it is the same on Windows, but I don't know).
If compiling with GCC, you could use Asm Labels. Then any name acceptable by the assembler should be ok.
On Linux with ELF executables you probably could not, as David Schwartz suggested, simply edit the binary file (because that would probably break some hash-table used in ELF for symbols).
Related
I’m currently having some problems trying to implement an integration with a Verifone PoS.
The bank we are working with provided us with one .dll file, one .h file and one .hpp file.
I’m usually a Java or PHP developer, so for the last days I consumed everything I found on the web about DLL files and how to use them, but none seemed to work so far. I got a lot of errors, many of them being something like “invalid dll”.
I found on the web that alongside a dll file there should have been a .lib file. I asked the third party about this, but apparently
There is no .lib file. The .dll file contains all the required info for an integration
From their documentation of library I found this:
The form of the supplied binary is a dynamic library. By its nature, a dynamic library allows for easier updates and corrections, not requiring recompilation or relinking of the client (calling) code, as long as the procedures prototypes (function parameters and return types) remain the same.
The language used for the library implementation is C++.
To access the functionalities implemented in the library binary, a C-style header interface is provided. This is comprised of the function prototypes available to be called as well as the types of the result-structures through which the returned data needs to be interpreted to make sense for the previously accessed functionality (the specific requested transaction).
So yeah, the .h file includes only the data types, and the .hpp file contains some declarations that looks like this:
extern "C" __declspec(dllexport) bool doSomething(int param);
Also in their documentation there is an example of how an implemetation should look (and it is fairly simple):
bool someVar = doSomething(1);
It looks like those functions can be called as simple as that, but they cannot. If I try to do that I get an “undefined function” (or similar) error.
At this point the only thing that seemed to have somehow worked (maybe) is loading the DLL with the LoadLibrary function. But besides the fact that whatever function I try to call, with whatever parameters, it returns false, it seems kind of wrong that I do not use the .hpp file at all.
So here we are. How I should aproach this? Is there a way to load the DLL and use the provided HPP file as function definitions? If not, is there another way beside LoadLibrary + GetProcAddress combo to do this?
Thank you!
I'm assuming the dll is a native dll, not a managed assembly (.net dll).
Usually, the dll author adds a preprocessor definition to the build system, like DLL_EXPORT. So if the author compiles the dll, the import library (a small .lib file) will contain all functions that used the DLL_API macro. Then the author can ship the very same header to a user. Because that user won't have the DLL_EXPORT macro defined, DLL_API will resolve to a dllimport, which basically says that the annotated function is defined in the import library.
Such a header might look like this (the whole #if condition is usually in its own header file which is then included in all headers that export functions):
#ifdef DLL_EXPORT
# define DLL_API __declspec(dllexport)
#else
# define DLL_API __declspec(dllimport)
#endif
extern "C"
{
void DLL_API SomeFunction(int x);
void DLL_API AnotherFunction(int x);
}
If the author builds the project (in msvc) the compiler will generate the dll file and a small .lib file, which is the import library. This lib will essentially do what you have to do now: calling LoadLibrary and GetProcAddress to resolve all the functions that have been annotated with __declspec(dllexport).
The following part is a bit speculative and I'm guessing a bit here.
All __declspec(dllimport) does, is tell consumers that this dll contains those functions. But the linker has to link a declaration to its definition (implementation) so the function must be defined somewhere at compiletime. And that place is the import library (.lib). If you don't link with the import library, you will get a linker error when you build your project.
This means simply changing the dllexport to a dllimport won't solve your problems. Without an import library your only option is to load the dll manually with LoadLibrary and search for each function.
If I were you, I'd ask the author for an example project that uses the dll. AFAIK, the only ways to use a native dll is either by linking to an import library or by loading everything manually.
Manually generating the import library from the dll
I've tested this to make sure it works.
First of all, fix the header file to either use the macros like I did in the example above, or just use dllimport directly.
Second, open the developer command prompt for VS and follow the steps from this answer. Make sure to use the correct file names and target architecture (x64 or x86). Now you should have a .lib file.
Thrid, add the lib to your project.
Add the directory of the lib (place it somewhere close to the project so you can use relative paths). Open the project properties and follow the steps in this image:
Make sure that Configuration and Platform are correct (you probably want it like in the image). You can also use relative paths. Click on the Macros button to see all predefined paths available to you.
Add the lib to the linker dependencies:
Put the header somewhere in your project where you can access it.
Now you can simply include the header anywhere in your project and use the functions declared inside it. But note that the dll file has to be placed somewhere where LoadLibrary can find it. Preferably this is the same directory where your project's executable is located.
Bonus facts
The definition file (.def) is actually very simple. The def file for my sample code above is:
LIBRARY MyLibrary
EXPORTS
AnotherFunction
SomeFunction
If I remove the extern "C" block around my declarations, my function names will be mangled and the def file looks like this:
LIBRARY MyLibrary
EXPORTS
?AnotherFunction##YAXH#Z
?SomeFunction##YAXH#Z
If you put those functions inside a namespace (for example FooSpace), that namespace name will also be part of the function name:
LIBRARY MyLibrary
EXPORTS
?AnotherFunction#FooSpace##YAXH#Z
?SomeFunction#FooSpace##YAXH#Z
Note that all extern "C" entities will ignore namespaces, meaning all extern "C" functions, variables, types, ... will be put into the global namespace, no matter if you define them inside a namespace or not.
These are also the names that you'd have to pass to GetProcAddress if you did it manually.
I have worked with "CPPLoadLibrary" example (from Microsoft All-in-One framework)
Okay, there are two ways of export symbols from the sample DLL.
Export symbols from a DLL using .DEF files
A module-definition (.DEF) file is a text file containing one or more module
statements that describe various attributes of a DLL. Create a .DEF file and
use the .def file when building the DLL. Using this approach, we can export
functions from the DLL by ordinal rather than by name.
Export symbols from a DLL using __declspec(dllexport)
__declspec(dllexport) adds the export directive to the object file so we do
not need to use a .def file. This convenience is most apparent when trying to
export decorated C++ function names.
And so we have the following code.
typedef int (_cdecl* LPFNGETSTRINGLENGTH1) (PCWSTR);
typedef int (CALLBACK* LPFNGETSTRINGLENGTH2) (PCWSTR);
LPFNGETSTRINGLENGTH1 lpfnGetStringLength1 = (LPFNGETSTRINGLENGTH1)
GetProcAddress(hModule, "GetStringLength1");
LPFNGETSTRINGLENGTH2 lpfnGetStringLength2 = (LPFNGETSTRINGLENGTH2)
GetProcAddress(hModule, "_GetStringLength2#4");
So my question is how to determine the name of symbol in order to call GetProcAddress?
in first case it's pretty straightforward, we take that symbol name from .DEF file.
But what about "_GetStringLength2#4"
What is underscore? What is "#4" stand for?
Thanks.
If you don't use a .DEF file, the export names are decorated according to their calling convention in order to support exporting overloaded functions. See Why can't I GetProcAddress a function I dllexport'ed?:
[T]he decoration scheme varies from architecture to architecture and from calling convention to calling convention. So, for example, if the function is exported from a PPC DLL, you would have to do GetProcAddress(hinst, "..SomeFunction"), but if it is exported from an 80386 DLL as extern "C" __stdcall, you would need GetProcAddress(hinst, "_SomeFunction#8"), but if it's __fastcall you would need GetProcAddress(hinst, "#SomeFunction#8").
What's more, C++ decoration varies from compiler vendor to compiler vendor. A C++ exported function might require GetProcAddress(hinst, "?SomeFunction##YGXHH#Z") if compiled with the Microsoft C++ compiler, but some other decorated string if compiled with the Borland C++ compiler.
So if you intend people to be able to GetProcAddress for functions and you intend your code to be portable to multiple platforms, or if you intend them to be able to use your DLL from a language other than C/C++ or use a C++ compiler different from Microsoft Visual Studio, then you must export the function by its undecorated name.
See The history of calling conventions, part3 for a description of the various name decoration schemes. In this case, the function uses the __stdcall calling convention, so it's decorated by prepending an underscore and appending a # sign and the number of bytes worth of parameters it takes. It takes one word-sized argument for a total of 4 bytes, so it's decorated as _GetStringLength2#4.
To answer your actual question, use your compiler's TDUMP or similar tool, or any other tool that can display an executable's exports table, so you can see the actual exported names.
Under windows we have a C interface (extern "C" { // interface }) to our C++ library, that exports unmangled functions using a module definition file (.def).
I am trying to recreate the same thing under linux, where I am relatively inexperienced. I understand that under NIX systems, all functions are exported by default. With this in mind I created a shared object, which I ran through the nm command.
I was surprised to see that, unlike in windows, my function names had been mangled!
How can I prevent this please?
The usual solution is to declare the functions extern "C". This not only causes the names to be mangled as in C, but also for the function to use the C calling conventions.
After googling, i came to know that Dllimport makes the function available for other modules,
is it mandatory to declare function with extern "c" identifier?
Also, Dllexport means, Dll itself uses the function while compiling it says. so by default all
functions present in DLL are dllexport?
__declspec(dllexport) exports a symbol. It makes it available from outside a DLL.
__declspec(dllimport) imports a symbol. It practically says "this symbol is not defined in this application, it needs to be imported from a DLL file".
You don't have to declare it with extern "C". If you don't use extern "C", then the symbol will be exported as a C++ symbol, and you will only be able to call it from C++ (and languages that support calling C++ DLLs). If you use extern "C", then the symbol will be exported as a C symbol, and you will be able to call it from languages that support caling C DLLs.
If you want to use your DLL in C#, you will need to use extern "C".
Here is an excellent tutorial that shows you how to use a C++ DLL in C#: How to marshal a C++ class. I have used solution A in many projects at work.
Also, here is a short tutorial on how you can use a C++ DLL in another C++ application: How to create and use DLL in C++.
No -- dllexport means you're exporting it from the DLL (or from an executable) so that other modules (DLLs or executables) can use that function.
dllimport is used to declare a function that's implemented in a DLL (or, again, executable).
So, in a typical case, you'll have something like:
#ifdef BUILDDLL
#define DLL declspec(dllexport)
#else
#define DLL declspec(dllimport)
#endif
Then each public function the DLL will be marked as DLL:
DLL int dosomething(int);
Then, when you're building the DLL, you'll define BUILDDLL, to have all those functions marked as dllexport. Otherwise, you'll include the same header in client code that needs to use the function(s). It won't define BUILDDLL, so they'll all be marked as dllimport instead, so when it comes to link time, it'll create a link to that DLL instead of trying to satisfy those functions from someplace like the standard library.
It also means that entries (in the form of static import and export tables) are created (by the linker) in the exe, dll..files, which document the dependencies between a provider and a consumer.
I generated a DLL in Visual from a C++ code. Dependency Walker sees 3 functions exported as C functions.
I made an SCons project to do the generate the DLL, and 2 of the 3 functions are not seen as C functions.
What makes a function seen as a or C++ function, without modifying the code ? It must be in the compilation/linking options, but I didn't find any relevant thing.
The function are prefixed by a macro : AM_LIB_EXPORT
In the .h, I have :
#ifdef _WIN32
#define AM_LIB_EXPORT __declspec(dllexport)
#else
#define AM_LIB_EXPORT
#endif // _WIN32
Thanks.
What makes a function seen as a or C++ function, without modifying the code ?
A function compiled by a C++ compiler is automatically a 'C++-function' and name-mangling occurs to resolve C++ features such as namespaces and overloading.
In order to get 'C' export names, one must use the aforementioned extern "C" qualifier in the function declaration. Alternatively a huge extern "C" { .. } block around the header containing the prototypes.
If this does not solve your issue, its maybe related to dllimport/dllexport. If you #define AM_LIB_EXPORT __declspec(dllexport) in your DLL build, you'll typically also need to make it dllimport for apps linking against your DLL in order for the linker to know where to fetch the symbols from.
Is this a name mangling issue? If you don't use extern "C" around your function declarations, they will get name-mangled.
I found the reason :
The export was also added as additionnal command line option (/EXPORT). In this case, it is exported as a C function. I don't understand why...
I removed this additionnal command line switch.
Thank you all.
I still don't know how to mark a thread as "resolved" ?