How to handle exceptions in unmanaged code

J

Jarkko Alli

Hi.

I am building an application using managed C++ which is calling nicely
old unmanaged DLLs.

A lot of old logic is based on intended exceptions (iterator reaches
end of items etc.). I just realized that when throwing an exception in
an unmanaged try/catch block it is not any more caught by the
unmanaged handler in its DLL but the calling managed C++ handler, if
there is any. Now, the logic originally was to handle all exceptions
in the unmanaged code itself. Is this a feature? Is there any
mechanism to allow the unmanaged code to handle the exceptions it
already is ready to handle?

Anyone any ideas?

Regards, Jarkko Alli
 
R

Ronald Laeremans [MSFT]

Do you have a repro case (as simple as possible) for this. It definitely
isn't intended behavior and I haven't seen it happen.

Ronald Laeremans
Visual C++ team
 
J

Julie

Jarkko said:
Hi.

I am building an application using managed C++ which is calling nicely
old unmanaged DLLs.

A lot of old logic is based on intended exceptions (iterator reaches
end of items etc.). I just realized that when throwing an exception in
an unmanaged try/catch block it is not any more caught by the
unmanaged handler in its DLL but the calling managed C++ handler, if
there is any. Now, the logic originally was to handle all exceptions
in the unmanaged code itself. Is this a feature? Is there any
mechanism to allow the unmanaged code to handle the exceptions it
already is ready to handle?

Anyone any ideas?

Regards, Jarkko Alli

This shouldn't be happening.

Presumably you are building the unmanaged code in VS.NET -- are your project
settings correct with respect to exception handling?

How did you initially create your VS.NET project? Did you convert it or
recreate it from scratch? I've had some funny things happen when a converted
project, or when I have created a project from scratch then changed its base
output type.
 
J

Jarkko Alli

Here is the code:

In C# I create a managed C++ "thing" mCore:

unsafe
{
char[] cpPath = dbPath.ToCharArray();
fixed (char *pPath = cpPath)
{
mCore = new C_DataProvider(pPath);
}
}

In Managed C++ wrapper the constructor looks like this:

C_DataProvider::C_DataProvider(
System::Char __nogc *cpDataPath)
{
C_CoreInterface* __pin* pCI = &m_coreInterface;
C_CoreTable* __pin* pCT = &m_currentTable;

try
{
*pCI = G_GetCoreInterface(cpDataPath);
*pCT = (*pCI)->M_OpenTable(g_currentTableName);
}
catch (C_SignalException) {}
}

The native DLL M_OpenTable method uses the following piece:
....
try
{
// Search the table

G_BSearchE(...) // This throws C_SignalException, if the table does
// not exist. It is normal behaviour...
}
catch {C_SignalException)
{
// Create the table
}
....

The C_SignalException class looks like this:

class CSCommon_API C_SignalException
{
public:
C_SignalException(const char *x=0) {}
};

What is wrong?

Regards, Jarkko Alli
 
E

EMonaco

Jarkko,

Are you sure the exception being thrown is of type C_SignalException? Is
its say an access violation exception or something else your catch() will
not handle it... quickest test would be a catch(...) // catch all

Regards,
Erin.
 
N

Nasse

I built a try/catch block in MEC++ code using C_SignalException and it went
there!

Regards, Jarkko

EMonaco said:
Jarkko,

Are you sure the exception being thrown is of type C_SignalException? Is
its say an access violation exception or something else your catch() will
not handle it... quickest test would be a catch(...) // catch all

Regards,
Erin.

--
Visit us on the web at: http://www.databasementsoftware.com


Jarkko Alli said:
Here is the code:

In C# I create a managed C++ "thing" mCore:

unsafe
{
char[] cpPath = dbPath.ToCharArray();
fixed (char *pPath = cpPath)
{
mCore = new C_DataProvider(pPath);
}
}

In Managed C++ wrapper the constructor looks like this:

C_DataProvider::C_DataProvider(
System::Char __nogc *cpDataPath)
{
C_CoreInterface* __pin* pCI = &m_coreInterface;
C_CoreTable* __pin* pCT = &m_currentTable;

try
{
*pCI = G_GetCoreInterface(cpDataPath);
*pCT = (*pCI)->M_OpenTable(g_currentTableName);
}
catch (C_SignalException) {}
}

The native DLL M_OpenTable method uses the following piece:
...
try
{
// Search the table

G_BSearchE(...) // This throws C_SignalException, if the table does
// not exist. It is normal behaviour...
}
catch {C_SignalException)
{
// Create the table
}
...

The C_SignalException class looks like this:

class CSCommon_API C_SignalException
{
public:
C_SignalException(const char *x=0) {}
};

What is wrong?

Regards, Jarkko Alli
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top