REALNewMemoryBlock

Hi,

I tried to replace REALNewMemoryBlock with using REALnewInstance and REALLoadObjectMethod with constructor.

But how do I know it succeeded?
Or failed?

I can’t catch the exception?

or could you guys undeprecate REALNewMemoryBlock and update it for 64-bit?

REALmemoryBlock MemoryBlock_New(RBUInteger len)
{	
    REALclassRef ref = REALGetClassRef("MemoryBlock");
    REALmemoryBlock m = REALnewInstance(ref);

    _STATIC_ void (*_fp)(REALmemoryBlock, RBUInteger) = nil;
    
	if (!_fp)
		_fp = (void(*)(REALmemoryBlock, RBUInteger)) REALLoadObjectMethod(m, "Constructor(length as Integer)");
	if (_fp) {
		_fp(m, len);
        return m;
	}
    REALUnlockObject(m);
    MSG(DYNAMIC ACCESS FAILURE in MemoryBlock_New)
}

Thanks. That Looks like my code.
But you can end up having a bad memory lock, too.
One which failed to initialize.
Maybe I should query size and see if it is >0?

I added some stuff to it. I guess you now can check if it is NULL:

[code]REALmemoryBlock MemoryBlock_New(RBUInteger len)
{
STATIC REALclassRef ref = NULL;

if (!ref)
    ref = REALGetClassRef("MemoryBlock");
if (ref) {
    REALmemoryBlock m = REALnewInstance(ref);

    _STATIC_ void (*_fp)(REALmemoryBlock, RBUInteger) = nil;
    
    if (!_fp)
        _fp = (void(*)(REALmemoryBlock, RBUInteger)) REALLoadObjectMethod(m, "Constructor(length as Integer)");
    if (_fp) {
        _fp(m, len);
        return m;
    }
    REALUnlockObject(m);
    MSG(DYNAMIC ACCESS FAILURE in MemoryBlock_New)
    return NULL;
}
MSG(DYNAMIC ACCESS: COULD NOT GET REALGetClassRef in MemoryBlock_New)
return NULL;

}
[/code]

If the class ref is NULL then you know you should call REALGetClassRef(“MemoryBlock”) in PluginEntry(). And if dynamic access fails (and the code above is ok) then a feedback report is required.

I think the problem is even bigger.
When you call the constructor in low memory situation, the line “return m” after the call is not executed.

So Xojo runtime jumps out of my code?
I thought exceptions are just stored for later?

Feedback request 40899 asks to undeprecate the function.

I would think the problem here is bigger since this could also happen for Picture, and really any other class that allocates big memory chunk.

I also made case 40902 for REALNewPicture.

I wonder if REALCallFunctionWithExceptionHandler can help here?

Yes, but expand your scope past things that allocate big memory chunks.

Basically anything returned by REALLoadObjectMethod can raise an exception, along with REALGetPropValue, REALSetPropValue, REALGetEventInstance, REALUnlockObject, all of the array functions, and anything else that executes Xojo code. Even some of the older now-deprecated functions could throw in certain situations.

It’s all rather unfortunate, but adding non-throwing wrappers for every framework function a plugin might ever be interested in isn’t the answer.

[quote=214691:@Christian Schmitz]So Xojo runtime jumps out of my code?
I thought exceptions are just stored for later?[/quote]

No, it won’t jump out of your code. Control flow continues in your C++ code until it gets back to Xojo code, where it jumps to the appropriate exception handler.

It can. With some of C++11 metaprogramming, I think you can even make it fairly elegant.

it confused me that the debugger stops right away and when you continue in debugger, my next C line executes.

So now I use REALCallFunctionWithExceptionHandler for this case and code like this:

[code] REALobject o = REALnewInstance(“MemoryBlock”);
DebugMessage(“o”, o);
if (o)
{
typedef void (*f)(REALobject o, RBInteger size);

	static f c = (f) REALLoadObjectMethod(o, "Constructor(bytes as Integer)");
	DebugMessage("c", (void*) c);
	if (c)
	{
		c(o, bytes);
		
		REALmemoryBlock m = (REALmemoryBlock) o;
		
		RBInteger size = MyREALMemoryBlockGetSize(m);
		DebugMessage("size", size);
		if (size < bytes)
		{
			DeleteObject(o);
		}
		else
		{
			d->result = (REALmemoryBlock) o;
		}
	}
	else
	{
		DeleteObject(o);
	}
}

[/code]

as you see I check size of memoryblock. The size is -1 when the exception is raised.

Still my problem is that I normally raise my own OutOfMemoryException.

Ok then, here is a full code that replaces REALNewMemoryBlock.

[code]struct delegateExceptionHandler {
REALmemoryBlock memblock;
RBInteger size;
};
typedef void (DelegateTaskProc)(void data);
static void MemoryBlock_allocation(void
data)
{
delegateExceptionHandler
dm = (delegateExceptionHandler*)data;

_STATIC_ REALclassRef ref = NULL;

if (!ref)
    ref = REALGetClassRef("MemoryBlock");
if (ref) {
    dm->memblock = REALnewInstance(ref);
    
    _STATIC_ void (*_fp)(REALmemoryBlock, RBUInteger) = nil;
    
    if (!_fp)
        _fp = (void(*)(REALmemoryBlock, RBUInteger)) REALLoadObjectMethod(dm->memblock, "Constructor(length as Integer)");
    if (_fp) {
        _fp(dm->memblock, dm->size);
        return;
    }
    REALUnlockObject(dm->memblock);
    MSG(DYNAMIC ACCESS FAILURE in MemoryBlock_allocation)
}
MSG(DYNAMIC ACCESS: COULD NOT GET REALGetClassRef in MemoryBlock_allocation)

}

static REALobject Perform_Creation_of_Object_with_exception_handler(DelegateTaskProc proc, RBInteger size, bool raiseException)
{
delegateExceptionHandler dm;
dm.size = size;

REALobject myObject = REALCallFunctionWithExceptionHandler(proc, &dm);
if (myObject) {
    if (raiseException)
        REALRaiseException(myObject);
    REALUnlockObject(myObject);
}
return dm.memblock;

}

REALmemoryBlock MemoryBlock_NewWithException(RBInteger size, bool raiseException)
{
return Perform_Creation_of_Object_with_exception_handler(MemoryBlock_allocation, size, raiseException);
}
[/code]

Are any of you able to use C++11 features?

I read about it, need to get my head around it and is C++11 also viable in Visual Studio?

Visual Studio 2013 supports a good amount of C++11 and Visual Studio 2015 supports almost all of it (and some C++14).

and I use Visual Studio 2008 :slight_smile:

Lord Christian !! you need to do your self a favour and make the jump to 2015 !! Its free and less painless than you might think. I made the jump from 2008 to 2013 earlier this year and then to 2015, its win win situation.

I guess I didn’t poor enough beer into you this summer to shake this out of you.

Only drawback was that I cannot run VS 2013 or 2015 on XP Virtual machines. But making good Windows 7 VM solved that, turning off all restore points and rubbish like that makes Windows 7 fairly light and reasonable on VMware.

What do you do to make sure your plugins run on older versions of Windows?

VS 2013 and 2015 can be used to target old versions of Windows