Notifications
Clear all

[Closed] [SDK] Crash after object creation

Hey,

I have a strange problem with a crash after creating an object with a plugin utility.
Either I have a mistake in the code or understanding how max generates an object, or there is a bug in Max. I tend to option one.
The base code was created with the max-wizard in Visual Studio 2010 for Max 2014.

Here the code of the plugin.cpp:


#include "bakePlugin.h"
#include "bakeUtil.h"

#define bakePlugin_CLASS_ID	Class_ID(0x6d6dfd1f, 0x94871f48)

class bakePlugin : public UtilityObj 
{
public:
		
	//Constructor/Destructor
	bakePlugin();
	virtual ~bakePlugin();

	virtual void DeleteThis() { }
	
	virtual void BeginEditParams(Interface *ip, IUtil *iu);
	virtual void EndEditParams(Interface *ip, IUtil *iu);

	virtual void SelectionSetChanged(Interface *ip, IUtil *iu);

	virtual void Init(HWND hWnd);
	virtual void Destroy(HWND hWnd);
	
	// Singleton access
	static bakePlugin* GetInstance() { 
		static bakePlugin thebakePlugin;
		return &thebakePlugin; 
	}

private:

	static INT_PTR CALLBACK DlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

	HWND   hPanel;
	IUtil* iu;
	Interface* ip;

	ICustButton *applyButton;
	
};


class bakePluginClassDesc : public ClassDesc2 
{
public:
	virtual int IsPublic() 							{ return TRUE; }
	virtual void* Create(BOOL /*loading = FALSE*/) 	{ return bakePlugin::GetInstance(); }
	virtual const TCHAR *	ClassName() 			{ return GetString(IDS_CLASS_NAME); }
	virtual SClass_ID SuperClassID() 				{ return UTILITY_CLASS_ID; }
	virtual Class_ID ClassID() 						{ return bakePlugin_CLASS_ID; }
	virtual const TCHAR* Category() 				{ return GetString(IDS_CATEGORY); }

	virtual const TCHAR* InternalName() 			{ return _T("bakePlugin"); }	// returns fixed parsable name (scripter-visible name)
	virtual HINSTANCE HInstance() 					{ return hInstance; }					// returns owning module handle

};


ClassDesc2* GetbakePluginDesc() { 
	static bakePluginClassDesc bakePluginDesc;
	return &bakePluginDesc; 
}


//--- bakePlugin -------------------------------------------------------
bakePlugin::bakePlugin()
	: hPanel(nullptr)
	, iu(nullptr)
{
	
}

bakePlugin::~bakePlugin()
{

}


void bakePlugin::BeginEditParams(Interface* ip, IUtil* iu) 
{
	this->iu = iu;
	hPanel = ip->AddRollupPage(
		hInstance,
		MAKEINTRESOURCE(IDD_PANEL),
		DlgProc,
		GetString(IDS_PARAMS),
		0);

	GenBoxObject* geoObj = (GenBoxObject*)ip->CreateInstance(GEOMOBJECT_CLASS_ID, Class_ID(BOXOBJ_CLASS_ID, 0));

	geoObj->SetParams(1.0f, 1.0f, 1.0f, 1, 1, 1, FALSE);

	INode *boxNode = ip->CreateObjectNode(geoObj);
	
}
	
void bakePlugin::EndEditParams(Interface* ip,IUtil* iu)
{
	this->iu = nullptr;
	this->ip = nullptr;

	ip->DeleteRollupPage(hPanel);

	hPanel = nullptr;
}

void bakePlugin::SelectionSetChanged(Interface *ip, IUtil *iu)
{

}

void bakePlugin::Init(HWND hWnd)
{
	applyButton = GetICustButton(hWnd);
}

void bakePlugin::Destroy(HWND hWnd)
{
	//ReleaseICustButton(applyButton);
}

INT_PTR CALLBACK bakePlugin::DlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg) 
	{
		case WM_INITDIALOG:
			bakePlugin::GetInstance()->Init(hWnd);


			break;

		case WM_DESTROY:
			bakePlugin::GetInstance()->Destroy(hWnd);
			break;

		case WM_COMMAND:
			switch(LOWORD(wParam))
			{
				case IDC_APPLYBUTTON:

					break;

				default:

					break;
			}
			
			break;

		case WM_LBUTTONDOWN:
		case WM_LBUTTONUP:
		case WM_MOUSEMOVE:
			GetCOREInterface()->RollupMouseMessage(hWnd,msg,wParam,lParam);
			break;

		default:
			return 0;
	}
	return 1;
}

The code is compiled and executed in Max. The object is also visible in the viewport, but when I try to select the object or select it in the object list, Max crashes.

Unhandled exception at 0x365411f6 (bakePlugin.dlu) in 3dsmax.exe: 0xC0000005: Access violation reading location 0x0000000000000000.

The location of the variable already seems to be wrong (0x0000000000000000). But is there any wrong initialized variable?

Thanks for your help,
Florian

6 Replies

I don’t think it’s best practice to add a new object in that manner, every time you switch back and forth to the utility panel with this utility running you’ll be creating a new object.You could Either try adding it to the plugin constructor or putting on a button in the rollup panel.

from the documentation

When the user begins to edit an item the BeginEditParams() method is called on it. At this point it is expected to do two things:

[ul]
[li]Adding or displaying its user interface via rollup pages.[/li]> [li]Register any sub-object selection types it may have.[/li]> [/ul]

Thanks for your answer.

This was just a test to show you the problem.
In our use case its added after clicking a button. But the problem was that Max crashed always after selecting the object.

Interestingly we yesterday tried the Max SDK 2012 and there it works. But we used the 2012-Wizard to create a new project.
So it might be a bug from Max 2014 or is there something else wrong in our code?

I’m not really able to help you out, but i felt like sharing my thoughts here might make a difference anyway:

I tried to recreate your problem…and after some “fun” with getting the SDK to compile at all (Hello? Link errors aren’t the way it should be, when just following the “installation guide”), i was actually able to notice the same problems.

I get these funky access violations whenever i try to create a node in the scene. I am able to see the object in the viewport, but selecting it makes max crash reproducably…

Any help? I can’t see anything wrong in the object-creation code, as it’s practically the same as in the examples of the SDK documentation…

what happens if you move the object creation code into the plugin constructor.

no issues if you create via the constructor like this

bakePlugin::bakePlugin() : hPanel(NULL) , iu(NULL)
{
	GenBoxObject* geoObj=(GenBoxObject*)GetCOREInterface()->CreateInstance(GEOMOBJECT_CLASS_ID,Class_ID(BOXOBJ_CLASS_ID, 0));
	geoObj->SetParams(1.0f, 1.0f, 1.0f, 1, 1, 1, FALSE);
	INode *boxNode = GetCOREInterface()->CreateObjectNode(geoObj); 
}

Thanks for your answer. It’s funny, but the bug doesn’t exist anymore! :surprised
I wasn’t able to reproduce it. Maybe it was something internal of Max or Windows or the SDK, but now I can easily create an object whereever I want in the code.

Hopefully it will stay, but for now the thread can be closed.

your original code crashed max every time for me.