I have compiled a library that I have created with MinGW into an existing application using Borland 6 (I know its old but that's what it was made with). I have used implib to create the .lib file and imported it into my project. I have also added the paths to the dll and necessary header files.
When I try to compile I get a pile of Unnresolved external type errors. Have I missed out any steps of the importing process? Assuming I haven't and the issue is something like name-mangling how do I go about writing the interface in such a way that name mangling won't matter. I know it involves extern C but thats about the limit of my knowledge. There are only two classes that need to be accessed from outside the dll the remainder are all only used internally. I'm not sure how to use extern C with something that is entirely built with classes. I'm stil hopeful that it's my importing with borland 6.
extern "C" cannot be used for classes, only for free functions. So you have an option of writing a "C" interface to your class, where each function takes a pointer to your class and you would probably have create and destroy functions.
This is a way it is typically done, and your class could be forwardly declared as struct, which is the same as class, and then could even be used by applications written in C. You would normally put extern "C" only when __cplusplus is defined so there are normally #ifdef guards around it.
There is another option, if you only want your class to be used by C++ and you don't want to have to write a C interface for all your class methods.
Users of the DLL use an abstract interface and still use Create and Destroy methods (with extern "C") to create a pointer to the abstract interface, but then use the pointer in the normal C++ way. Of course ideally you will wrap this pointer in a smart pointer, e.g. a boost shared_ptr with a custom deleter that calls the Destroy method. (Users of the library should do that but you can provide a headers-only interface to do it).
There are a few other issues you would need to beware of if doing this, e.g. anything to do with run-time type information is likely to not work on the user-side, including exceptions. And once again your library could provide "open-source" C++ wrappers (compiled on the client side) to handle this in a more C++ way. A sort-of pImpl.
The name mangling is not standardized across compilers. Only expose extern C functions so that they are not name mangled. But this has a limitation that you cannot use object orient programming.
Another option is to implement COM objects as they are binary compatible.
Related
I am working on an API that in wraps C++ behaviors with C calling convention functions. The API is composed of a collection of shared libraries (dll) that may be used in a variety of languages. In instances where a C++ class object is pass across the dll boundary, a C opaque pointer or "Handle" is used to refer to the underlying C++ object, similar to the Win32 API. An example header file prototype of such a wrapper function is
extern "C" { __declspec(dllexport) int __cdecl MyObjConfig(MyObj_t* handle); }
Many of the API functions / classes interface with hardware peripherals. In many cases it's not practical to be able to test on the representative hardware system. I would like to find a way to mock the lower level components so that higher level libraries or exectuables using those libraries can be tested in a simulated environment. However, I'm loathe to include phrases in the underlying source code such as
if(is_test) { return 0; }
For example, I would like to mock the behavior of a function float GetSensorData() so that I can test an executable that links to GetSensorData's parent dll and calls get sensor data, by returning a reasonable imitation of the sensor's normal data, without setting up the sensor explicitly. Also, I would like to avoid having to alter the source of the executable beyond making sure it is linking to an imitation of GetSensorData's dll.
A key part of my interest in an automated framework for creating the dll mocks is that I don't want to have to maintain two seperate versions of each library: a test version and an actual version. Rather I would like to work on the actual and have the "mock" compilation generated programmatically.
Can anyone suggest a good way to do this? I've looked at Gtest and CMock / Unity. Both seem fine for testing the dlls themselves but don't seem well equipped to accomodate the
extern "C" { __declspec(dllexport) int __cdecl
function prototype declarations.
Thanks!
If you have a function that you wish to mock that is located in a library you can either do function pointer substitution or link-time substitution. I wrote about it more in-depth in this answer: https://stackoverflow.com/a/65814339/4441211
I personally recommend the function pointer substitution since it is much more simple and straightforward.
I have to build an API for a C++ framework which do some simulation stuff. I already have created a new class with __declspec(dllexport) functions and built the framework to a DLL.
This works fine and I can use the framework within a C# application.
But is there another or a better approach to create an API with C++?
If you want to create a C++-API, exporting a set of classes from a DLL/shared library is the way to go. Many libraries written in C++ decide to offer a C interface though, because pure C interfaces are much easier to bind to foreign languages. To bind foreign languages to C++, a wrapper generator such as SWIG is typically required.
C++-APIs also have the problem that, due to C++ name-mangling, the same compiler/linker needs to be used to build the framework and the application.
It is important to note that the __declspec(dllexport)-mechanism of telling the compiler that a class should be exported is specific to the Microsoft Compiler. It is common practice to put it into a preprocessor macro to be able to use the same code on other compilers:
#ifdef _MSC_VER
# define MY_APP_API __declspec(dllexport)
#else
# define MY_APP_API
#endif
class MY_APP_API MyClass {}
The solution with exporting classes have some serious drawbacks. You won't be able to write DLLs in another languages, because they don't support name mangling. Furthermore, you won't be able to use other compilers than VS (because of the same reason). Furthermore, you may not be able to use another version of VS, because MS doesn't guarantee, that mangling mechanism stays the same in different versions of the compiler.
I'd suggest using flattened C-style interface, eg.
MyClass::Method(int i, float f);
Export as:
MyClass_MyMethod(MyClass * instance, int i, float f);
You can wrap it inside C# to make it a class again.
I would like to be able to use C/C++ functions from python using ctypes python module.
I have a function int doit() in the .c / .cpp file. When I try to load the shared library:
Frr=CDLL("/path/FoCpy2/libFrr.so")
Frr.doit(c_int(5))
i find it working really well when the .c variant is used. When C++ is called the good way to call this function is (found out using nm libFrr.so using nm -gC libFrr.so produces just plain doit()):
Frr._Z4doitv(c_int(5))
I have read on Stackexchange that there is no standard way to call C++ from python, and there is "nonstandard name mangling" issue. Is the "Z4" a part of that issue? I guess the nonstandard name mangling would appear for more advanced language features such as class methods, templates, but also for such basic functions? Is it possible to force using simple C function names in simple cases for the C++ code?
You can use extern "C" to make the functions "look like" C functions to the outside world (i.e., disable name-mangling). And yes, you are correct, name-mangling is needed mostly for the more complicated features and types of functions that C++ has, and the name-mangling scheme has never been standardized (nor the binary compatibility) and so it varies from compiler to compiler and between versions (but most main-stream compilers have settled to something permanent now, but still different between compiler-vendors). And the reason that mangling is also required for plain old free functions is because C++ supports overloading (same function names but with different parameters), and thus, the compilers will encode the parameter specification (e.g., types) into the mangled names. Of course, if you use extern "C" you lose all features for which name-mangling is needed, so, it more or less boils down to C functions only.
You can use extern "C" either on a per-function basis, like so:
extern "C" int doit();
Or for the overall header:
extern "C" {
// all the function declarations here ...
};
However, for Python specifically, I highly recommend that you use a library that allows you to construct Python classes and functions that are a reflection of your C++ classes and functions, that makes life a lot easier and hides away all this extern "C" business. I recommend using Boost.Python, see this getting started page, it makes exporting functions and classes to Python a breeze. I guess others would also recommend SWIG, but I have never used it.
Calling c++ library functions is always a mess, actually even if you're using C++ you have to use the same compiler, etc. to make sure it works.
The only general solution is to define your c++ functions as extern "C" and make sure you follow the involved limitations - see here for an explanation of it.
I have a small doubt.
I am adding some extra functions in a C++ code and these functions are getting called by functions of a class.
Is it necessary to make these extra functions a part of class or can a C++ class function call a C function?
If yes, how should the makefile be modified ?
Thanks!
As long as you have included some declaration and the C function is linked in it some point in the compilation, you can call C functions in any C++ function. For instance:
mycfunc.h:
void test(int x);
myfunc.c:
void test(int x) {
printf("%d\n", x);
}
Now, simply include the header file where you want to use the function. In your Makefile, simply make sure you include "myfunc.c" (or .o if you're compiling objects) in the final compilation.
C++ is not a pure object oriented language.
So you can use imperative form as it is in C ( even if it's modular or not ).
Some C functions not encapsulated in Objects are accessible using c* includes (ctime for instance).
You do not need to put them in a class. Functions exist in C++ just as in C so you can just use them. Just try it and ask again if you have trouble.
As you state that you add functions to a C++ project, just treat (and think of) all your code as C++. Put your new stuff in files using the same filename extensions as those of the rest of the project.
Edit in response to comment from OP:
Yes, no need to think about the distinction between C and C++ in this case. Just write .cpp files. And in the makefile, just add those files just as the other files are listed there.
The distinction between C and C++ is important if you have existing C++ code and need to use if from C, or for example if you have existing C libraries and need to call that from C++. In your case there's very likely no reason not to stick to C++. Unlike Java, it's completely natural to have free standing functions. There even many in the C++ standard library.
Now, if in your case it is good design to have free standing functions instead of adding to classes (modifying or using inheritance) is hard to tell given the information you have posted. But, if what you need to do can be done in a natural way without accessing the private parts of existing classes the answer may very well be yes.
I'm trying to create a abstraction layer for platforms such as win32, mac os, linux, iOs etc.
I want this to be dynamically linked. On platforms that don't support this it shouldn't be a problem since from what I've seen everything that can be compiled as a dynamic library can be compiled as a static one as well with minimum impact on the code.
Now, to get to the point of this:
I created a interface named IThread and a class named CThread. I use a function named CreateThread that's defined with extern "C" to be able to export it and call it outside the library. The problem here is that in win32 for example there already is a function named CreateThread and thus I get a linker error. I understand the error and why it's appearing but I'm not sure of a good way to avoid this. I don't really like to use weird naming as qt uses like CreateQtThread.
Another idea I have would be is to create a thread manager/factory that creates instances of CThread but I'm not sure this would be a great idea.
What do you guys think about this? I'm asking because I don't want to rush on important organizing problems like this.
Thank you very much
I use a function named CreateThread that's defined with extern "C" to be able to export it and call it outside the library.
This is bad. I can't talk for other platforms, but on windows it's perfectly fine to export C++ functions. They are just get mangled, and you get some sanity checking in case someone changes the declaration. In fact, it's the only correct way to export a function that is C++. If you declare it as extern "C" you get no namespaces, no overloading, and someone who compiles with /EHsc will be in trouble if an exception escapes from your function.
Preferred solution: Do not declare them as extern "C", and put them in a namespace.
The only other solution: well, guess why all those C libraries prefix their functions with their_lib_prefix_function...
Your decision to use extern "C" is sound in my view because it allows access from other languages, compilers etc. But doing so means you can't use namespaces so you simply must prefix your functions with something to identify them as being from your library, a poor man's namespace if you will.
This is the compromise you must make if you want to use extern "C".
Well, I don't know whether you will like this as I know the C developers I worked with found it unaesthetic. But, it's very simple and prevents collisions like this. (More or less mentioned in this answer with the "their_lib_prefix_function" comment.)
So, whenever I was using C code, I used to basically 'namespace' my functions using an underscore. So, let's say your namespace is MegaAbstraction, then something like CreateThread becomes MegaAbstraction_CreateThread. Easy peasy. And no collisions, unless someone else has a namespace called MegaAbstraction in which case I recommend finding a namespace that's unlikely to be used by anyone else. ;)
Does your CreateThread use the stdcall calling convention (aka WINAPI)? If you use the cdecl calling convention, it should export the function name as _CreateThread and avoid the linkage conflict with the Win32 CreateThread function.
extern "C" _declspec(export) int _cdecl CreateThread(...
There is no "CreateQtThread" function in Qt, not even something similar. There's a QThread class, and it has constructors. If needed, you can put everything in a namespace.