C++ MFC 64bit : setting up environment with existing DLLS to link

Hi,
I am new of Rhino programming and I am trying to set up my environment. I work in the field of structural engineering.
I have several DLLs Win32 which work fine, and that I would like to reuse for my Rhino Plugins.
However, I have seen that Rhino5 Visual Studio 10 “means” 64 bit programming. I don’t want to go back to VS2005, which I still have, because this would be quite boring (two Visual Studios…).

So I have recompiled my DLLs for x64. They compiled fine. I have created the first plug in with an additional dummy command, and it worked fine with Rhino 5, 64bit.
Then I moved forward and linked my new Plug In with some of my existing MFC DLL recompiled 64 bit. The plug in is loaded fine.
Then I read an archive of some like 18,000 cross sections (European, USA, Indian, Japanese…), which will be one of the goal of my first plug in , by using one of the functionalities of my DLLs, reading a file of mine. It works.
However, when I move forward to try to choose among those 18,000 one fit for my needs, the program crashes.

My debugger shows that an ASSERT is issued at this statement in “AfxWin1.inl”:

_AFXWIN_INLINE HINSTANCE AFXAPI AfxGetResourceHandle()
{ ASSERT(afxCurrentResourceHandle != NULL);

My DLLs define new MFC derived objects and systematically use the AFX_EXT_CLASS macro.
I don’t think the problem is some 32/64 bit programming clash. I guess it’s more something related to the “dialog” of the DLLs with Rhino.
Many thanks
Paolo

Rhino C++ plug-ins are “Regular” MFC DLLs.

https://msdn.microsoft.com/en-us/library/30c674tx(v=vs.100).aspx

Ann MFC DLLs you link with your Rhino C++ plug-in should also be Regular MFC DLLs, not Extension DLLs.

Really many thanks for your help.
When back in 1996 I began my porting from C/DOS extended to C++/MFCWin95, using extension DLL seemed logic. It has worked fine for 20 ys, and still works under Win8.
Now I have quite a number of classes, derived from CObject, and embedded in extension dlls. These are my workhorse…
Is there a way a can reuse this huge set of code? Can I use classes directly derived from MFC CObject?

Really very many thanks
Paolo

Hi Paulo,

Just curious, was your extension DLL called by an application (.exe) or by a DLL?

Keep in mind that the plug-in (DLL) is calling into your DLL, not Rhino.exe. Also, resources and module state is a big issue when dealing with MFC DLLs. Here is all the dirty secrets.

https://msdn.microsoft.com/en-us/library/ft1t4bbc.aspx

Basically, if your DLL is going to display a dialog box, then you are going to have to switch the active module state in your DLL before creating any object that is going to display the box.

https://msdn.microsoft.com/en-us/library/cc6feexs.aspx

I’m happy to work with you get your MFC DLL working with Rhino. If you want to email me directly (dale@mcneel.com), then we can take this off line.

Thanks,

– Dale

I can certainly understand the appropriateness of taking all the dirty details offline, but I think it would help a number of others to continue this thread with mention of major issues found and their solutions. I know I would find it interesting, and I’m sure there are others who will be motivated to convert their dll’s to 64-bit as time goes on.

Thank you very much to both.
I’ll get inside the documentation by Microsoft and try some more code in order to solve the issue. I’ll be back after I will try. In the meantime some more info and considerations.

My MFC extension DLLs are liked between themselves and are usually linked by my main applications, which up to now have been Win32 MFC applications (exe).

Presently, Rhino loads the plugin, and the plugin calls some functions and uses some objects defined in the MFC extension DLLs. What is surprising is that the Plugin is loaded, and so the MFXEXT dlls (if some miss the plugin is not loaded by Rhino), and some part of the stuff is correctly done (for instance, serialization of CObject derived classes). It is not a crash from the start.
The problem, yes, seems to be related to dialog opening. However, the debugging behaviour of the program is different by the release behavior. In release a first dialog opens correctly and then I have the crash after pressing OK. When debugging the ASSERT is got before opening the dialog (dlg.DoModal() stuff).
I think that some sort of workaround must be found, because it’s too important to save and reuse already existing and quite much tested code.
For instance, my very first plug in would add to Rhino the ability to read a 18,000+ cross section archive, also using filters and design criteria, and then to generate 3D members easily. Having in mind civil engineering issues (especially in the field of steel structures) this is a quite interesting Plugin. Isn’t it? I dare say it is.
If this works, then quite a number of interesting issues open. Really. I am thinking to steel connections issues, which I have so much worked about.

I’ll read, study and try, and later go back. Thank you everybody for your precious help.

Also, as it is the very first time I use 64 bit programming, I wonder if some 32 to 64 porting issue might be responsible. I don’t think so. My code should be relatively safe, I guess (but… I know that 32 to 64 is always a problem to be faced not just by a simple recompilation, perhaps I have been too optimistic).
Paolo

A couple of issues.

  1. I initially loaded my Plugin using the Release folder. Later I wished to use the Debug folder. However, it was not possible for me to understand how to change the stored path of the Plugin from within Rhino. I had to change the path by directly modifying the registry key.

  2. I have defined this function in my extension DLL (the main CPP module of the extension DLL):

BOOL switch_to_local(BOOL mode)
{
static HINSTANCE oldinst;
if(mode == TRUE)
{
oldinst = AfxGetResourceHandle();
AfxSetResourceHandle(theinstance);
}
else if (mode == FALSE) AfxSetResourceHandle(oldinst);
}
However it does not work (but it had in the past, as I did use it) because when AfxGetResourceHandle() is called, the current resource handle is NULL. And this implies an assertion of the inline function already mentioned.
AFXWININLINE HINSTANCE AFXAPI AfxGetResourceHandle()
{ ASSERT(afxCurrentResourceHandle != NULL);

So when the Plugin takes the control, the current Resource handle is set to null. Subsequent calls to AfxGetResourceHandle will lead to a crash.

ad 1) you can simply drag the plug-in onto Rhino, either from the Release or Debug folder to update the path in the registry. All subsequent loading of the plug-in will then use the new path.
This only works, however, if the plug-in is not yet loaded (so plug-ins that load at start-up will not work in this way).

Thank you for the hint. Bye. Paolo

Hi All,

I was able to start back my work on the issue after some months related to other projects and finally solved it, thanks to an old Dale’s hint.

The crash was not due to the regular vs extension DLL issue. The crash, now removed, is related to mixing unicode and multibyte string support. I finally had the prove of it (at February it was an hypothesis).

It is not possible to mix regular and extension DLL and also unicode multibyte strings.

It is on the other hand possible to have an extension DLL called by a regular DLL which is the Rhino plug in. When I turn my 64bit extension DLL to unicode string, and recompile it, it works.

So I can now start my work and the road is open to reuse my DLLs for Rhino. I hope I will soon produce some plug in.
About the problem of porting the DLLs with multibyte to unicode, I can perhaps send some hint if this will be needed.

This issue is closed.