2025-01-22 16:18:30 +01:00

1028 lines
22 KiB
C++

#include <hxcpp.h>
#include <stdio.h>
#include <hx/Memory.h>
#include <hx/OS.h>
#define IGNORE_CFFI_API_H
#include <hx/CFFI.h>
#include <map>
#include <string>
#ifdef _MSC_VER
#pragma warning( disable : 4190 )
#endif
// Class for boxing external handles
namespace hx
{
class Abstract_obj : public Object
{
public:
HX_IS_INSTANCE_OF enum { _hx_ClassId = hx::clsIdAbstract };
Abstract_obj(int inType,void *inData)
{
mType = inType;
mHandle = inData;
mFinalizer = 0;
mMarkSize = 0;
}
Abstract_obj(int inType,int inSize, finalizer inFinalizer)
{
mType = inType;
mFinalizer = 0;
mMarkSize = 0;
mHandle = 0;
if (inSize)
{
mMarkSize = inSize;
mHandle = HxAlloc(inSize);
memset(mHandle,0,mMarkSize);
}
SetFinalizer(inFinalizer);
}
virtual int __GetType() const { return mType; }
virtual hx::ObjectPtr<hx::Class_obj> __GetClass() const { return 0; }
virtual bool __IsClass(hx::Class inClass ) const { return false; }
virtual void *__GetHandle() const
{
return mHandle;
}
void __Mark(hx::MarkContext *__inCtx)
{
HX_MARK_MEMBER(_hxcpp_toString);
if (mMarkSize>=sizeof(void *) && mHandle)
{
hx::MarkConservative((int *)mHandle, ((int *)mHandle) + (mMarkSize/sizeof(int)), __inCtx );
}
}
#ifdef HXCPP_VISIT_ALLOCS
void __Visit(hx::VisitContext *__inCtx)
{
HX_VISIT_MEMBER(_hxcpp_toString);
if (mFinalizer)
mFinalizer->Visit(__inCtx);
}
#endif
void SetFinalizer(finalizer inFinalizer)
{
if (!inFinalizer)
{
if (mFinalizer)
mFinalizer->Detach();
mFinalizer = 0;
}
else
{
if (!mFinalizer)
mFinalizer = new hx::InternalFinalizer(this);
mFinalizer->mFinalizer = inFinalizer;
}
}
void Clear()
{
SetFinalizer(0);
mType = 0;
if (mMarkSize && mHandle)
HxFree(mHandle);
mHandle = 0;
}
String toString()
{
if (_hxcpp_toString.mPtr)
return _hxcpp_toString( Dynamic(this) );
char buffer[40];
sprintf(buffer,"0x%p", mHandle);
return HX_CSTRING("Abstract(") +
__hxcpp_get_kind(this) +
HX_CSTRING(":") +
String::create(buffer,strlen(buffer)) +
HX_CSTRING(")");
}
hx::Val __Field(const String &inString, hx::PropertyAccess inCallProp)
{
if (inString==HX_CSTRING("_hxcpp_toString")) return _hxcpp_toString;
if (inString==HX_CSTRING("_hxcpp_kind")) return __hxcpp_get_kind(this);
return hx::Object::__Field(inString, inCallProp);
}
hx::Val __SetField(const String &inName,const hx::Val &inValue, hx::PropertyAccess inCallProp)
{
if (inName==HX_CSTRING("_hxcpp_toString"))
{
_hxcpp_toString = inValue;
return inValue;
}
return hx::Object::__SetField(inName, inValue,inCallProp);
}
Dynamic _hxcpp_toString;
hx::InternalFinalizer *mFinalizer;
void *mHandle;
int mType;
int mMarkSize;
};
typedef ObjectPtr<Abstract_obj> Abstract;
} // end namespace hx
vkind k_int32 = (vkind)vtAbstractBase;
vkind k_hash = (vkind)(vtAbstractBase + 1);
vkind k_cpp_pointer = (vkind)(vtAbstractBase + 2);
vkind k_cpp_struct = (vkind)(vtAbstractBase + 3);
vkind k_cpp_objc = (vkind)(vtAbstractBase + 4);
static int sgKinds = (int)(vtAbstractBase + 5);
typedef std::map<std::string,int> KindMap;
typedef std::map<int,std::string> ReverseKindMap;
static KindMap sgKindMap;
static ReverseKindMap sgReverseKindMap;
int hxcpp_alloc_kind()
{
return ++sgKinds;
}
void hxcpp_kind_share(int &ioKind,const char *inName)
{
int &kind = sgKindMap[inName];
if (kind==0)
kind = hxcpp_alloc_kind();
ioKind = kind;
sgReverseKindMap[kind] = inName;
}
String __hxcpp_get_kind(Dynamic inObject)
{
int type = inObject->__GetType();
if (type<vtAbstractBase)
return null();
if (type==(int)(size_t)k_cpp_pointer)
return HX_CSTRING("cpp.Pointer");
ReverseKindMap::const_iterator it = sgReverseKindMap.find(type);
if (it==sgReverseKindMap.end())
return null();
return String::create(it->second.c_str(), it->second.size());
}
#ifndef __clang__
#pragma warning( disable : 4290 )
#endif
// #define THROWS throw(Dynamic)
#define THROWS
//#define THROWS throw(Dynamic)
#define THROWS
extern "C" {
/*
This bit of Macro magic is used to define extern function pointers
in ndlls, define stub implementations that link back to the hxcpp dll
and glue up the implementation in the hxcpp runtime.
For the static link case, these functions are linked directly.
*/
void hx_error() THROWS
{
hx::Throw( HX_CSTRING("ERROR") );
}
void val_throw(hx::Object * arg1) THROWS
{
if (arg1==0)
hx::Throw( null() );
hx::Throw( arg1 );
}
void hx_fail(const char * inMessage,const char * inFile,int inLine)
{
if (inFile!=0 && inLine!=0)
hx::Throw( HX_CSTRING("Failure ") + String(inMessage) + HX_CSTRING(" @ ") +
String(inFile) + HX_CSTRING(":") + Dynamic(inLine) );
else
hx::Throw( HX_CSTRING("Failure ") + String(inMessage) );
}
// Determine hx::Object * type
int val_type(hx::Object * arg1)
{
if (arg1==0)
return valtNull;
return arg1->__GetType();
}
\
vkind val_kind(hx::Object * arg1) THROWS
{
if (arg1==0)
hx::Throw( HX_CSTRING("Value has no 'kind'") );
int type = arg1->__GetType();
if (type<valtAbstractBase)
hx::Throw( HX_CSTRING("Value has no 'kind'") );
return (vkind)(intptr_t)(type);
}
void * val_to_kind(hx::Object * arg1,vkind arg2)
{
if (arg1==0)
return 0;
if ((int)(intptr_t)arg2 == arg1->__GetType())
return arg1->__GetHandle();
return 0;
}
// don't check the 'kind' ...
void * val_data(hx::Object * arg1)
{
if (arg1==0)
return 0;
return arg1->__GetHandle();
}
int val_fun_nargs(hx::Object * arg1)
{
if (arg1==0)
return faNotFunction;
return arg1->__ArgCount();
}
// Extract hx::Object * type
bool val_bool(hx::Object * arg1)
{
if (arg1==0) return false;
return arg1->__ToInt()!=0;
}
int val_int(hx::Object * arg1)
{
if (arg1==0) return 0;
return arg1->__ToInt();
}
double val_float(hx::Object * arg1)
{
if (arg1==0) return 0.0;
return arg1->__ToDouble();
}
double val_number(hx::Object * arg1)
{
if (arg1==0) return 0.0;
return arg1->__ToDouble();
}
// Create hx::Object * type
hx::Object * alloc_null() { return 0; }
hx::Object * alloc_bool(bool arg1) { return Dynamic(arg1).GetPtr(); }
hx::Object * alloc_int(int arg1) { return Dynamic(arg1).GetPtr(); }
hx::Object * alloc_float(double arg1) { return Dynamic(arg1).GetPtr(); }
hx::Object * alloc_empty_object() { return new hx::Anon_obj(); }
hx::Object * alloc_abstract(vkind arg1,void * arg2)
{
int type = (int)(intptr_t)arg1;
return new hx::Abstract_obj(type,arg2);
}
hx::Object *create_abstract(vkind inKind,int inMemSize, hx::finalizer inFree )
{
int type = (int)(intptr_t)inKind;
return new hx::Abstract_obj(type,inMemSize,inFree);
}
void free_abstract(hx::Object *obj)
{
if (obj)
{
hx::Abstract_obj *abstract = dynamic_cast<hx::Abstract_obj *>(obj);
if (abstract)
abstract->Clear();
}
}
hx::Object * alloc_best_int(int arg1) { return Dynamic(arg1).GetPtr(); }
hx::Object * alloc_int32(int arg1) { return Dynamic(arg1).GetPtr(); }
// String access
int val_strlen(hx::Object * arg1)
{
if (arg1==0) return 0;
return arg1->toString().length;
}
const wchar_t * val_wstring(hx::Object * arg1)
{
if (arg1==0) return L"";
return arg1->toString().__WCStr();
}
const char * val_string(hx::Object * arg1)
{
if (arg1==0) return "";
return arg1->__CStr();
}
hx::Object * alloc_string(const char * arg1)
{
return Dynamic( String::create(arg1) ).GetPtr();
}
hx::StringEncoding hxs_encoding(const String &str)
{
#ifdef HX_SMART_STRINGS
if (str.isUTF16Encoded())
return hx::StringUtf16;
else
return hx::StringAscii;
#else
return hx::StringUtf8;
#endif
}
wchar_t * val_dup_wstring(value inVal)
{
hx::Object *obj = (hx::Object *)inVal;
if (!obj)
return 0;
String s = obj->toString();
if (!s.raw_ptr())
return 0;
#ifdef HX_SMART_STRINGS
if ( sizeof(wchar_t)==2 && s.isUTF16Encoded())
{
wchar_t *result = (wchar_t *)hx::NewGCBytes(0,(s.length+1)*2);
memcpy(result, s.wchar_str(), s.length*2 );
result[s.length]=0;
return result;
}
#endif
return (wchar_t *)s.wchar_str();
}
char * val_dup_string(value inVal)
{
hx::Object *obj = (hx::Object *)inVal;
if (!obj) return 0;
String s = obj->toString();
if (!s.raw_ptr())
return 0;
#ifdef HX_SMART_STRINGS
if (s.isUTF16Encoded())
return (char *)s.utf8_str();
#endif
char *result = (char *)hx::NewGCBytes(0,s.length+1);
memcpy(result, s.raw_ptr(), s.length);
result[s.length] = 0;
return result;
}
char *alloc_string_data(const char *inData, int inLength)
{
char *result = (char *)hx::NewGCBytes(0,inLength+1);
if (inData)
{
memcpy(result, inData, inLength);
result[inLength] = 0;
}
return result;
}
hx::Object *alloc_string_len(const char *inStr,int inLen)
{
return Dynamic( String::create(inStr,inLen) ).GetPtr();
}
hx::Object *alloc_wstring_len(const wchar_t *inStr,int inLen)
{
String str = String::create(inStr,inLen);
return Dynamic(str).GetPtr();
}
// Array access - generic
int val_array_size(hx::Object * arg1)
{
if (arg1==0) return 0;
return arg1->__length();
}
hx::Object * val_array_i(hx::Object * arg1,int arg2)
{
if (arg1==0) return 0;
return arg1->__GetItem(arg2).GetPtr();
}
void val_array_set_i(hx::Object * arg1,int arg2,hx::Object *inVal)
{
if (arg1==0) return;
arg1->__SetItem(arg2, Dynamic(inVal) );
}
void val_array_set_size(hx::Object * arg1,int inLen)
{
#if (HXCPP_API_LEVEL<330)
if (arg1==0) return;
arg1->__SetSize(inLen);
#else
hx::ArrayBase *base = dynamic_cast<hx::ArrayBase *>(arg1);
if (base)
{
base->__SetSize(inLen);
}
else
{
cpp::VirtualArray_obj *va = dynamic_cast<cpp::VirtualArray_obj *>(arg1);
if (va)
va->__SetSize(inLen);
}
#endif
}
void val_array_push(hx::Object * arg1,hx::Object *inValue)
{
hx::ArrayBase *base = dynamic_cast<hx::ArrayBase *>(arg1);
if (base==0) return;
base->__push(inValue);
}
hx::Object * alloc_array(int arg1)
{
Array<Dynamic> array(arg1,arg1);
return array.GetPtr();
}
// Array access - fast if possible - may return null
// Resizing the array may invalidate the pointer
bool * val_array_bool(hx::Object * arg1)
{
#if (HXCPP_API_LEVEL>330)
hx::ArrayCommon *common = dynamic_cast< hx::ArrayCommon * >(arg1);
if (!common) return 0;
arg1 = common->__GetRealObject();
#endif
Array_obj<bool> *a = dynamic_cast< Array_obj<bool> * >(arg1);
if (a==0)
return 0;
return (bool *)a->GetBase();
}
int * val_array_int(hx::Object * arg1)
{
#if (HXCPP_API_LEVEL>330)
hx::ArrayCommon *common = dynamic_cast< hx::ArrayCommon * >(arg1);
if (!common) return 0;
arg1 = common->__GetRealObject();
#endif
Array_obj<int> *a = dynamic_cast< Array_obj<int> * >(arg1);
if (a==0)
return 0;
return (int *)a->GetBase();
}
double * val_array_double(hx::Object * arg1)
{
#if (HXCPP_API_LEVEL>330)
hx::ArrayCommon *common = dynamic_cast< hx::ArrayCommon * >(arg1);
if (!common) return 0;
arg1 = common->__GetRealObject();
#endif
Array_obj<double> *a = dynamic_cast< Array_obj<double> * >(arg1);
if (a==0)
return 0;
return (double *)a->GetBase();
}
float * val_array_float(hx::Object * arg1)
{
#if (HXCPP_API_LEVEL>330)
hx::ArrayCommon *common = dynamic_cast< hx::ArrayCommon * >(arg1);
if (!common) return 0;
arg1 = common->__GetRealObject();
#endif
Array_obj<float> *a = dynamic_cast< Array_obj<float> * >(arg1);
if (a==0)
return 0;
return (float *)a->GetBase();
}
value * val_array_value(hx::Object * arg1)
{
return 0;
}
typedef Array_obj<unsigned char> *ByteArray;
// Byte arrays
// The byte array may be a string or a Array<bytes> depending on implementation
buffer val_to_buffer(hx::Object * arg1)
{
ByteArray b = dynamic_cast< ByteArray >(arg1);
return (buffer)b;
}
bool val_is_buffer(value inVal) { return val_to_buffer((hx::Object *)inVal)!=0; }
buffer alloc_buffer(const char *inStr)
{
int len = inStr ? strlen(inStr) : 0;
ByteArray b = new Array_obj<unsigned char>(len,len);
if (len)
memcpy(b->GetBase(),inStr,len);
return (buffer)b;
}
buffer alloc_buffer_len(int inLen)
{
ByteArray b = new Array_obj<unsigned char>(inLen,inLen);
return (buffer)b;
}
value buffer_val(buffer b)
{
return (value)b;
}
value buffer_to_string(buffer inBuffer)
{
ByteArray b = (ByteArray) inBuffer;
String str(b->GetBase(),b->length);
Dynamic d(str);
return (value)d.GetPtr();
}
void buffer_append(buffer inBuffer,const char *inStr)
{
ByteArray b = (ByteArray)inBuffer;
int olen = b->length;
int len = strlen(inStr);
b->__SetSize(olen+len);
memcpy(b->GetBase()+olen,inStr,len);
}
int buffer_size(buffer inBuffer)
{
ByteArray b = (ByteArray)inBuffer;
return b->length;
}
void buffer_set_size(buffer inBuffer,int inLen)
{
ByteArray b = (ByteArray)inBuffer;
b->__SetSize(inLen);
}
void buffer_append_sub(buffer inBuffer,const char *inStr,int inLen)
{
ByteArray b = (ByteArray)inBuffer;
int olen = b->length;
b->__SetSize(olen+inLen);
memcpy(b->GetBase()+olen,inStr,inLen);
}
void buffer_append_char(buffer inBuffer,int inChar)
{
ByteArray b = (ByteArray)inBuffer;
b->Add(inChar);
}
char * buffer_data(buffer inBuffer)
{
ByteArray b = (ByteArray)inBuffer;
return b->GetBase();
}
// Append value to buffer
void val_buffer(buffer inBuffer,value inValue)
{
hx::Object *obj = (hx::Object *)inValue;
if (obj)
{
buffer_append(inBuffer, obj->toString().__CStr());
}
else
{
buffer_append_sub(inBuffer,"null",4);
}
}
// Call Function
hx::Object * val_call0(hx::Object * arg1) THROWS
{
if (!arg1) Dynamic::ThrowBadFunctionError();
return arg1->__run().GetPtr();
}
hx::Object * val_call0_traceexcept(hx::Object * arg1) THROWS
{
try
{
if (!arg1) Dynamic::ThrowBadFunctionError();
return arg1->__run().GetPtr();
}
catch(Dynamic e)
{
String s = e;
fprintf(stderr,"Fatal Error : %s\n",s.__CStr());
exit(1);
}
return 0;
}
hx::Object * val_call1(hx::Object * arg1,hx::Object * arg2) THROWS
{
if (!arg1) Dynamic::ThrowBadFunctionError();
return arg1->__run(arg2).GetPtr();
}
hx::Object * val_call2(hx::Object * arg1,hx::Object * arg2,hx::Object * arg3) THROWS
{
if (!arg1) Dynamic::ThrowBadFunctionError();
return arg1->__run(arg2,arg3).GetPtr();
}
hx::Object * val_call3(hx::Object * arg1,hx::Object * arg2,hx::Object * arg3,hx::Object * arg4) THROWS
{
if (!arg1) Dynamic::ThrowBadFunctionError();
return arg1->__run(arg2,arg3,arg4).GetPtr();
}
hx::Object * val_callN(hx::Object * arg1,hx::Object ** arg2, int nCount) THROWS
{
if (!arg1) Dynamic::ThrowBadFunctionError();
Array<Dynamic> args = Array_obj<Dynamic>::__new(0, nCount);
while (nCount--)
args << *arg2++;
return arg1->__Run( args ).GetPtr();
}
// Call object field
hx::Object * val_ocall0(hx::Object * arg1,int arg2) THROWS
{
if (!arg1) hx::Throw(HX_INVALID_OBJECT);
return arg1->__IField(arg2)->__run().GetPtr();
}
hx::Object * val_ocall1(hx::Object * arg1,int arg2,hx::Object * arg3) THROWS
{
if (!arg1) hx::Throw(HX_INVALID_OBJECT);
return arg1->__IField(arg2)->__run(arg3).GetPtr();
}
hx::Object * val_ocall2(hx::Object * arg1,int arg2,hx::Object * arg3,hx::Object * arg4) THROWS
{
if (!arg1) hx::Throw(HX_INVALID_OBJECT);
return arg1->__IField(arg2)->__run(arg3,arg4).GetPtr();
}
hx::Object * val_ocall3(hx::Object * arg1,int arg2,hx::Object * arg3,hx::Object * arg4,hx::Object * arg5) THROWS
{
if (!arg1) hx::Throw(HX_INVALID_OBJECT);
return arg1->__IField(arg2)->__run(arg3,arg4,arg5).GetPtr();
}
hx::Object * val_ocallN(hx::Object * arg1,int arg2,hx::Object * arg3) THROWS
{
if (!arg1) hx::Throw(HX_INVALID_OBJECT);
return arg1->__IField(arg2)->__run(Dynamic(arg3)).GetPtr();
}
// Objects access
int val_id(const char * arg1)
{
return __hxcpp_field_to_id(arg1);
}
void alloc_field(hx::Object * arg1,int arg2,hx::Object * arg3) THROWS
{
//hx::InternalCollect();
if (!arg1) hx::Throw(HX_INVALID_OBJECT);
arg1->__SetField(__hxcpp_field_from_id(arg2),arg3, HX_PROP_DYNAMIC );
}
void hxcpp_alloc_field(hx::Object * arg1,int arg2,hx::Object * arg3)
{
return alloc_field(arg1,arg2,arg3);
}
void alloc_field_numeric(hx::Object * arg1,int arg2,double arg3) THROWS
{
//hx::InternalCollect();
if (!arg1) hx::Throw(HX_INVALID_OBJECT);
arg1->__SetField(__hxcpp_field_from_id(arg2),arg3, HX_PROP_DYNAMIC );
}
void hxcpp_alloc_field_numeric(hx::Object * arg1,int arg2,double arg3)
{
return alloc_field_numeric(arg1,arg2,arg3);
}
hx::Object * val_field(hx::Object * arg1,int arg2) THROWS
{
if (!arg1) hx::Throw(HX_INVALID_OBJECT);
return arg1->__IField(arg2).GetPtr();
}
double val_field_numeric(hx::Object * arg1,int arg2) THROWS
{
if (!arg1) hx::Throw(HX_INVALID_OBJECT);
return arg1->__INumField(arg2);
}
value val_field_name(field inField)
{
return (value)Dynamic(__hxcpp_field_from_id(inField)).mPtr;
}
void val_iter_field_vals(hx::Object *inObj, __hx_field_iter inFunc ,void *inCookie)
{
if (inObj)
{
Array<String> fields = Array_obj<String>::__new(0,0);
inObj->__GetFields(fields);
for(int i=0;i<fields->length;i++)
{
inFunc((value)Dynamic(inObj->__Field(fields[i], HX_PROP_NEVER )).mPtr, __hxcpp_field_to_id(fields[i].__CStr()), inCookie);
}
}
}
void val_iter_fields(hx::Object *inObj, __hx_field_iter inFunc ,void *inCookie)
{
if (inObj)
{
Array<String> fields = Array_obj<String>::__new(0,0);
inObj->__GetFields(fields);
for(int i=0;i<fields->length;i++)
{
inFunc((value)inObj, __hxcpp_field_to_id(fields[i].__CStr()), inCookie);
}
}
}
// Abstract types
vkind alloc_kind()
{
return (vkind)(intptr_t)hxcpp_alloc_kind();
}
void kind_share(vkind *inKind,const char *inName)
{
int k = (int)(intptr_t)*inKind;
hxcpp_kind_share(k,inName);
*inKind = (vkind)(intptr_t)k;
}
// Garbage Collection
void * hx_alloc(int arg1)
{
return hx::NewGCBytes(0,arg1);
}
void * alloc_private(int arg1)
{
return hx::NewGCPrivate(0,arg1);
}
hx::Object * alloc_raw_string(int length)
{
return Dynamic( String( (HX_CHAR *) alloc_private(length+1), length) ).GetPtr();
}
void val_gc(hx::Object * arg1,hx::finalizer arg2) THROWS
{
hx::Abstract_obj *abstract = dynamic_cast<hx::Abstract_obj *>(arg1);
if (!abstract)
{
hx::GCSetFinalizer(arg1,arg2);
//hx::Throw(HX_CSTRING("Finalizer not on abstract object"));
}
else
abstract->SetFinalizer(arg2);
}
void val_gc_ptr(void * arg1,hxPtrFinalizer arg2) THROWS
{
hx::Throw(HX_CSTRING("Finalizer not supported here"));
}
void val_gc_add_root(hx::Object **inRoot)
{
hx::GCAddRoot(inRoot);
}
void val_gc_remove_root(hx::Object **inRoot)
{
hx::GCRemoveRoot(inRoot);
}
void gc_set_top_of_stack(int *inTopOfStack,bool inForce)
{
hx::SetTopOfStack(inTopOfStack,inForce);
}
void gc_change_managed_memory(int inDelta, const char *inWhy)
{
hx::GCChangeManagedMemory(inDelta, inWhy);
}
value *alloc_root()
{
hx::Object ** result = new hx::Object *();
hx::GCAddRoot(result);
return (value *)result;
}
void free_root(value *inValue)
{
hx::Object **root = (hx::Object **) inValue;
hx::GCRemoveRoot(root);
delete root;
}
// Used for finding functions in static libraries
int hx_register_prim( const char * arg1, void* arg2)
{
__hxcpp_register_prim(arg1,arg2);
return 0;
}
void gc_enter_blocking()
{
hx::EnterGCFreeZone();
}
void gc_exit_blocking()
{
hx::ExitGCFreeZone();
}
bool gc_try_blocking()
{
return hx::TryGCFreeZone();
}
bool gc_try_unblocking()
{
return hx::TryExitGCFreeZone();
}
void gc_safe_point()
{
if (hx::gPauseForCollect)
hx::PauseForCollect();
}
gcroot create_root(value) { return 0; }
value query_root(gcroot) { return 0; }
void destroy_root(gcroot) { }
/*String alloc_hxs_wchar(const wchar_t *ptr,int size)
{
return String::create(ptr,size);
}
String alloc_hxs_utf16(const char16_t *ptr,int size)
{
return String::create(ptr,size);
}
String alloc_hxs_utf8(const char *ptr,int size)
{
return String::create(ptr,size);
}*/
const char * hxs_utf8(const String &string,hx::IStringAlloc *alloc)
{
return string.utf8_str(alloc);
}
const wchar_t * hxs_wchar(const String &string,hx::IStringAlloc *alloc)
{
return string.wchar_str(alloc);
}
const char16_t * hxs_utf16(const String &string,hx::IStringAlloc *alloc)
{
return string.wc_str(alloc);
}
EXPORT void * hx_cffi(const char *inName)
{
#define HXCPP_PRIME
#define DEFFUNC(name,r,b,c) if ( !strcmp(inName,#name) ) return (void *)name;
#include <hx/CFFIAPI.h>
return 0;
}
}