Does Xamarin have an #if or #ifdef for determining the platform? - cross-platform

For example, #ifdef iOS, #ifdef android, or the like. If there is #if, that would be even better.

iOS:
#if __MOBILE__
Console.WriteLine ("__MOBILE__ is defined");
#endif
#if __IOS__
Console.WriteLine ("__IOS__ is defined");
#endif
Android:
#if __MOBILE__
Console.WriteLine ("__MOBILE__ is defined");
#endif
#if __ANDROID__
Console.WriteLine ("__ANDROID__ is defined");
#endif
https://bugzilla.xamarin.com/show_bug.cgi?id=6459#c12
xamarin documentation

Yes it does, I don't know, if Xamarin.iOS provides its own symbols, as I'm new to Xamarin and I actually do not use Xamarin.iOS, but you can define your own symbols.
Right click on the project an open the project options. In the "Compiler" settings you can lookup existing flags and create add new ones.
For example here are the symbols that are shipped with Xamarin.Android:
DEBUG;__MOBILE__;__ANDROID__;
The flags should be available immediately after you have defined them.

Related

Objective C - How to check if Executable can be launched (eg. terminal)

I am currently building an Executable handling application in Objective C and I just wanna know a simple code that can determine if an executable file can be launched (without launching it) or if it is just a loadable one.
Thanks.
Once you've taken care of permission bits and whether the file is a Mach-O, there are three things you need to consider:
File type
CPU compatibility
Fat binaries
File type
Whether your Mach-O is an executable, dylib, kext, etc., can be determined from a field in its header.
From <mach-o/loader.h>:
struct mach_header {
uint32_t magic;
cpu_type_t cputype;
cpu_subtype_t cpusubtype;
uint32_t filetype; // <---
uint32_t ncmds;
uint32_t sizeofcmds;
uint32_t flags;
};
Also from <mach-o/loader.h> you get all possible values for that field:
#define MH_OBJECT 0x1 /* relocatable object file */
#define MH_EXECUTE 0x2 /* demand paged executable file */
#define MH_FVMLIB 0x3 /* fixed VM shared library file */
#define MH_CORE 0x4 /* core file */
#define MH_PRELOAD 0x5 /* preloaded executable file */
#define MH_DYLIB 0x6 /* dynamically bound shared library */
#define MH_DYLINKER 0x7 /* dynamic link editor */
#define MH_BUNDLE 0x8 /* dynamically bound bundle file */
#define MH_DYLIB_STUB 0x9 /* shared library stub for static linking only, no section contents */
#define MH_DSYM 0xa /* companion file with only debug sections */
#define MH_KEXT_BUNDLE 0xb /* x86_64 kexts */
CPU compatibility
Just because it says "executable", doesn't mean it can be launched though. If you take an iOS app and try to execute it on your iMac, you'll get a "Bad CPU type in executable" error message.
The different CPU types are defined in <mach/machine.h>, but the only of comparing against the current CPU type is via defines:
#include <mach/machine.h>
bool is_cpu_compatible(cpu_type_t cputype)
{
return
#ifdef __i386__
cputype == CPU_TYPE_X86
#endif
#ifdef __x86_64__
cputype == CPU_TYPE_X86 || cputype == CPU_TYPE_X86_64
#endif
#ifdef __arm__
cputype == CPU_TYPE_ARM
#endif
#if defined(__arm64__)
cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64
#endif
;
}
(This will only work if your application has 64-bit slices, so that it always runs as 64-bit when it can. If you want to be able to run as a 32-bit binary and detect whether a 64-bit binary could be run, you'd have to use sysctl on "hw.cpu64bit_capable" together with defined, but then it gets even uglier.)
Fat binaries
Lastly, your binaries could be enclosed in fat headers. If so, you'll simply need to iterate over all slices, find the one corresponding to your current architecture, and check the two conditions above for that.
Implementation
There is no Objective-C API for this that I know of, so you'll have to fall back to C.
Given a pointer to the file's contents and the is_cpu_compatible function from above, you could do it like this:
#include <stdbool.h>
#include <stddef.h>
#include <mach-o/fat.h>
#include <mach-o/loader.h>
bool macho_is_executable(char *file)
{
struct fat_header *fat = (struct fat_header*)file;
// Fat file
if(fat->magic == FAT_CIGAM) // big endian magic
{
struct fat_arch *arch = (struct fat_arch*)(fat + 1);
for(size_t i = 0; i < fat->nfat_arch; ++i)
{
if(is_cpu_compatible(arch->cputype))
{
return macho_is_executable(&file[arch->offset]);
}
}
// File is not for this architecture
return false;
}
// Thin file
struct mach_header *hdr32 = (struct mach_header*)file;
struct mach_header_64 *hdr64 = (struct mach_header_64*)file;
if(hdr32->magic == MH_MAGIC) // little endian magic
{
return hdr32->filetype == MH_EXECUTE && is_cpu_compatible(hdr32->cputype);
}
else if(hdr64->magic == MH_MAGIC_64)
{
return hdr64->filetype == MH_EXECUTE && is_cpu_compatible(hdr64->cputype);
}
// Not a Mach-O
return false;
}
Note that these are still rather basic checks though, which will e.g. not detect corrupt Mach-O's, and which could easily be fooled by malicious files. If you wanted that, you would have to either emulate an operating system and launch the binary within, or get into the research field of theoretical IT and revolutionize the mathematics of provability.
My understanding is you want to distinguish a Mach-O standalone executable from a Mach-O dyld library. A standalone executable will use either:
LC_MAIN load command to denote the entry point, supported since MacOS 10.7
LC_UNIXTHREAD load command , older non-dyld approach to do the same (still supported)
A dyld library will not have either of these Mach-O load commands, so if you detect one of them it means it's a runnable standalone executable. That of course does not imply the binary executable is valid and kernel won't kill it for other reasons.
If you want inspect some test files to verify it I recommend using a free tool called MachOView

make mosquitto-auth-plug on windows

I am currently trying to build the mosquitto-auth-plugin on windows but I am unsure which make process to use. The doc says to edit the config.mk file which I have done, then to 'make' the auth-plug -- this is were I am struck I have tried to make using GnWin & MinGW but neither has worked is there a way to build-make the library on windows or can I make it in Linux and copy the auth-plug.o to my windows machine?
I'm not aware of anybody having attempted to build mosquitto-auth-plug on Windows, and I'd be very surprised if that worked at all; as the author of the plugin, I paid no attention to portability outside Un*x, and so as to not raise hopes, I will not. :-)
That said, you cannot run (load) shared objects built on Linux on Windows. What may be possible, but it's been years since I did anything similar, is to cross compile with an appropriate toolchain.
I build it for Windows, using the HTTP and JWT backends only.
Had to fix:
Put __declspec(dllexport) to the mosquitto_auth_Xyz... functions in auth-plug.c.
Added alternative code for fnmatch(a,b) and strsep() in auth-plug.c, see below.
In log.c I fell back to use log=__log instead of log=mosquitto_log_printf as I failed importing the function from libmosquitto.
Compiled using Visual Studio 2017 Express with preprocessor definitions _CRT_NONSTDC_NO_DEPRECATE and _CRT_SECURE_NO_WARNINGS put into place.
The code works fine!
For fnmatch(a,b) and strsep() in auth-plug.c change the #include to:
#ifdef _WIN32
#include <windows.h>
#include <shlwapi.h>
#define fnmatch(a, b, c) PathMatchSpecA(a, b)
extern char* strsep(char** stringp, const char* delim)
{
char* start = *stringp;
char* p;
p = (start != NULL) ? strpbrk(start, delim) : NULL;
if (p == NULL)
{
*stringp = NULL;
}
else
{
*p = '\0';
*stringp = p + 1;
}
return start;
}
#else
#include <fnmatch.h>
#endif

