added a C++ API
This commit is contained in:
parent
6d73e7898e
commit
de7a01d322
@ -84,28 +84,48 @@ endif
|
||||
|
||||
.PHONY: build-executable
|
||||
build: build-executable
|
||||
build-executable: $(bindir)/executable $(bindir)/executable-cpp
|
||||
build-executable: $(bindir)/executable $(bindir)/executable-as-cxx $(bindir)/executable-as-cxx11 $(bindir)/executable-cxx $(bindir)/executable-cxx11
|
||||
|
||||
$(bindir)/executable: $(srcdir)/whereami.c $(srcdir)/whereami.h $(exampledir)/executable.c
|
||||
mkdir -p $(@D)
|
||||
$(CC) -I $(srcdir) $(CPPFLAGS) $(CFLAGS) $(filter-out %.h,$^) $(LDFLAGS) -o $@
|
||||
$(if $(postbuild),$(postbuild) $@)
|
||||
|
||||
$(bindir)/executable-cpp: $(srcdir)/whereami.c $(srcdir)/whereami.h $(exampledir)/executable.c
|
||||
$(bindir)/executable-as-cxx: $(srcdir)/whereami.c $(srcdir)/whereami.h $(exampledir)/executable.c
|
||||
mkdir -p $(@D)
|
||||
$(CXX) -x c++ -I $(srcdir) $(CPPFLAGS) $(CXXFLAGS) $(filter-out %.h,$^) $(LDFLAGS) -o $@
|
||||
$(CXX) -std=c++03 -x c++ -I $(srcdir) $(CPPFLAGS) $(CXXFLAGS) $(filter-out %.h,$^) $(LDFLAGS) -o $@
|
||||
$(if $(postbuild),$(postbuild) $@)
|
||||
|
||||
$(bindir)/executable-as-cxx11: $(srcdir)/whereami.c $(srcdir)/whereami.h $(exampledir)/executable.c
|
||||
mkdir -p $(@D)
|
||||
$(CXX) -std=c++11 -x c++ -I $(srcdir) $(CPPFLAGS) $(CXXFLAGS) $(filter-out %.h,$^) $(LDFLAGS) -o $@
|
||||
$(if $(postbuild),$(postbuild) $@)
|
||||
|
||||
$(bindir)/executable-cxx: $(srcdir)/whereami++.cpp $(srcdir)/whereami++.h $(exampledir)/executable.cpp
|
||||
mkdir -p $(@D)
|
||||
$(CXX) -std=c++03 -x c++ -I $(srcdir) $(CPPFLAGS) $(CXXFLAGS) $(filter-out %.h,$^) $(LDFLAGS) -o $@
|
||||
$(if $(postbuild),$(postbuild) $@)
|
||||
|
||||
$(bindir)/executable-cxx11: $(srcdir)/whereami++.cpp $(srcdir)/whereami++.h $(exampledir)/executable.cpp
|
||||
mkdir -p $(@D)
|
||||
$(CXX) -std=c++11 -x c++ -I $(srcdir) $(CPPFLAGS) $(CXXFLAGS) $(filter-out %.h,$^) $(LDFLAGS) -o $@
|
||||
$(if $(postbuild),$(postbuild) $@)
|
||||
|
||||
.PHONY: build-library
|
||||
build: build-library
|
||||
build-library: $(bindir)/library$(libsuffix) $(bindir)/library-cpp$(libsuffix)
|
||||
build-library: $(bindir)/library$(libsuffix) $(bindir)/library-as-cxx$(libsuffix) $(bindir)/library-cxx$(libsuffix)
|
||||
|
||||
$(bindir)/library$(libsuffix): $(srcdir)/whereami.c $(srcdir)/whereami.h $(exampledir)/library.c
|
||||
mkdir -p $(@D)
|
||||
$(CC) -I $(srcdir) $(CPPFLAGS) $(CFLAGS) $(filter-out %.h,$^) $(LDFLAGS) -shared -o $@
|
||||
$(if $(postbuild),$(postbuild) $@)
|
||||
|
||||
$(bindir)/library-cpp$(libsuffix): $(srcdir)/whereami.c $(srcdir)/whereami.h $(exampledir)/library.c
|
||||
$(bindir)/library-as-cxx$(libsuffix): $(srcdir)/whereami.c $(srcdir)/whereami.h $(exampledir)/library.c
|
||||
mkdir -p $(@D)
|
||||
$(CXX) -x c++ -I $(srcdir) $(CPPFLAGS) $(CXXFLAGS) $(filter-out %.h,$^) $(LDFLAGS) -shared -o $@
|
||||
$(if $(postbuild),$(postbuild) $@)
|
||||
|
||||
$(bindir)/library-cxx$(libsuffix): $(srcdir)/whereami++.cpp $(srcdir)/whereami++.h $(exampledir)/library.cpp
|
||||
mkdir -p $(@D)
|
||||
$(CXX) -x c++ -I $(srcdir) $(CPPFLAGS) $(CXXFLAGS) $(filter-out %.h,$^) $(LDFLAGS) -shared -o $@
|
||||
$(if $(postbuild),$(postbuild) $@)
|
||||
|
101
example/executable.cpp
Normal file
101
example/executable.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <whereami++.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push, 3)
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
#define RTLD_LAZY 1
|
||||
#define RTLD_NOW 2
|
||||
#define RTLD_GLOBAL 4
|
||||
#define RTLD_LOCAL 8
|
||||
|
||||
static void* dlopen(const char* fileName, int mode)
|
||||
{
|
||||
wchar_t buffer[MAX_PATH];
|
||||
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, fileName, -1, buffer, sizeof(buffer) / sizeof(*buffer)))
|
||||
{
|
||||
wchar_t buffer_[MAX_PATH];
|
||||
|
||||
GetFullPathNameW(buffer, sizeof(buffer_) / sizeof(*buffer_), buffer_, NULL);
|
||||
|
||||
return (void*)LoadLibraryW(buffer_);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int dlclose(void* handle)
|
||||
{
|
||||
return FreeLibrary((HMODULE)handle) ? 0 : -1;
|
||||
}
|
||||
|
||||
static const char* dlerror(void)
|
||||
{
|
||||
DWORD error;
|
||||
|
||||
error = GetLastError();
|
||||
|
||||
if (error)
|
||||
{
|
||||
static char message[1024];
|
||||
|
||||
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), message, sizeof(message), NULL);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
return "no error";
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#endif
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::cout << "executable path: " << whereami::getExecutablePath() << std::endl;
|
||||
whereami::whereami_path_t executablePath = whereami::getExecutablePath();
|
||||
std::cout << " dirname: " << executablePath.dirname() << std::endl;
|
||||
std::cout << " basename: " << executablePath.basename() << std::endl;
|
||||
|
||||
std::cout << "module path: " << whereami::getModulePath() << std::endl;
|
||||
whereami::whereami_path_t modulePath = whereami::getModulePath();
|
||||
std::cout << " dirname: " << modulePath.dirname() << std::endl;
|
||||
std::cout << " basename: " << modulePath.basename() << std::endl;
|
||||
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
std::string prefix = "--load-library=";
|
||||
std::string arg = std::string(argv[i]);
|
||||
|
||||
if (arg.compare(0, prefix.length(), prefix) == 0)
|
||||
{
|
||||
std::string name = arg.substr(prefix.length());
|
||||
void* handle;
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
handle = dlopen(name.c_str(), RTLD_NOW);
|
||||
if (!handle)
|
||||
std::cout << "failed to load library: " << dlerror() << std::endl;
|
||||
|
||||
if (handle)
|
||||
dlclose(handle);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
61
example/library.cpp
Normal file
61
example/library.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <whereami++.h>
|
||||
|
||||
#if defined(__GNUC__) && !defined(_WIN32)
|
||||
__attribute__((constructor))
|
||||
#endif
|
||||
static void load()
|
||||
{
|
||||
std::cout << "library loaded" << std::endl;
|
||||
|
||||
std::cout << "executable path: " << whereami::getExecutablePath() << std::endl;
|
||||
whereami::whereami_path_t executablePath = whereami::getExecutablePath();
|
||||
std::cout << " dirname: " << executablePath.dirname() << std::endl;
|
||||
std::cout << " basename: " << executablePath.basename() << std::endl;
|
||||
|
||||
std::cout << "module path: " << whereami::getModulePath() << std::endl;
|
||||
whereami::whereami_path_t modulePath = whereami::getModulePath();
|
||||
std::cout << " dirname: " << modulePath.dirname() << std::endl;
|
||||
std::cout << " basename: " << modulePath.basename() << std::endl;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && !defined(_WIN32)
|
||||
__attribute__((destructor))
|
||||
#endif
|
||||
static void unload()
|
||||
{
|
||||
std::cout << "library unloaded" << std::endl;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push, 3)
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
load();
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
unload();
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
104
src/whereami++.cpp
Normal file
104
src/whereami++.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
// (‑●‑●)> released under the WTFPL v2 license, by Gregory Pakosz (@gpakosz)
|
||||
// https://github.com/gpakosz/whereami
|
||||
|
||||
// in case you want to #include "whereami++.cpp" in a larger compilation unit
|
||||
#if !defined(WHEREAMIPP_H)
|
||||
#include <whereami++.h>
|
||||
#endif
|
||||
|
||||
namespace whereami {
|
||||
|
||||
namespace {
|
||||
#define WHEREAMI_H
|
||||
#define WAI_FUNCSPEC
|
||||
#define WAI_PREFIX(function) function
|
||||
#include "whereami.c"
|
||||
}
|
||||
|
||||
whereami_string_t whereami_path_t::dirname() const
|
||||
{
|
||||
return path.substr(0, dirname_length);
|
||||
}
|
||||
|
||||
whereami_string_t whereami_path_t::basename() const
|
||||
{
|
||||
return path.substr(dirname_length + 1);
|
||||
}
|
||||
|
||||
#if defined(WHEREAMI_CXX11)
|
||||
whereami_path_t::operator whereami_string_t() &&
|
||||
{
|
||||
return std::move(path);
|
||||
}
|
||||
|
||||
whereami_path_t::operator whereami_string_t() const &
|
||||
{
|
||||
return path;
|
||||
}
|
||||
#else
|
||||
whereami_path_t::operator const whereami_string_t&() const
|
||||
{
|
||||
return path;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WHEREAMI_CXX11)
|
||||
whereami_path_t::whereami_path_t(whereami_string_t&& path, int dirname_length) noexcept
|
||||
: path(std::move(path)), dirname_length(dirname_length)
|
||||
{
|
||||
}
|
||||
#else
|
||||
whereami_path_t::whereami_path_t(whereami_string_t& path, int dirname_length)
|
||||
: path(path), dirname_length(dirname_length)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(WHEREAMI_DISABLE_OSTREAM)
|
||||
std::ostream& operator<<(std::ostream& os, const whereami_path_t& path)
|
||||
{
|
||||
return os << path.path;
|
||||
}
|
||||
|
||||
#endif
|
||||
WAI_FUNCSPEC
|
||||
whereami_path_t getExecutablePath()
|
||||
{
|
||||
whereami_string_t path;
|
||||
int dirname_length = -1;
|
||||
|
||||
int length = getExecutablePath(0, 0, 0);
|
||||
if (length != -1)
|
||||
{
|
||||
path.resize(length);
|
||||
getExecutablePath(&path[0], length, &dirname_length);
|
||||
}
|
||||
|
||||
#if defined(WHEREAMI_CXX11)
|
||||
return whereami_path_t(std::move(path), dirname_length);
|
||||
#else
|
||||
return whereami_path_t(path, dirname_length);
|
||||
#endif
|
||||
}
|
||||
|
||||
WAI_FUNCSPEC
|
||||
whereami_path_t getModulePath()
|
||||
{
|
||||
whereami_string_t path;
|
||||
int dirname_length = -1;
|
||||
|
||||
int length = getModulePath(0, 0, 0);
|
||||
if (length != -1)
|
||||
{
|
||||
path.resize(length);
|
||||
getModulePath(&path[0], length, &dirname_length);
|
||||
}
|
||||
|
||||
#if defined(WHEREAMI_CXX11)
|
||||
return whereami_path_t(std::move(path), dirname_length);
|
||||
#else
|
||||
return whereami_path_t(path, dirname_length);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace whereami
|
67
src/whereami++.h
Normal file
67
src/whereami++.h
Normal file
@ -0,0 +1,67 @@
|
||||
// (‑●‑●)> released under the WTFPL v2 license, by Gregory Pakosz (@gpakosz)
|
||||
// https://github.com/gpakosz/whereami
|
||||
|
||||
#ifndef WHEREAMIPP_H
|
||||
#define WHEREAMIPP_H
|
||||
|
||||
#if !defined(WHEREAMI_STRING_T)
|
||||
#include <string>
|
||||
typedef std::string whereami_string_t;
|
||||
#else
|
||||
typedef WHEREAMI_STRING_T whereami_string_t;
|
||||
#endif
|
||||
#if !defined(WHEREAMI_DISABLE_OSTREAM)
|
||||
#include <ostream>
|
||||
#endif
|
||||
|
||||
#if (defined (__cplusplus) && (__cplusplus > 199711L)) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706))
|
||||
#define WHEREAMI_CXX11
|
||||
#endif
|
||||
|
||||
namespace whereami {
|
||||
|
||||
class whereami_path_t
|
||||
{
|
||||
public:
|
||||
#if defined(WHEREAMI_CXX11)
|
||||
operator whereami_string_t() &&;
|
||||
operator whereami_string_t() const &;
|
||||
#else
|
||||
operator const whereami_string_t&() const;
|
||||
#endif
|
||||
whereami_string_t dirname() const;
|
||||
whereami_string_t basename() const;
|
||||
|
||||
private:
|
||||
whereami_path_t();
|
||||
|
||||
#if defined(WHEREAMI_CXX11)
|
||||
whereami_path_t(whereami_string_t&& path, int dirname_length) noexcept;
|
||||
#else
|
||||
whereami_path_t(whereami_string_t& path, int dirname_length);
|
||||
#endif
|
||||
|
||||
friend whereami_path_t getExecutablePath();
|
||||
friend whereami_path_t getModulePath();
|
||||
#if !defined(WHEREAMI_DISABLE_OSTREAM)
|
||||
friend std::ostream& operator<<(std::ostream& os, const whereami_path_t& path);
|
||||
#endif
|
||||
|
||||
whereami_string_t path;
|
||||
int dirname_length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the path to the current executable.
|
||||
*/
|
||||
whereami_path_t getExecutablePath();
|
||||
|
||||
/**
|
||||
* Returns the path to the current module.
|
||||
*/
|
||||
whereami_path_t getModulePath();
|
||||
|
||||
} // namespace whereami
|
||||
|
||||
#endif // #ifndef WHEREAMIPP_H
|
||||
|
@ -10,6 +10,13 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef WAI_FUNCSPEC
|
||||
#define WAI_FUNCSPEC
|
||||
#endif
|
||||
#ifndef WAI_PREFIX
|
||||
#define WAI_PREFIX(function) wai_##function
|
||||
#endif
|
||||
|
||||
#if !defined(WAI_MALLOC) || !defined(WAI_FREE) || !defined(WAI_REALLOC)
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
@ -38,7 +38,7 @@ WAI_FUNCSPEC
|
||||
int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length);
|
||||
|
||||
/**
|
||||
* Returns the path to the current module
|
||||
* Returns the path to the current module.
|
||||
*
|
||||
* Usage:
|
||||
* - first call `int length = wai_getModulePath(NULL, 0, NULL);` to retrieve
|
||||
|
Loading…
Reference in New Issue
Block a user