问题
I'm writing a C++ library using MinGW (4.8.0 dw2 posix). This library is used in another C++ project that use another compiler( in this case msvc ).
Refering to this I was redesign my C++ library. There are two things that I don't know how can I do:
- Can I use namespaces?
- I noticed that time_t on MinGW is 32 bit and in msvc is 64 bit. What Can I do?
1)
Does this broke the ABI:
// Window.h
// MYLIB_API defined as __declspec( dllexports )
// MYLIB_CALL defined as __stdcall
namespace mylib {
class Window {
public:
virtual void MYLIB_CALL destroy() = 0;
virtual void MYLIB_CALL setTitle(const char* title) = 0;
virtual const char* MYLIB_CALL getTitle() = 0;
void operator delete(void* p) {
if (p) {
Window* w = static_cast<Window*>(p);
w->destroy();
}
}
};
} // mylib
extern "C" MYLIB_API mylib::Window* MYLIB_CALL CreateWindow(const char* title);
2
How can I be sure that foundamental types are the same accross different compiler. For example in this case time_t
is defined as unsigned long
on MinGW and `__int64' on msvc. What can I do?
回答1:
Use my library cppcomponents at https://github.com/jbandela/cppcomponents
This is tested with Visual C++ 2013 (Previous versions did not have enough c++11 support) and mingw gcc 4.7+ on windows. It is a header only library released under the boost license. This allows you to use c++11 features like std::string, vector, tuple, pair, time_point across the compilers. I would be happy to answer any questions you have regarding how to use it for your particular case.
Here is an example for your case
First define the class in Window.h
#include <cppcomponents/cppcomponents.hpp>
namespace mylib{
struct IWindow :cppcomponents::define_interface<
cppcomponents::uuid<0x0d02ac9a, 0x4188, 0x48fc, 0x8054, 0xafe7252ec188 >>
{
std::string getTitle();
void setTitle(std::string new_title);
CPPCOMPONENTS_CONSTRUCT(IWindow, getTitle, setTitle);
};
inline std::string WindowID(){ return "windowlibdll!Window"; }
typedef cppcomponents::runtime_class<WindowID, cppcomponents::object_interfaces<IWindow>> Window_t;
typedef cppcomponents::use_runtime_class<Window_t> Window;
}
Then implement the class in WindowImp.cpp
#include "Window.h"
struct ImplementWindow:cppcomponents::implement_runtime_class<ImplementWindow,mylib::Window_t>
{
std::string title_;
ImplementWindow(){}
std::string getTitle(){
return title_;
}
void setTitle(std::string new_title){
title_ = new_title;
}
};
CPPCOMPONENTS_DEFINE_FACTORY()
Finally Use the code in UseWindow.cpp
#include "Window.h"
#include <iostream>
int main(){
mylib::Window w;
w.setTitle("my title");
std::cout << w.getTitle();
}
Here is how you build it the library using g++
g++ WindowImp.cpp -std=c++11 -shared -o windowlibdll.dll -I Source\Repos\cppcomponents
And here is how you build with program using MSVC 2013
cl UseWindow.cpp /EHsc /I Source\Repos\cppcomponents
Replace Source\Repose\cppcomponents
with the path were you have cppcomponents
Make sure the resulting windowslibdll.dll and the UseWindow.exe are in the same directory and run UseWindow.exe
来源:https://stackoverflow.com/questions/19591911/c-library-across-different-compilers