Custom exception crashes C4D

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 15/01/2005 at 13:34, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   8.206 
Platform:    Mac  ;  Mac OSX  ; 
Language(s) :     C++  ;

---------
This really isn't an SDK question, but I cannot find any information about this.

Porting my Windows C4D plugin over to MacOS. Using CodeWarrior 9. Everything compiles great and my plugin runs well in C4D R9 on MacOSX.

But, everytime I throw a custom exception, C4D disappears (i.e.: crashes). This did not happen on Windows ever (VSC++ 6.0).

To clarify, custom exception means - not derived from any exception class (which may be the problem in CW on Mac, but no information to be found). Here's the class:

  
// CLASS: Error Exception  
class ErrorException  
{  
     private:  
          INT error;  
          String text;  
          String text2;  
     public:  
          ErrorException(INT err, String txt);  
          ErrorException(INT err, String line1, String line2);  
          INT GetError();  
          String GetString();  
          String GetString2();  
};  

And I throw/catch it like this:

  
     try  
     {  
          // Do something that might throw  
          throw ErrorException(ERROR_MEMORY, "text");  
     }  
     catch (ErrorException ee)  
     {  
          ErrDlgCaller::CallErrorDialog(ee.GetError(), ee.GetString(), ee.GetString2(), FALSE);  
     }  

As far as I know, it is perfectly legal to try/throw/catch your own exceptions for your own errors and warnings. So, why does C4D crash on Mac and not on Windows (yes, exceptions are enabled in CW build).

Thanks,
Robert

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 16/01/2005 at 20:57, xxxxxxxx wrote:

Anybody? I've tried everything (besides removing exceptions), searched high and low, and read more documents than I care to mention. Nothing to resolve the issue.

This is becoming a problem - it is the last and final block to a commercial release of demo and commercial versions for both Windows and MacOS.

Thanks,

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 17/01/2005 at 11:41, xxxxxxxx wrote:

Okay, here's what I found - obtusely yet. In a three-year old thread for RealBasic SDK plugins on Mac, there is an identical issue. This issue seems to stem from PPC code using Carbon and Classic PPC. See the thread here, if you'd not mind helping:

C++ throw/catch exception in plugins

Personally, I don't think that commenting out __sinit() is an option. What I have read is that in Mac applications, main() should have a try/catch block to catch all uncaught exceptions as a last ditch sink for exception handling.

So, what I was considering was modifying C4D_MAIN to do this. I'd really appreciate support here since removing exception handling for C-style error handling will require a near complete rewrite of finalized working code - costing me time, money, and effort (literally).

Thanks,

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 17/01/2005 at 17:34, xxxxxxxx wrote:

Me: Hi, myself.
Myself: I, how 'ya doin'?
I: Doing great, myself.

Well, since this seems to be an uncircumventable issue, I opted for a 'fake' exception handling scheme that required the least amount of recoding. Now my exception class just has Throw() which calls the dialog and returns from the method and those methods which had try/catch blocks now have a goto/Catch: (horrid, I know). If anything, it mimics the intended error handling without need of exceptions.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 21/01/2005 at 10:15, xxxxxxxx wrote:

Officially, the SDK project doesn't support exceptions (as you've noticed). However, I believe the unofficial intention is that the use that you describe should work, i.e. when all exceptions are caught. If there are changes to c4d_pmain.cpp in future versions of C4D to accomodate this better, then it might be possible for you to manually backport the changes to support exceptions in R8 as well (just like with the __WINCRTINIT hack).
I'm glad you found a temporary solution that works.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 21/01/2005 at 14:42, xxxxxxxx wrote:

In future versions of C4D the c4d_pmain.cpp file will look like this:

    
    
    // this is the "glue" to C4D...  
    // please modify only if you know exactly what you are doing...
    
    
    
    
    #ifdef WIN32  
      #include <windows.h>  
    #endif
    
    
    
    
    #include "c4d_plugin.h"
    
    
    
    
    #ifdef __MAC  
      #ifdef __cplusplus  
      extern "C" {  
      #endif
    
    
    
    
      extern void __sinit(void);  
      extern void __destroy_global_chain(void);
    
    
    
    
      // defined by linker  
      extern char __code_start__[];         
      extern char __code_end__[];     
      extern char __data_start__[];     
      extern char __data_end__[];   
      extern char __exception_table_start__[];    
      extern char __exception_table_end__[];  
    
    
    
    
      static int fragmentID;            //  ID given to fragment by exception-handling  
    
    
    
    
      static asm char *__RTOC(void)  
      {  
          mr    r3,RTOC  
        #if !defined(__MWERKS__)    
          blr  
        #endif  
      }
    
    
    
    
      #include <NMWException.h>
    
    
    
    
      #define C4D_MAIN LONG c4d_main(LONG action, void* p1, void* p2, void* p3)  
      C4D_MAIN;
    
    
    
    
      #ifdef __cplusplus  
      }  
      #endif  
    #elif defined __PC  
      HINSTANCE g_hinstDLL;  
      LPVOID g_lpReserved;
    
    
    
    
      #ifdef __cplusplus  
      extern "C" {  
      #endif  
        
      #define C4D_MAIN LONG __declspec(dllexport) c4d_main(LONG action, void* p1, void* p2, void* p3)  
      C4D_MAIN;
    
    
    
    
      #ifndef __WINCRTINIT  
      BOOL APIENTRY DllMain(HANDLE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved)  
      {  
        switch (ul_reason_for_call)  
        {  
          case DLL_PROCESS_ATTACH:  
          case DLL_THREAD_ATTACH:  
          case DLL_THREAD_DETACH:  
          case DLL_PROCESS_DETACH:  
            break;  
        }  
          return TRUE;  
        }  
        #else  
        extern BOOL APIENTRY _CRT_INIT(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
    
    
    
    
        BOOL APIENTRY DllMainCRTStartup( HINSTANCE hinst, DWORD reason, LPVOID reserved )  
      {       
        g_hinstDLL = hinst;  
        g_lpReserved = reserved;  
        return TRUE;  
      }  
      #endif  
      #ifdef __cplusplus  
      }  
      #endif  
    #else  
      #ifdef __cplusplus  
      extern "C" {  
      #endif
    
    
    
    
      #define C4D_MAIN LONG c4d_main(LONG action, void* p1, void* p2, void* p3)  
      C4D_MAIN;
    
    
    
    
      #ifdef __cplusplus  
      }  
      #endif  
    #endif
    
    
    
    
    LONG InitOS(void *p);
    
    
    
    
    CHAR path_storage[1024];
    
    
    
    
    C4D_MAIN //(LONG action, void* p1, void* p2, void* p3)  
    {  
      static LONG init_count = 0;  
      LONG i;  
      CHAR *c;  
        
      switch (action)  
      {  
        case C4DPL_INIT_VERSION:  
          return C4DPL_VERSION;
    
    
    
    
        case C4DPL_INIT_SYS:  
          init_count += 1;  
          if (init_count == 1)  
          {  
            if (InitOS(p1) < 7500) return C4DPL_ERROR_VERSION;  
            #ifdef __PC  
              #ifdef __WINCRTINIT  
                _CRT_INIT(g_hinstDLL, DLL_PROCESS_ATTACH, g_lpReserved);  
              #endif  
            #elif defined __MAC
    
    
    
    
              //  register this code fragment with the Exception Handling mechanism  
             fragmentID = __register_fragment( __code_start__, __code_end__, __data_start__, __data_end__, __exception_table_start__, __exception_table_end__, __RTOC());
    
    
    
    
              __sinit();  
            #endif  
            if (!p3) return C4DPL_ERROR_VERSION;  
            for (i = 0, c = (CHAR* )p3; c[i]; i++) path_storage[i] = c[i];  
            path_storage[i] = 0;  
          }  
          return 1;
    
    
    
    
        case C4DPL_MESSAGE:  
          if (!PluginMessage((LONG)p1,p2)) return C4DPL_ERROR;  
          return 1; 
    
    
    
    
        case C4DPL_INIT:  
          return PluginStart();  
          
        case C4DPL_END:  
          init_count -= 1;  
          if (init_count == 0)  
          {  
            PluginEnd();  
            void FreeResource();  
            FreeResource();  
            #ifdef __PC  
              #ifdef __WINCRTINIT  
                _CRT_INIT(g_hinstDLL, DLL_PROCESS_DETACH, g_lpReserved);  
              #endif  
            #elif defined __MAC  
              __destroy_global_chain();
    
    
    
    
              //  unregister this code fragment with the Exception Handling mechanism  
              __unregister_fragment( fragmentID );  
            #endif  
          }  
          return 1;  
            
        default:  
          break;  
      } 
    
    
    
    
      return C4DPL_ERROR;  
    }

So you could try modifying the c4d_pmain.cpp in your API folder to see if CW9 can handle exceptions then.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 21/01/2005 at 15:19, xxxxxxxx wrote:

Thanks, Mikael!

I will test this out as soon as time permits.

Robert