Turn on autocompletion in macros

I would love to have autocomplete in macros like for example,
#ifdef DEBUG
static void print_debug_info(object obj) {
...
}
#endif
Using a near-default configuration of AppCode, it doesn't appear this is enabled. Is there anyway to enable it?

CMake adds -Dlibname_EXPORTS compile definition

CMake adds the following compile definition to all source code files automatically when simply compiling a target:
-Dlibname_EXPORTS
Why is this done and how can I disable it?
cmake add <libname>_EXPORTS macros only for shared libraries. It's useful when exporting API's in Windows DLL.
#if defined(_WINDOWS) && defined(testlib_EXPORTS)
# define API_DLL extern "C" __declspec(dllexport)
#else
# define API_DLL
#endif
API_DLL void foo();
It could be disabled by setting the DEFINE_SYMBOL property of target to empty.
# disable the <libname>_EXPORTS
set_target_properties(sharedlib
PROPERTIES
DEFINE_SYMBOL ""
)
Reference
http://www.cmake.org/cmake/help/v3.0/prop_tgt/DEFINE_SYMBOL.html

How do I pass QMainWindow resize events down to a QGLWidget contained in the QMainWindow?

Initially, I followed the structure of http://qt-project.org/wiki/How_to_use_OpenGL_Core_Profile_with_Qt. I created a vanilla Visual Studio 2010 Qt application project, clicked on the .ui file to start Qt Designer, inserted a QWidget and promoted it to myglwidget. I then created a myglwidget subclass of QGLWidget.
That worked fine, and I got my red triangle.
The issue is that myglwidget doesn't get any of the resize events when the main window is resized, even if I set the widget size properties to "expanding."
And when I restructure my app constructor to call setCentralWidget(&myglwidget_) the code compiles and runs but no OpenGL window appears.
I'm not seeing how to resize my widget to match the main window size. I'm also not understanding why the setCentralWidget approach didn't work.
I believe I know how to solve the problem by writing explicit Qt code, but that defeats the purpose of my trying to build an OpenGL app in Qt using Qt Designer.
The following code for the application "baz6" fixes the problem. The code I inserted in the wizard-generated code is flagged with //***
baz6.h:
#ifndef BAZ6_H
#define BAZ6_H
#include <QtGui/QMainWindow>
#include "ui_baz6.h"
#include "myglwidget.h" //***
#include <QResizeEvent>
class baz6 : public QMainWindow
{
Q_OBJECT
public:
baz6(QWidget *parent = 0, Qt::WFlags flags = 0);
~baz6();
private:
Ui::baz6Class ui;
myGLWidget *myglwidget_; //***
};
#endif // BAZ6_H
baz6.c:
#include "baz6.h"
#include "myglwidget.h"
baz6::baz6(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
myglwidget_ = new myGLWidget(); //***
setCentralWidget(myglwidget_); //***
}
baz6::~baz6()
{
}
Previously, I had not explicitly constructed the myGLWidget.