I am using GTest to write UT for my code.
In order to test "non-virtual" functions, i generated the "function mangled name" using "nm" utility and added it in the "test suite.cpp" file (under extern "C") in the below format
__wrap_Mangled_name (function args as in original)
and then linked the same in "tst_def" file. Still when i run the test suite, the original function in the source code gets called instead of this "wrapped one". But in fact, this wrapped function should be called .
I cross-checked whether this mangled name is correct or not using "C++filt" utility and it was correct.
Any suggestions for this?
Thanks,
Udhai
Related
I am using swig 4.0.2 to generate a package for tcl use.
The source .i file contains lots of classes and the generated _wrap.cpp file contains the all the classes with their methods as I would expect and everything compiles ok with no warnings.
However, for at least 1 class, when I come to call a method on a instance from a tcl script I get a runtime error saying the method does not exist. The error also dumps out all the available methods of the class. The method I am trying to call, along with a few others, does not exist in that list.
Invalid method. Must be one of: configure cget -acquire -disown -delete ...
There doesn't appear to be any pattern to which methods are not in the list though it is consistent which methods are missing.
The missing methods are scattered through the declared swig interface. ie they aren't at the beginning or end, nor all in one block. There is no pattern to their names nor function signature that I can see.
The function being run when the error occurs is SWIG_Tcl_MethodCommand: a function generated by swig. It is responsible for looking up the method by name and printing out the error code.
The function wrappers all exist and are referenced in the class's swig_method array.
I would have imagined that if a method was not going to be found by the look up it would be all or nothing.
Does anyone have ideas where I could look for errors?
I'm afraid I haven't been able to isolate into a small testcase that I can share.
I'm using swig 4.02, generating code for tcl8 and compiling under c++ 14.
The problem is caused by copy and paste code.
A second swig package exists in the Project I'm working on. It redeclares the same class interface but with some methods missing!
If I sync up the declarations then everything works.
This leaves the question of how the original code with unsynced swig interfaces (that was generated with swig1.0) ever worked.
Suppose my code have an internal function, which is not exported, not available for public in any other way (say, a thread function for CreateThread). If I compile my application with C++ Builder (using 10.4 Sydney with classic compiler) - then I can check (via .map file) that my function will lose its name and will be named something like _16386. It always starts with _ followed by some integer. Another example are names like C3304_3, D304_0, B09.
This is not specific to my functions. Same is true for internal (non-published) RTL functions.
This is not mangling. Mangling is a way to decorate name with type information. For example: #Winapi#Commctrl#initialization$qqrv. This is a completely different thing. Additionally, "Map with mangled names" option is set to False. If I set it to True - mangled version for _16386 will become something like #Winapi#Commctrl#_16386.
It is certainly not a problem for typical application runs, because there are no references to that function via its name. However, if I am going to use something like exception tracer tool (or even MS Process Explorer - assuming that I will convert C++ Builder symbols into MS DBG format) - this tool will use produced symbols/debug info and will show me the _16386 name. And I have no idea what code this name refers to!
Why does compiler/linker do that? Is there any way to stop it doing so?
P.S. All tests run with the default Debug profile, which means "Disable all optimizations" and "Full debug info" options are enabled.
I have 2 functions of same name in two different c++ files. Lets say the function name is initialize(char*) and files are file1.cpp and file2.cpp. From gdb how do I call the initialize() function of file file2.cpp. I have tried "call 'file2.cpp'::initialize("setup") but it calls function of file1.cpp.
I verified that same function gets called both times.
This looks like a bug in gdb. You should report it.
This could probably be used as workaround:
print 'file1.cpp'::initialize
print 'file2.cpp'::initialize
(now you have addresses of both functions)
call address-of-one-or-other-function("setup")
I'm trying to explicitly link with a DLL. No other resources is available except the DLL file itself and some documentation about the classes and its member functions.
From the documentation, each class comes with its own
member typedef
example: typedef std::map<std::string,std::string> Server::KeyValueMap, typedef std::vector<std::string> Server::String Array
member enumeration
example: enum Server::Role {NONE,HIGH,LOW}
member function
example: void Server::connect(const StringArray,const KeyValueMap), void Server::disconnect()
Implementing the codes from google search, i manage to load the dll can call the disconnect function..
dir.h
LPCSTR disconnect = "_Java_mas_com_oa_rollings_as_apiJNI_Server_1disconnect#20";
LPCSTR connect =
"_Java_mas_com_oa_rollings_as_apiJNI_Server_1connect#20";
I got the function name above from depends.exe. Is this what is called decorated/mangled function names in C++?
main.cpp
#include <iostream>
#include <windows.h>
#include <tchar.h>
#include "dir.h"
typedef void (*pdisconnect)();
int main()
{
HMODULE DLL = LoadLibrary(_T("server.dll"));
pdisconnect _pdisconnect;`
if(DLL)
{
std::cout<< "DLL loaded!" << std::endl;
_disconnect = (pdisconnect)GetProcAddress(DLL,disconnect);
if(_disconnect)
{
std::cout << "Successful link to function in DLL!" << std::endl;
}
else
{
std::cout<< "Unable to link to function in DLL!" << std::endl;
}
}
else
{
std::cout<< "DLL failed to load!" << std::endl;
}
FreeLibrary (DLL);
return 0;}
How do i call (for example) the connect member function which has the parameter datatype declared in the dll itself?
Edit
more info:
The DLL comes with an example implementation using Java. The Java example contains a Java wrapper generated using SWIG and a source code.
The documentation lists all the class, their member functions and also their datatypes. According to the doc, the list was generated from the C++ source codes.(??)
No other info was given (no info on what compiler was used to generate the DLL)
My colleague is implementing the interface using Java based on the Java example given, while I was asked to implement using C++. The DLL is from a third party company.
I'll ask them about the compiler. Any other info that i should get from them?
I had a quick read through about JNI but i dont understand how it's implemented in this case.
Update
i'm a little confused... (ok, ok... very confused)
Do i call(GetProcAddress) each public member function separately only when i want to use them?
Do i create a dummy class that imitates the class in the dll. Then inside the class definition, i call the equivalent function from the DLL? (Am i making sense here?) fnieto, is this what you're showing me at the end of your post?
Is it possible to instantiate the whole class from the DLL?
I was trying to use the connect function described in my first post. From the Depends.exe DLL output,
std::map // KeyValueMap has the following member functions: del, empty, get, has_1key,set
std::vector // StringArray has the following member functions: add, capacity, clear, get, isEMPTY, reserve, set, size
which is different from the member functions of map and vector in my compiler (VS 2005)...
Any idea? or am i getting the wrong picture here...
Unless you use a disassembler and try to figure out the paramater types from assemly code, you can't. These kind of information is not stored in the DLL but in a header file coming with the DLL. If you don't have it, the DLL is propably not meant to be used by you.
I would be very careful if I were you: the STL library was not designed to be used across compilation boundaries like that.
Not that it cannot be done, but you need to know what you are getting into.
This means that using STL classes across DLL boundaries can safely work only if you compile your EXE with the same exact compiler and version, and the same settings (especially DEBUG vs. RELEASE) as the original DLL. And I do mean "exact" match.
The C++ standard STL library is a specification of behavior, not implementation. Different compilers and even different revisions of the same compiler can, and will, differ on the code and data implementations. When your library returns you an std::map, it's giving you back the bits that work with the DLL's version of the STL, not necessarily the STL code compiled in your EXE.
(and I'm not even touching on the fact that name mangling can also differ from compiler to compiler)
Without more details on your circumstances, I can't be sure; but this can be a can of worms.
In order to link with a DLL, you need:
an import library (.LIB file), this describes the relation between C/C++ names and DLL exports.
the C/C++ signatures of the exported items (usually functions), describing the calling convention, arguments and return value. This usually comes in a header file (.H).
From your question it looks like you can guess the signatures (#2), but you really need the LIB file (#1).
The linker can help you generate a LIB from a DLL using an intermediate DEF.
Refer to this question for more details: How to generate an import library from a DLL?
Then you need to pass the .lib as an "additional library" to the linker. The DLL must be available on the PATH or in the target folder.
I would like to call a method from an dll, but i don't have the source neither the header file. I tried to use the dumpbin /exports to see the name of the method, but i can found the methods signature?
Is there any way to call this method?
Thanks,
If the function is a C++ one, you may be able to derive the function signature from the mangled name. Dependency Walker is one tool that will do this for you. However, if the DLL was created with C linkage (Dependency Walker will tell you this), then you are out of luck.
The C++ language does not know anything about dlls.
Is this on Windows? One way would be to:
open the dll up in depends.exe shipped with (Visual Studio)
verify the signature of the function you want to call
use LoadLibrary() to get load this dll (be careful about the path)
use GetProcAddress() to get a pointer to the function you want to call
use this pointer-to-function to make a call with valid arguments
use FreeLibrary() to release the handle
BTW: This method is also commonly referred to as runtime dynamic linking as opposed to compile-time dynamic linking where you compile your sources with the associated lib file.
There exists some similar mechanism for *nixes with dlopen, but my memory starts to fail after that. Something called objdump or nm should get you started with inspecting the function(s).
As you have found, the exports list in a DLL only stores names, not signatures. If your DLL exports C functions, you will probably have to disassemble and reverse engineer the functions to determine method signatures. However, C++ encodes the method signature in the export name. This process of combining the method name and signature is called "name mangling". This Stackoverflow question has a reference for determining the method signature from the mangled export name.
Try the free "Dependency Walker" (a.k.a. "depends") utility. The "Undecorate C++ Functions" option should determine the signature of a C++ method.
It is possible to figure out a C function signature by analysing beginnig of its disassembly. The function arguments will be on the stack and the function will do some "pops" to read them in reverse order. You will not find the argument names, but you should be able to find out their number and the types. Things may get more difficult with return value - it may be via 'eax' register or via a special pointer passed to the function as the last pseudo-argument (on the top of the stack).
If you indeed know or strongly suspect the function is there, you can dynamically load the DLL with loadLibrary and get a pointer to the function with getProcAddress. See MSDN
Note that this is a manual, dynamic way to load the library; you'll still have to know the correct function signature to map to the function pointer in order to use it. AFAIK there is no way to use the dll in a load-time capability and use the functions without a header file.
Calling non-external functions is a great way to have your program break whenever the 3rd party DLL is updated.
That said, the undname utility may also be helpful.