Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / September 2004

Tip: Looking for answers? Try searching our database.

Function Pointers, Delegates, Legacy Code...and some sympathy

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Mark Olbert - 21 Sep 2004 05:08 GMT
First off, the sympathy is for all you poor buggers out there who have to figure out how to marry
Managed Extensions for C++ onto your legacy code. My condolences; my brief experience with the
process leads me to believe the Microsoft hates all of its VC++ developers :)

Now, the question. I'm getting a NullReferenceException in a __gc class that wraps functionality in
a legacy C/C++ app (it's actually part of the Nero burning rom api).

The legacy API expects to be given a configuration structure that contains, among other things, a
pair of function pointers which the codebase calls at various times. After much hair-pulling, I came
up with the following:

__delegate bool IdleCallbackHandler( void* pUserData );
__delegate NeroUserDlgInOut UserDialogCallbackHandler( void* pUserData, NeroUserDlgInOut type, void*
data );

[StructLayout(Layout::Sequential)]
__gc public struct NeroIdleCallback
{
public:
    IdleCallbackHandler* ncCallbackFunction;
    void* ncUserData;
};

[StructLayout(Layout::Sequential)]
__gc public struct NeroUserDialogCallback
{
public:
    UserDialogCallbackHandler* ncCallbackFunction;
    void* ncUserData;
};

[StructLayout(Layout::Sequential)]
__gc public struct NeroSettings
{
public:
    const char *nstNeroFilesPath;
    const char *nstVendor, *nstSoftware;
    const char *nstLanguageFile;
    NeroIdleCallback* nstIdle;
    NeroUserDialogCallback* nstUserDialog;
    bool  nstEnableOverburn;
    DWORD nstOverburnSize;
};

I configure this structure, and the callback substructures, in the constructor of my wrapper class
as follows:

theSettings = new NeroSettings();
theSettings->nstNeroFilesPath = "NeroFiles";
theSettings->nstLanguageFile = "Nero.txt";

theSettings->nstEnableOverburn = false;
theSettings->nstOverburnSize = 0;
   
theSettings->nstIdle = new NeroIdleCallback();
theSettings->nstIdle->ncCallbackFunction = new IdleCallbackHandler(this, &Nero::FireIdleEvent);
theSettings->nstIdle->ncUserData = idleData;

theSettings->nstUserDialog = new NeroUserDialogCallback();
theSettings->nstUserDialog->ncCallbackFunction = new UserDialogCallbackHandler(this,
&Nero::FireUserDialogEvent);
theSettings->nstUserDialog->ncUserData = userdlgData;

theSettings->nstVendor = "ahead";
theSettings->nstSoftware = "Nero - Burning Rom";

Everything works fine during initialization, and in retrieving certain basic information from the
legacy codebase.

But when I call a legacy function that triggers the IdleCallback, I get the NullReferenceException:

void AvailableDrives( NERO_MEDIA_TYPE mtFlags )
{
    // this next line blows up... but the IdleCallback gets called first
    NERO_SCSI_DEVICE_INFOS* drives = NeroGetAvailableDrivesEx(MEDIA_CD, NULL);
    ...
}

The interesting part is the part mentioned in that comment:  the IdleCallback method gets called,
and returns, but then the exception gets thrown.

And what's really interesting is that setting the ncCallbackFunction delegate/function pointer to
NULL in the NeroIdleCallback structure -- which forces the legacy codebase to NOT call the
IdleCallback -- avoids the exception.

Sorry for being so long-winded.

What I'm wondering is, am I handling the function pointer concept correctly here? Is it possible
that I've done something wrong so that when the callback returns, it tries to return to a place that
doesn't exist?

- Mark
Ernesto Basc?n - 23 Sep 2004 00:17 GMT
Hi Mark:

The idea is to write an inner __nogc class inside our __gc class. The inner
class will contain the callback function (as a static method).

This article was very helpful to me:

http://www.codeproject.com/managedcpp/cbwijw.asp

Best regards

Ernesto

> First off, the sympathy is for all you poor buggers out there who have to figure out how to marry
> Managed Extensions for C++ onto your legacy code. My condolences; my brief experience with the
[quoted text clipped - 89 lines]
>
> - Mark
Mark Olbert - 24 Sep 2004 15:24 GMT
Thanx, Ernesto! That article was a big help!

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.