mkdir buildx64
cd buildx64
cmake ..
cd ..
mkdir build
cd build
cmake .. -A Win32
cd ..
#include "kminwindef.h"
#include "kIrrCompileConfig.h"
#ifdef _KIRR_WINDOWS_
#ifdef _KIRR_ANDROID_PLATFORM_
#ifdef _KIRR_WINDOWS_API_
// 常用的几个。
#ifdef _MSC_VER /* Visual Studio */
#ifdef __ANDROID__
// 不常用不建议采用的。
#ifdef _WIN32 // _WINDOWS
Linux 为 srandom 和 random 函数,Windows 为 srand 和 rand 函数。
Linux 为 snprintf,Windows 为 _snprintf。
同理,Linux 中的 strcasecmp,Windows 为 _stricmp。
Linux 中,time_t 结构是长整形。而 windows 中,time_t 结构是 64 位的整形。如果要在 windows 始 time_t 为 32 位无符号整形,可以加宏定义,_USE_32BIT_TIME_T。
Linux 中,sleep 的单位为秒。Windows 中,Sleep 的单位为毫秒。即,Linux 下 sleep (1),在 Windows 环境下则需要 Sleep (1000)。
Windows 中的 timecmp 宏,不支持大于等于或者小于等于。
Windows 中没有 struct timeval 结构的加减宏可以使用,需要手动定义:
#define MICROSECONDS (1000 * 1000)
#define timeradd(t1, t2, t3) do { \
(t3)->tv_sec = (t1)->tv_sec + (t2)->tv_sec; \
(t3)->tv_usec = (t1)->tv_usec + (t2)->tv_usec % MICROSECONDS; \
if ((t1)->tv_usec + (t2)->tv_usec > MICROSECONDS) (t3)->tv_sec ++; \
} while (0)
#define timersub(t1, t2, t3) do { \
(t3)->tv_sec = (t1)->tv_sec - (t2)->tv_sec; \
(t3)->tv_usec = (t1)->tv_usec - (t2)->tv_usec; \
if ((t1)->tv_usec - (t2)->tv_usec < 0) (t3)->tv_usec --, (t3)->tv_usec += MICROSECONDS; \
} while (0)
Android、Linux 实现 Windows API:
DWORD WINAPI GetTickCount(VOID) {
struct timespec ts{};
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
return 0;
}
DWORD theTick;
theTick = ts.tv_nsec / 1000000;
theTick += ts.tv_sec * 1000;
return theTick;
}
ULONGLONG WINAPI GetTickCount64(VOID) {
struct timespec ts{};
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
return 0;
}
ULONGLONG theTick;
theTick = ts.tv_nsec / 1000000;
theTick += ts.tv_sec * 1000;
return theTick;
}
Linux 与 Windows 下面,均可以使用 stat 调用来查询文件信息。但是,Linux 只支持 2G 大小,而 Windows 只支持 4G 大小。 为了支持更大的文件查询,可以在 Linux 环境下加 _FILE_OFFSET_BITS=64 定义,在 Windows 下面使用 _stat64 调用,入参为 struct __stat64。
Linux 中可根据 stat 的 st_mode 判断文件类型,有 S_ISREG、S_ISDIR 等宏。Windows 中没有,需要自己定义相应的宏,如
#define S_ISLNK(m) (((m) & 00170000) == 0120000)
#define S_ISREG(m) (((m) & 00170000) == 0100000)
#define S_ISDIR(m) (((m) & 00170000) == 0040000)
#define S_ISCHR(m) (((m) & 00170000) == 0020000)
#define S_ISBLK(m) (((m) & 00170000) == 0060000)
#define S_ISFIFO(m) (((m) & 00170000) == 0010000)
#define S_ISSOCK(m) (((m) & 00170000) == 0140000)
Linux 中删除文件是 unlink,Windows 中为 DeleteFile。
// exdir 表示进行文件夹检查,不能是 文件夹
bool IsFilePathExists(const char* path, bool exdir)
{
int code = ::access(path, 0);
if (0 == code) {
if (exdir && IsDirectory(path)) {
return false;
}
return true;
}
return false;
}
bool IsFileRegular(const std::string &path) {
struct stat st;
if (stat(path.c_str(), &st))
return false;
return S_ISREG(st.st_mode);
}
bool IsDirectory(const std::string &path)
{
struct stat st;
if (stat(path.c_str(), &st))
return false;
return S_ISDIR(st.st_mode);
}
#include "pch.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string>
#include <iostream>
#include <assert.h>
#include <kIrrCompileConfig.h>
#ifdef _MSC_VER
#include <EGL/egl.h>
#include <EGL/eglplatform.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2platform.h>
#else
#include <EGL/egl.h>
#include <GLES/gl.h> // for glPointParameterf
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
//#include <GLES3/gl3.h> // for glReadBuffer
#define MAX_PATH 256
#include <dlfcn.h>
#endif
#include "fkdriver.h"
#include "fakedriverAdapter.h"
#include "fakehook.h"
#include "kminwindef.h"
#ifdef _KIRR_WINDOWS_
std::wstring getCurrentPath() {
wchar_t fpath[MAX_PATH];
DWORD dwRet = GetModuleFileName(NULL, fpath, MAX_PATH);
std::wstring fdir = fpath;
int index = fdir.rfind('\\');
return fdir.substr(0, index);
}
HINSTANCE getLibrary(const TCHAR* libPath) {
std::wstring current = getCurrentPath();
current.append(libPath);
int index = current.rfind('\\');
std::wstring curdir = current.substr(0, index);
WCHAR lpBuffer[MAX_PATH];
GetCurrentDirectory(MAX_PATH, lpBuffer);
SetCurrentDirectory(curdir.c_str());
HINSTANCE hDLL = LoadLibrary(current.c_str());
SetCurrentDirectory(lpBuffer);
if (hDLL == nullptr) {
int err = GetLastError();
return nullptr;
}
return hDLL;
}
// Mali Adreno PowerVR
void* getEGLFunction(EnumFakeDriverHookFunction fid, const char* fname) {
const wchar_t* libPath = getFakeDriverAdapterPath();
static HINSTANCE hDLL = getLibrary(libPath);
if (hDLL == nullptr) {
int err = GetLastError();
return nullptr;
}
fname = getFunctionName(fid);
FARPROC fptr = GetProcAddress(hDLL, fname);
if (fptr == nullptr) {
int err = GetLastError();
return nullptr;
}
return fptr;
}
extern "C" IMAGE_DOS_HEADER __ImageBase;
void* getCurrentEGLFunction(EnumFakeDriverHookFunction fid) {
static HMODULE module = reinterpret_cast<HMODULE>(&__ImageBase);
PROC result = GetProcAddress(module, getFunctionName(fid));
return result;
}
PROC getCurrentProcAddress(EnumFakeDriverHookFunction fid) {
static HMODULE module = reinterpret_cast<HMODULE>(&__ImageBase);
PROC result = GetProcAddress(module, getFunctionName(fid));
return result;
}
#else
void* getProcAddress(void* handle, EnumFakeDriverHookFunction fid) {
if (handle == nullptr) {
char* err = dlerror();
return nullptr;
}
const char* fname = getFunctionName(fid);
char buffer[MAX_PATH] = { 0 };
for (int i = 0; i < strlen(fname); i++) {
buffer[i] = fname[i];
if (buffer[i] == '@') {
buffer[i] = 0;
break;
}
}
void* fptr = dlsym(handle, &buffer[1]);
if (fptr == nullptr) {
char* err = dlerror();
return nullptr;
}
return fptr;
}
void* getCurrentEGLFunction(EnumFakeDriverHookFunction fid) {
static void* handle = dlopen("libfakedriver.so", RTLD_LAZY); // dlclose(handle);
return getProcAddress(handle, fid);
}
void* getEGLFunction(EnumFakeDriverHookFunction fid, const char* fname) {
static void* handle = dlopen("libfakedriverAdapter.so", RTLD_LAZY); // dlclose(handle);
return getProcAddress(handle, fid);
}
#endif
Android:
#include <jni.h>
#include <string>
#include <dlfcn.h> // 关键头文件。
void* getProcAddress(void* handle, const char* fname) {
if (handle == nullptr) {
char* err = dlerror();
return nullptr;
}
void* fptr = dlsym(handle, fname);
if (fptr == nullptr) {
char* err = dlerror();
return nullptr;
}
return fptr;
}
void* getFunctionPtr(const char* fname) {
static void* handle = dlopen("libtest.so", RTLD_LAZY); // dlclose(handle);
return getProcAddress(handle, fname);
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_test_MainActivity_stringFromJNI(
JNIEnv* env,
jobject thiz) {
void* func = getFunctionPtr("Java_com_testEngine_platform",
"libtestEngine.so");
typedef jstring JNICALL (*FUNC)(JNIEnv* env, jobject /* this */);
FUNC myfunc = (FUNC) func;
jstring retv = myfunc(env, thiz);
return retv;
//std::string hello = "Hello from C++";
//return env->NewStringUTF(hello.c_str());
}
https://blog.csdn.net/qq_36810544/article/details/84329132
https://codeproject.freetls.fastly.net/Articles/1146/CString-clone-Using-Standard-C
https://blog.csdn.net/jzkdl/article/details/80196309